1 Reply Latest reply on Sep 6, 2006 3:35 AM by Ferenc Hechler

    Problem calling SLSBs from isolated EARs

    Ferenc Hechler Newbie

      Hello,

      I am using JBoss 4.0.4GA with EJB3.0 RC 8

      I want to deploy an application split into multiple components.
      The aim is to be able to redeploy one component without touching the others
      (of course only for unchanged interfaces).
      The components communicate using Stateless Session Beans.

      With the JBoss flat class-loading model this is not possible, because of
      class-loader errors after redeploying one component.

      So I decided to use isolated EARs for each component.
      Following the tips at

      http://wiki.jboss.org/wiki/Wiki.jsp?page=CommonHurdlesAndDifficultiesYouMayEncounterDuringEJB3Development

      I adjusted "conf/jboss-service.xml" and "deploy/ear-deployer.xml" to use
      isolation and CallByValue.
      Each EAR has its own loader-repository defined in "META-INF/jboss-app.xml"

      I got thinks working as long as the parameters are of simple type (like String).
      Even complex types work as long as they are defined outside of the EAR, e.g.
      "HashMap".
      I use an simple type defined inside the EAR, like

      public class MyType implements Serializable { public String data; }


      From a client java application I can call all methods via the remote interface:

      void f(String) -> works
      void f(HashMap) -> works
      void f(MyType) -> works


      From iside an SLSB I call another SLSB deployed on the same JBoss in another
      component (which means different EARs and different loader-repositories):

      void f(String) -> works
      void f(HashMap) -> works
      void f(MyType) -> fails


      the following exception is thrown when proxy.f(myType) is called via the local
      interface:

      Caused by: java.lang.IllegalArgumentException: Wrong target. class pkg.MyBean for public java.lang.String pkg.MyBean.f(pkg.MyType)
       at org.jboss.aop.joinpoint.MethodInvocation.handleErrors(MethodInvocation.java:141)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:116)
       at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
       at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:126)
       ... 55 more


      using the remote interface yields:

      Caused by: java.lang.NoClassDefFoundError
       at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:57)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.stateless.StatelessRemoteProxy.invoke(StatelessRemoteProxy.java:102)
       at $Proxy138.processDto(Unknown Source)
       at pkg.MyBean.f(MyBean.java:97)
       ...


      The same problem was mentioned at

      http://jboss.com/index.html?module=bb&op=viewtopic&p=3950618


      So my final question is:
      ========================

      "Is it possible to call SLSBs from other SLSBs in isolated EARs with user defined Types?"

      Best regards,

      feri


        • 1. Re: Problem calling SLSBs from isolated EARs
          Ferenc Hechler Newbie

          The behaviour for CallByValue is described in

          http://wiki.jboss.org/wiki/Wiki.jsp?page=ClassLoadingConfiguration

          as:

          Call By Value

          1. caller does ejb.someMethod()
          2. invocation is marshalled - the parameters are turned into ObjectStream? (a byte[])
          3. container with a different classloader unmarshalls - byte[] -> java Objects - including classloading
          4. invocation is passed through ejb container
          5. container does bean.someMethod()
          6. result is marshalled - the return value is turned into ObjectStream?
          7. result is unmarshalled using the caller's classloader - byte[] -> java Object
          8. result is return to the caller


          If a call "proxy.f(myType)" is done via Call By Value in step 2. the parameter myType should be serialized.
          I modified MyType to debug de-/serialization:

          public class MyType implements Serializable {
           public String str;
           private void writeObject(ObjectOutputStream out) throws IOException
           {
           // debug
           out.defaultWriteObject();
           }
          
           private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
           {
           in.defaultReadObject();
           // debug
           }
          }



          If a call via remote interface is made from a client-java-app the writeObject() and readObject() methods get called.
          If a call is made from inside a SLSB (local interface) neither method gets called.
          So the step 2. (marshall parameters) is missing.

          Did I miss something in the configurations?

          conf/jboss-service.xml:
          ...
          <mbean code="org.jboss.naming.NamingService" name="jboss:service=Naming" xmbean-dd="resource:xmdesc/NamingService-xmbean.xml">
           <attribute name="CallByValue">true</attribute>
           <attribute name="Port">1099</attribute>
           <attribute name="BindAddress">${jboss.bind.address}</attribute>
           <attribute name="RmiPort">1098</attribute>
           <attribute name="RmiBindAddress">${jboss.bind.address}</attribute>
           <depends optional-attribute-name="LookupPool" proxy-type="attribute">jboss.system:service=ThreadPool</depends>
          </mbean>
          ...


          deploy/ear-deployer.xml:
          <server>
           <mbean code="org.jboss.deployment.EARDeployer" name="jboss.j2ee:service=EARDeployer">
           <attribute name="Isolated">true</attribute>
           <attribute name="CallByValue">true</attribute>
           </mbean>
          </server>


          EAR1: META-INF/jboss-app.xml:
          <jboss-app>
           <loader-repository>mydomain:loader=mycomponent1</loader-repository>
          </jboss-app>


          EAR2: META-INF/jboss-app.xml:
          <jboss-app>
           <loader-repository>mydomain:loader=mycomponent2</loader-repository>
          </jboss-app>