JNI, System.loadLibrary() and class loader interactions
bhandsaker Aug 25, 2005 10:59 AMIf this is the wrong forum, please redirect this.
I have been debugging a problem with JBoss and JNI native code.
I have sample code that runs outside of JBoss, but when run in JBoss
it throws an UnsatisfiedLinkError referencing the method name on the
first call to a native method. I have verified (at the OS level) that
the DLLs (happens to be Windows) are in fact being loaded in to the
process.
I believe I've finally found the cause of my problem, which I believe
is that the native libraries are loaded in the context of a particular
ClassLoader. In my case, I'm loading the DLLs in one ClassLoader and
the classes that define the native methods are being loaded into a
different ClassLoader.
These are third-party java classes and JNI DLLs, so I don't have control
over the design. The classes to not load the DLLs automatically, the
caller has to do it.
Questions:
1. Does my suspect cause above sound correct? If the DLL is loaded in
a different ClassLoader than the class declaring the native method,
should I expect it to not "see" the loaded native method?
2. I was initially somewhat surprised that this seems to happen even if
I load the DLLs in a ClassLoader that is the parent of the ClassLoader
that loads the class declaring the native method. For example, I have
tried loading the DLLs in the boot class loader (the one that loads
org.jboss.Main), hoping that all descendent class loaders would be
able to see the DLLs, but this did not work. (I loaded just the DLLs
in the boot class loader, not the classes declaring the native methods.)
I haven't been able to find definitive documentation on this in terms
of Java language specs. Is it correct that child class loaders do not
inherit visibility to native libraries loaded by thier parents?
Or is this some kind of bug in the JBoss ClassLoader implementations?
3. If I'm on the right track, what I think I would like to do is to have
my MBean load the DLLs once and then also have the MBean force-load
the classes that declare the native methods. These would not be hot
deployable. Then I would like to be able to reference these classes
from other jars and EJBs that are deployed separately and have my
code be hot deployable.
Should this work?
What class loader is used for an MBean in JBoss?
I read the JMX 4.x class loader documentation but couldn't find
a specific reference to which class loader is used for MBeans.