Deployed EJB3 with a remote client ( code reviewd 100 times
mjreged Nov 15, 2005 11:19 AMI know, i know another problem. But hear me out, my example is as simple as it can get, followed all blogs, trailblazer examples, etc.. etc. and the server shows that my session beas is deployed so why i can't connect, beats me.
I present to you the sequence of code that i made step by step you tell me if anything is wrong ...
step 1 : configure mysql 5 ( ok running ), created ejbds shema with emp table
CREATE TABLE `ejbds`.`emp` ( `empno` int(11) NOT NULL auto_increment, `ENAME` varchar(50) default NULL, `SAL` double default NULL, PRIMARY KEY (`empno`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1
A) ok so i create ejb-ds.xml so i can drop it into JBOSS_HOME/server/default/deploy. here is how it looks
<datasources> <local-tx-datasource> <jndi-name>ejbds</jndi-name> <connection-url>jdbc:mysql://localhost:3306/ejbds</connection-url> <driver-class>com.mysql.jdbc.Driver</driver-class> <user-name>ejbadmin</user-name> <password>local</password> <exception-sorter-class-name> org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter </exception-sorter-class-name> <metadata> <type-mapping>mySQL</type-mapping> </metadata> </local-tx-datasource> </datasources>
B) the server claims that it the ejbds is bound
09:59:22,773 INFO [ConnectionFactoryBindingService] Bound ConnectionManager 'jboss.jca:service=DataSourceBinding,name=ejbds' to JNDI name 'java:ejbds'
2 ) the next step is to write Entity bean and a Session Beans
here is my Entity Bean
package phoenix.par; import javax.persistence.*; import java.util.ArrayList; import java.util.Collection; @Entity @Table(name = "emp") public class Employee implements java.io.Serializable{ private int empNo; private String eName; private double sal; @Id(generate=GeneratorType.AUTO) @Column(name="empno") public int getEmpNo() { return empNo; } public void setEmpNo(int empNo) { this.empNo = empNo; } @Column(name="ENAME") public String getEname() { return eName; } public void setEname(String eName) { this.eName = eName; } @Column(name="SAL") public double getSal() { return sal; } public void setSal(double sal) { this.sal = sal; } public String toString() { return getEname(); } }
B) Session Bean contains the interface with @Remote in it and Implementation of that Interface
package phoenix.ejb3; import javax.ejb.Remote; import javax.ejb.Remove; import phoenix.par.Employee; @Remote public interface EmployeeFacade{ void addEmployee(int empNo, String name, double salary); Employee findEmployeeByEmpNo(int empNo); }
the implementation is as follows :
package phoenix.ejb3; import javax.persistence.*; import javax.ejb.*; import phoenix.par.Employee; @Stateless(name="EmployeeFacade") public class EmployeeFacadeBean implements EmployeeFacade{ @PersistenceContext(unitName="phoenix") private EntityManager em; public Employee findEmployeeByEmpNo(int empNo) { return ((Employee) em.find(Employee.class,empNo)); } public void addEmployee(int empNo, String eName, double sal) { emp = new Employee(); emp.setEmpNo(empNo); emp.setEname(eName); emp.setSal(sal); em.persist(emp); } }
so here is my persistence.xml with the name "phoenix" the name that the bean looks up to Inject the Persistance Manager.
<entity-manager> <name>phoenix</name> <jta-data-source>java:/ejbds</jta-data-source> <properties> <property name="hibernate.hbm2ddl.auto" value="none"/> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> <property name="hibernate.cache.provider_class" value="org.jboss.ejb3.entity.TreeCacheProviderHook"/> <property name="hibernate.treecache.mbean.object_name" value="jboss.cache:service=EJB3EntityTreeCache"/> </properties> </entity-manager>
C) so what's left to do is to COMPILE and PACK in the *.ear package
- i used a ant script for generating everything
customer.par package
customer.par
|_META-INF
.... |_ persistence.xml
|_ phoenix.par.Employee.class
then packaged the *.ejb3
phoenix-ejb30.ejb3
|_META-INF
.... |_ ~empty~
|_phoenix.ejb3.EmployeeFacade.class
|_phoenix.ejb3.EmployeeFacadeBean.class
So the last thing is to put it inside the *.ear
phoenix.ear
|_META-INF
.... |_application.xml
|_ phoenix-ejb30.ejb3
|_ customer.par
SO NOW THE PACKAGE IS READY TO BE DEPLOYED
i drop the ear into the server/default/deploy folder
and the server acts on it
i check the http://localhost:8080/jmx-console/HtmlAdaptor
and in the list there it is :
phoenix
org.jboss.ejb3.entity.InjectedEntityManager
phoenix.ejb3.EmployeeFacade
$Proxy73
etc....
so i have to assume it deployed, console showes
10:00:27,845 INFO [SessionFactoryImpl] Checking 0 named queries 10:00:27,846 INFO [Ejb3Deployment] Create EntityManager with JNDI name: phoenix 10:00:27,885 INFO [JaccHelper] JACC Policy Configuration for deployment has been put in service 10:00:27,885 INFO [Ejb3Deployment] EJB3 deployment time took: 4169 10:00:28,061 INFO [ProxyDeployer] no declared remote bindings for : phoenix.ejb3.EmployeeFacadeBean 10:00:28,099 INFO [ProxyDeployer] there is remote interfaces for phoenix.ejb3.EmployeeFacadeBean 10:00:28,099 INFO [ProxyDeployer] default remote binding has jndiName of phoenix.ejb3.EmployeeFacade
3 ) Now to only have an Client that can actually use the bean would be great
so here is my client code that i run with ANT so that i can put everything in the classpath from the JBoss client folder since i don't know what is needed and what is not
package phoenix.ejb3; import phoenix.par.Employee; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import java.util.Hashtable; import java.util.Properties; import java.io.*; import javax.persistence.*; public class EmployeeClient{ public static Hashtable getDefaultJNDI() { Properties p = new Properties(); p.setProperty(InitialContext.PROVIDER_URL, "jnp://localhost:1099"); p.setProperty(InitialContext.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory"); p.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces"); return p; } public static void main(String [] args) { try { Context context = new InitialContext( getDefaultJNDI() ); System.out.println("Looking up for a Class !!!!!!!!!!!" ); EmployeeFacade ef = (EmployeeFacade)context.lookup("EmployeeFacade.class.getName()"); // EmployeeFacade ef = (EmployeeFacade)context.lookup("phoenix.ejb3.EmployeeFacade"); -- idont know which to use int empNo = 0; String name = null; Double sal = null; try { empNo= Integer.parseInt(args [0]); name = args [1]; sal = Double.parseDouble(args[2]); } catch(Exception e) { System.err.println("Correct arguments not received, exiting"); System.exit(0); } ef.addEmployee(empNo, name, sal); System.out.println("Employee with empNo:"+empNo+" created"); System.out.println("Find the employee using Entity Manager API"); Employee emp2 = ef.findEmployeeByEmpNo(empNo); // Dump the Bean out System.out.println(emp2); } catch(Throwable ex) { ex.printStackTrace(); } } }
So when i run the Client i get Exceptions that are different depending on what string i put in the lookup() method.
like
init: [echo] -----> Initializing project properties run: [java] Looking up for a Class !!!!!!!!!!! [java] javax.naming.CommunicationException [Root exception is java.lang.ClassNotFoundEx ception: org.jboss.ejb3.JBossProxy (no security manager: RMI class loader disabled)] [java] at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:713) [java] at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:572) [java] at javax.naming.InitialContext.lookup(InitialContext.java:351) [java] at phoenix.ejb3.EmployeeClient.main(EmployeeClient.java:34)
or if i change how i look up string i get
something like this
run: [java] Looking up for a Class !!!!!!!!!!! [java] javax.naming.NameNotFoundException: EmployeeFacade.class.getName() not bound [java] at org.jnp.server.NamingServer.getBinding(NamingServer.java:514) [java] at org.jnp.server.NamingServer.getBinding(NamingServer.java:522) [java] at org.jnp.server.NamingServer.getObject(NamingServer.java:528) [java] at org.jnp.server.NamingServer.lookup(NamingServer.java:281) [java] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [java] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [java] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [java] at java.lang.reflect.Method.invoke(Method.java:585)
SO WHAT DO YOU THINK , what's the problem ?
if i missed something please let me know