1 Reply Latest reply on Apr 10, 2015 4:26 AM by Andrew Dinn

    Using Loaded classes in Helper Class

    John Martin Newbie

      Suppose i have my own helper class defined for application and i loaded my helper class in boot sequence using -b option.

      but whenever i try to use methods used in application in helper class it's throwing exception.

       

      e.g.  1. Even if my application using mysql jar to connect to database, if try to create connection in helper class

      it's throwing exception at mysql driver loading as java.lang.ClassNotFoundException: com/mysql/jdbc/Driver

      the problem remains same even including mysql jar in helper jar

      e.g. 2. If I try to access any method defined in application using Reflection classes it will through

      ClassNotFoundException

       

      Thanks in Advance,

        • 1. Re: Using Loaded classes in Helper Class
          Andrew Dinn Master

          Hi John,

           

          Apologies for not answering sooner -- afraid I missed the email notification for this question (I got 3 copies in my email folder all of them marked as read :-/ ???)

           

          The problem is to do with classloaders -- in this case the linkage between the helper and the sql classes. When Byteman links rule code into a target method it ensures that classes in the rule code are linked via a classloader which inherits from the target method's classloader. So, if the target method can link against com/mysql/jdbc/Driver then so can the rule code.

           

          Now when you call out to a helper method things are different. The classloader for the helper class is the one the JVM uses to load the helper class. If you have placed the helper jar into the bootstrap classpath then your helper class will only be able to see classes loaded by the bootstrap loader.  If you have added it to the system classpath then your helper class will only be able to see classes which are loaded by the system classloader  (that's assuming you are not using a module loader -- with  OSGi or JBoss Modules the visibility are much more complicated). So, in these cases your helper class will only be able to refer to the sql driver class if the sql jar is deployed in the bootstrap or system classpath.

           

          If your sql driver class is in a scoped deployment like an ear or a web app then the only way to make it possible for your helper class to see the sql class is to add it to the deployment. That will also ensure that the Byteman rule code can be linked against the helper when it is injected into the target method. If you are using a module loader then you may be able to deploy your helper in a module and add module dependencies from i) the helper's module to the sql driver module and ii) the target method owner's module to your helper module.

           

          [Well, that's not quite the end of the story. If your helper class is in the bootstrap path then it can locate the classloader of the target method owner, lookup the sql driver class by name and then call methods of that class by reflection. Assuming you don't have a restrictive security policy this ought to work without hitting security exceptions. If you really want to be able to access the driver I suggest you try it and see what happens.]

           

          So, just to tie up any loose strings attached to your reference to the -b option, you may be wondering why we provide a way of loading the helper jar into the bootstrap classpath? (n.b. that's using bmsubmit -b /path/to/myhelper.jar to load into a running JVM or -javaagent::....,boot:/path/to/myhelper.jar from the java command line). Those options don't exist to deal with this general problem you are hitting (we usually refer to the general problem as classloader hell). Actually, they are only provided for a very special case -- when you want to inject code into JVM runtime bootstrap classes. Imagine you want to inject a rule into java.lang.Thread. The injected code needs to handle errors thrown by Byteman. That means the Byteman jar needs to be placed into the bootstrap classpath. Now, when Byteman injects the rule it needs to link the rule code using the loader of class Thread i.e. the bootstrap loader. But the rule code references the helper class. So that class also needs to be loaded via the bootstrap loader.