https://bz.apache.org/bugzilla/show_bug.cgi?id=62830

--- Comment #17 from Igal Sapir <isa...@apache.org> ---
(In reply to Christopher Schultz from comment #16)
> (In reply to Igal Sapir from comment #13)
> > (In reply to Christopher Schultz from comment #12)
> > <snip/>
> > 
> > Below are the relevant log entries:
> > 
> > > 22-Oct-2018 18:45:04.739 INFO [main] 
> > > org.apache.catalina.core.JniLifecycleListener.lifecycleEvent Loaded 
> > > native library opencv_java343
> > > 22-Oct-2018 18:45:04.759 INFO [main] 
> > > org.apache.catalina.core.JniLifecycleListener.lifecycleEvent Loaded 
> > > native library opencv_java343
> 
> Okay.
> 
> 
> > Then I modified ROOT.xml, context_1.xml, and context_2.xml, one at a time:
> > 
> > > 22-Oct-2018 18:45:51.692 INFO 
> > > [ContainerBackgroundProcessor[StandardEngine[Catalina]]] 
> > > org.apache.catalina.core.JniLifecycleListener.lifecycleEvent Loaded 
> > > native library opencv_java343
> > > [...]
> > > 22-Oct-2018 18:46:01.803 INFO 
> > > [ContainerBackgroundProcessor[StandardEngine[Catalina]]] 
> > > org.apache.catalina.core.JniLifecycleListener.lifecycleEvent Loaded 
> > > native library opencv_java343
> 
> Interesting. I didn't realize that the JVM binds the native library to a
> specific ClassLoader and, does one of two things if the library has alreayd
> been loaded:
> 
> 1. Ignores the call (if in the same ClassLoader; says so in javadoc for
> Runtime.loadLibrary)
> 2. Throws an UnsatisfiedLinkError complaining that the library is already
> loaded from a different ClassLoader.
> 
> The Java spec[1] has something odd to say about native lirbaries and
> ClassLoaders, though it's still a little unclear:

Oh, that is a much newer version of the link that I posted in the OP.  I'll
give it a read.

> "The programmer may use a single library to store all the native methods
> needed by any number of classes, as long as these classes are to be loaded
> with the same class loader. The VM internally maintains a list of loaded
> native libraries for each class loader."
> 
> I guess "same class loader" can also mean "or a child class loader" since
> it's evidently working for you.

I believe that this is due to the delegation model [2] of class loaders (or
else that would have really been useless as Remy pointed out above):

"
When requested to find a class or resource, a ClassLoader instance will
delegate the search for the class or resource to its parent class loader before
attempting to find the class or resource itself.
"

There is some variation in the Servlet spec for the order IIRC, but there is
still delegation. 

> But the point is that you need to consistently (re)load the native library
> into the same classloader if you don't want to throw any errors.

It's not actually re-loading.  As you cited above, subsequent calls are
ignored, but yes, they must be done in the same class loader or its lineage.  

That's the reason for adding the static methods to Library and adding the
Listener.  Because these classes are in $CATALINA_HOME/lib, the native library
to be loaded by a shared class loader which is in the lineage.

> [1]
> https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.
> html#jni_interface_functions_and_pointers

[2] https://docs.oracle.com/javase/8/docs/api/java/lang/ClassLoader.html

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to