2 Replies Latest reply on Mar 28, 2014 4:09 PM by vikrammurugesan

    Not able to use reflection to invoke method on a Class from different Classloader

    vikrammurugesan

      I am migrating my application from EAP 5.1.2 to EAP 6.0.1 (waiting for 6.2.0 to be approved by my company).

       

      Version Details - EAP 6.0.1, Windows x86 JDK 1.7.0_45

       

      We have this logic in our code (EAR artifact) that,

      1. Creates a custom classloader and loads some jars needed into this classloader (it just add all the classes in these jars into the classloader).
      2. Sets the TCCL (thead context class loader) to this custom classloader.
      3. Looks up a specific class from this custom classloader and invokes a method in the class using Reflection.
      4. To invoke the method it passes one of the classes from the Application's module classloader as parameter.
      5. After invoking we set the TCCL back to its original classloader.

       

      We have to do the 5 step logic I mentioned above several times during runtime. And the JARs are different each time.

       

      Step 4 is where the problem arises. Due to the modular classloader design, in EAP 6, the code is not able to invoke this method (because the parameter is of type org.omg.CORBA.portable.InputStream - which is loaded by the JacORB module classloader). It throws IllegalArgumentException saying I'm trying to pass the parameter from the wrong Classloader.

       

      Things I have tried so far,

      • I tried putting the JacORB classes in my project - assuming my app would load the jacorb classes from the app, but I was wrong and I realized I did not understand the classloader design. So I read the Class Loading in AS7 - JBoss AS 7.0 - Project Documentation Editor - which clearly explains why.
      • I tried cloning my java.lang.reflect.Method instance using the transloader API to the app classloader. Unfortuntely transloader can only clone objects that are Seriallizable and java.lang.reflect.Method is not.
      • I tried cloning my paramter of type org.omg.CORBA.portable.InputStream to the custom classloader (TCCL) and again transloader is not able to do it. It is probably a bug in the transloader API and the last time it was updated is 2007. I tried to fix the problems in the transloader project and after I got it working, I was back to square one, It gave the same IllegalArgumentException. So it did not help much
      • I tried adding the JARs to the System Classloader using this technique. Again my App Class loader is not able to load those classes that I added using this technique. I had a look at how the JBoss ModuleClassLoader loads classes and I think the ModuleClassloader will not lookup classes from the URLs I added. Please correct me if I am wrong as I am not very confident about this. Also if there is a way to make the App ModuleClassLoader look up classes from URLs available in System classloader.
      • I tried creating my own JBoss module. It worked but so it is not a workable solution as I have to change the JARs frequently during runtime

       

      As you can seen I have spent the past few days trying to overcome this problem with a solution. I would greatly appreciate any help or ideas.

       

      Thanks,

      Vikram