2 Replies Latest reply on Nov 16, 2005 7:53 AM by mjreged

    Deployed EJB3  with a remote client ( code reviewd 100 times

      I 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




        • 1. Re: Deployed EJB3  with a remote client ( code reviewd 100 t

          Ok , hi, yeah i got it to work ,
          I had to add these jars to classpath to get the client to work :

          ejb3-persistence.jar
          jbossall-client.jar
          jboss-aspect-library-jdk50.jar
          jboss-ejb3.jar
          also don't forget to include your Entity classes and your Session bean interface that is used in the client in your classpath too.

          and since the object travel throught the network, they are serialized, you need
          to cal merge( obj ) before perisist( obj )

          • 2. Re: Deployed EJB3  with a remote client ( code reviewd 100 t

            Ohh yeah one more thing,,
            Yeah sure i did get the client to work , but it works localy only,
            if i move it to another computer i gives me exception about not being able to connect to RMI,

            the client tries to connect to localhost at all times. how can that be i have
            a jndi.properties in the src root that provides the ip address to my server yet it only looks for localhost, i also tied the hashtable to provided the properties to the InitalContext and still no good. I will try some things today and let you know if i was able to connect,,, if anyone has an idea on what it should be done in this respect please drop a line