3 Replies Latest reply on Oct 6, 2010 3:24 AM by jaikiran

    Achieving isolation in 6.0.0.M5

    gwzoller

      Hello,

       

      I'm getting a strange ClassNotFoundException I believe is related to classloaders on JBoss 5.1, 6.0.0 M4/5 (really mostly interested in 6).

       

      I am running an EAR in which I've included a jboss-app.xml file in the ear's META-INF directory to ensure it has a separate classloader (?).

      Contents of this file are:

       

      <jboss-app>
            <loader-repository>
                 com.stuff.profile:archive=Foo.ear
            </loader-repository>
      </jboss-app>

       

      My EAR contains:

       

           FooEJB.jar

           FooClient.jar (contains interfaces like FooLocal I'm interested in below)

           Foo.war (web app for the EAR that can make local calls into the EJB using interfaces found in FooClient.jar)

       

      I inject the EJB in my WAR code thus: (in a ServletContextListener)

       

      @EJB(name="profile")
      private FooLocal profile = null;

       

      Then use it a little later in this code like this:

       

      System.out.println("Before reload: "+profile);
      profile.doSomething();

       

      My Output:
      Before reload: Proxy to jboss.j2ee:ear=Foo.ear,jar=FooEjb.jar,name=profile,service=EJB3 implementing [interface com.stuff.profile.FooLocal]

      ...

      <Clip--preamble exceptions>

      ...
      09:57:13,764 ERROR [STDERR] Caused by: java.lang.ClassNotFoundException: com.stuff.profile.FooLocal
      09:57:13,764 ERROR [STDERR]     at java.net.URLClassLoader$1.run(Unknown Source)
      09:57:13,764 ERROR [STDERR]     at java.security.AccessController.doPrivileged(Native Method)
      09:57:13,764 ERROR [STDERR]     at java.net.URLClassLoader.findClass(Unknown Source)
      09:57:13,764 ERROR [STDERR]     at java.lang.ClassLoader.loadClass(Unknown Source)
      09:57:13,764 ERROR [STDERR]     at java.lang.ClassLoader.loadClass(Unknown Source)
      09:57:13,764 ERROR [STDERR]     at java.lang.Class.forName0(Native Method)
      09:57:13,764 ERROR [STDERR]     at java.lang.Class.forName(Unknown Source)
      09:57:13,764 ERROR [STDERR]     at org.jboss.ejb3.common.classloader.PrimitiveAwareClassLoader.findClass(PrimitiveAwareClassLoader.java:105)
      09:57:13,764 ERROR [STDERR]     at java.lang.ClassLoader.loadClass(Unknown Source)
      09:57:13,764 ERROR [STDERR]     at java.lang.ClassLoader.loadClass(Unknown Source)
      09:57:13,764 ERROR [STDERR]     at org.jboss.ejb3.common.lang.SerializableMethod.getClassFromName(SerializableMethod.java:307)
      09:57:13,764 ERROR [STDERR]     ... 28 more

       

      So the injection worked!  I get a proxy to the local interace I wanted--but it dies trying to marshal the class.

       

      Here's the kicker:  I've got two EARs constructed in essentially identical fashion differeing by their names and loader-repositories.
      If I only put one of these EARs in my JBoss deploy directory everything works!  If I add the other EAR (which alphabetically precedes
      Foo.ear so it loads first), the first EAR works and I get these exceptions on the second.

       

      I'm baffled.  I'm dabbling in the dark art of classloader isolation--and not knowing what I'm doing.

       

      Any ideas greatly appreciated!
      Greg

        • 1. Re: Achieving isolation in 6.0.0.M5
          jaikiran

          Greg Zoller wrote:

           

          Hello,

           

          I'm getting a strange ClassNotFoundException I believe is related to classloaders on JBoss 5.1, 6.0.0 M4/5 (really mostly interested in 6).

           

          I am running an EAR in which I've included a jboss-app.xml file in the ear's META-INF directory to ensure it has a separate classloader (?).

          By default, in JBoss AS6, each .ear has it's own isolated classloader. So you don't need the jboss-app.xml for the classloader config.

           

           

          Greg Zoller wrote:

           

          My EAR contains:

           

               FooEJB.jar

               FooClient.jar (contains interfaces like FooLocal I'm interested in below)

               Foo.war (web app for the EAR that can make local calls into the EJB using interfaces found in FooClient.jar)

           

          I inject the EJB in my WAR code thus: (in a ServletContextListener)

           

          @EJB(name="profile")
          private FooLocal profile = null;

           

          Then use it a little later in this code like this:

           

          System.out.println("Before reload: "+profile);
          profile.doSomething();

           

          My Output:
          Before reload: Proxy to jboss.j2ee:ear=Foo.ear,jar=FooEjb.jar,name=profile,service=EJB3 implementing [interface com.stuff.profile.FooLocal]

          ...

          <Clip--preamble exceptions>

          ...
          09:57:13,764 ERROR [STDERR] Caused by: java.lang.ClassNotFoundException: com.stuff.profile.FooLocal
          09:57:13,764 ERROR [STDERR]     at java.net.URLClassLoader$1.run(Unknown Source)
          09:57:13,764 ERROR [STDERR]     at java.security.AccessController.doPrivileged(Native Method)
          09:57:13,764 ERROR [STDERR]     at java.net.URLClassLoader.findClass(Unknown Source)
          09:57:13,764 ERROR [STDERR]     at java.lang.ClassLoader.loadClass(Unknown Source)
          09:57:13,764 ERROR [STDERR]     at java.lang.ClassLoader.loadClass(Unknown Source)
          09:57:13,764 ERROR [STDERR]     at java.lang.Class.forName0(Native Method)
          09:57:13,764 ERROR [STDERR]     at java.lang.Class.forName(Unknown Source)
          09:57:13,764 ERROR [STDERR]     at org.jboss.ejb3.common.classloader.PrimitiveAwareClassLoader.findClass(PrimitiveAwareClassLoader.java:105)
          09:57:13,764 ERROR [STDERR]     at java.lang.ClassLoader.loadClass(Unknown Source)
          09:57:13,764 ERROR [STDERR]     at java.lang.ClassLoader.loadClass(Unknown Source)
          09:57:13,764 ERROR [STDERR]     at org.jboss.ejb3.common.lang.SerializableMethod.getClassFromName(SerializableMethod.java:307)
          09:57:13,764 ERROR [STDERR]     ... 28 more

           

          So the injection worked!  I get a proxy to the local interace I wanted--but it dies trying to marshal the class.

           

          Can you please post the entire exception stacktrace? Also, are you sure, this is AS6? Because from what I remember, that PrimitiveAwareClassLoader shouldn't come into picture for the EJB3 call.

           

          Greg Zoller wrote:

           


           

          Here's the kicker:  I've got two EARs constructed in essentially identical fashion differeing by their names and loader-repositories.
          If I only put one of these EARs in my JBoss deploy directory everything works!  If I add the other EAR (which alphabetically precedes
          Foo.ear so it loads first), the first EAR works and I get these exceptions on the second.

           

          I'm baffled.  I'm dabbling in the dark art of classloader isolation--and not knowing what I'm doing.

           

          Any ideas greatly appreciated!
          Greg

           

          So you mean, everything works fine if there's only 1 ear deployed. But fails when there are multiple .ears containing the same EJBs? I guess, the injected proxy is perhaps being picked up from the wrong .ear file (but that doesn't explain a CNFE, instead I would have expected a CCE).

          • 2. Re: Achieving isolation in 6.0.0.M5
            gwzoller

            I've attached a file containing two extremely trivial EARs to the original post that illustrate my problem.  (I removed the jboss-app.xml as it isn't needed in AS6.)

             

            Code and a shared library (Scala) is included.  My goal is essentially this:  each of these trivial EARs is only ~17k big, but the Scala lib is ~6M--a huge tax in file size if you anticipate a large number of small EARs deployed.  I want to put the Scala library in default/lib and isolate the EARs so that while each should (hopefully) load its own isolated copy of the Scala lib in memory, at least my EAR file size is nice and small (beneficial for my target environment).

             

            I'm hoping that Scala is neither here nor there--the same principle might apply to any common library you could want to put in default/lib (Richfaces, etc.).

             

            Deploy one EAR and all is well.  Deploy both and one goes boom (one that worked fine alone).

             

            Am I misusing the tech?

             

            Thanks for any ideas.  This is driving me nuts.

            • 3. Re: Achieving isolation in 6.0.0.M5
              jaikiran

              Greg Zoller wrote:

               

              I want to put the Scala library in default/lib and isolate the EARs so that while each should (hopefully) load its own isolated copy of the Scala lib in memory, at least my EAR file size is nice and small (beneficial for my target environment).

               

              If you place the scala library or any other jar in default/lib, then it will be shared by the application classloaders.