PDA

View Full Version : JNI FindClass returns NULL for user defined classes in resin 3.1


shalabh
12-18-2009, 10:44 AM
When I am trying to find a java class using JNI FindClass method, the method is returning NULL. The class is present in the WEB-INF/classes. The code is working fine if it is run as a standalone java application but when it is deployed on resin, it fails.

According to sun documentation:
http://java.sun.com/docs/books/jni/html/functions.html#52110
In Java 2 SDK release 1.2, FindClass locates the class loader associated with the current native method. If the native code belongs to the null loader, then it uses the bootstrap class loader to load the named class or interface. Otherwise, it invokes the ClassLoader.loadClass method in the corresponding class loader to load the named class or interface.

I think the issue is that there is no class loader invoked by resin for the native code hence it is only searching in the bootstrap classpath and the class is not available there. This is also supported by the fact that if I am trying to find a system class like java.lang.String using the same code, it succeeds.

I also tried to set the classpath using <jvm-classpath> in resin.conf file but the issue is not resolved.

Is there any configuration in resin 3.1 to define class loader for native code or any other workaround to make the JNI API work.

I am using jdk 1.5.

ferg
12-22-2009, 05:00 PM
Normally in Resin you need to use the contextClassLoader. In Java, from

<pre>
Thread thread = Thread.currentThread();
ClassLoader loader = thread.getContextClassLoader();

Class cl = Class.forName("mypkg.MyClass", false, loader);
</pre>

Because Resin has a complex classloader structure, it's important to use the context classloader, rather than the class's own classloader. For example, if the loading class is in the system classpath, but the class you want to load is in WEB-INF/classes, you need to use the context class loader to load it, because WEB-INF/classes is not visible to the system classloader.

shalabh
12-29-2009, 10:04 AM
In Java I can use the contextClassLoader to find the classes using reflection, but the issue is with the JNI FindClass() API. I need to call a Java method from the native code and the JNI does not use the contextClassLoader.
Moreover, even if I passed the path of the required classes in the <jvm-classpath> argument in resin.conf file, still the JNI is unable to find the class.
The only reason I can guess is "If the native code belongs to the null loader, then it uses the bootstrap class loader to load the named class or interface" as mentioned in my previous post.