Discussion:
Shared library jni under tomcat
Joel Hirsh
2018-11-20 06:03:22 UTC
Permalink
I am running Tomcat 8.0.32 on LInux, and trying to use a jni library under
tomcat, and am hitting a wall.

First I found that only one instance of the native library can be loaded so
the library needs to live in shared/lib for general use.

Then in order to load the native library I found documentation that I both
needed to load the native library from a bootstrap jar that also lives in
shared/lib and that the jar be loaded with the common clasloader
Ref:
https://wiki.apache.org/tomcat/HowTo#I.27m_encountering_classloader_problems_when_using_JNI_under_Tomcat

So I have my code working to do all that. And if I make a call from the
bootstrap jar to the first native method it works.
But when I try to access the native method from my application code I get
an error "java.lang.UnsatisfiedLinkError:".

I believe that is because the native library has been loaded with the
URLClassLoader and the application is loaded with the WepappClassLoader.
Although I also read that the classloaders are hierarchical, and should go
up the chain to find classes.

I have verified that the URLClassLoader used to load the bootstrap jar is
the same as the parent loader of the application (with .equals())

I did read an ancient thread (2006) that kind of described the problem I am
having, and the last post there indicated that the solution is "to touch
each class that uses native methods (from the loader that loaded the native
library) , forcing the classes to be loaded". But I don't know how to
'touch' a java class. And my classes that use native methods are part of
the application and could not be loaded by the URLClassLoader in any case.
Or even if that post is (still) relevant.

I have run out of ideas on what to do or test next. I've been through doc
like
https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html
and many posts on stackoverflow on this topic, and cannot find anything to
help.

Any suggestions would be most welcome.
Christopher Schultz
2018-11-20 17:02:11 UTC
Permalink
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Joel,
Post by Joel Hirsh
I am running Tomcat 8.0.32 on LInux, and trying to use a jni
library under tomcat, and am hitting a wall.
First I found that only one instance of the native library can be
loaded so the library needs to live in shared/lib for general use.
Then in order to load the native library I found documentation that
I both needed to load the native library from a bootstrap jar that
also lives in shared/lib and that the jar be loaded with the common
https://wiki.apache.org/tomcat/HowTo#I.27m_encountering_classloader_pr
oblems_when_using_JNI_under_Tomcat

All
you should need is the native library in the right place on the
disk (in java.library.path, which you might have to set in setenv.sh)
and enable the APRLifecycleListener in server.xml. It's right at the top
.
Post by Joel Hirsh
So I have my code working to do all that. And if I make a call
from the bootstrap jar to the first native method it works. But
when I try to access the native method from my application code I
get an error "java.lang.UnsatisfiedLinkError:".
What kind of native calls are you trying to make?
Post by Joel Hirsh
I believe that is because the native library has been loaded with
the URLClassLoader and the application is loaded with the
WepappClassLoader. Although I also read that the classloaders are
hierarchical, and should go up the chain to find classes.
I have verified that the URLClassLoader used to load the bootstrap
jar is the same as the parent loader of the application (with
.equals())
I did read an ancient thread (2006) that kind of described the
problem I am having, and the last post there indicated that the
solution is "to touch each class that uses native methods (from the
loader that loaded the native library) , forcing the classes to be
loaded". But I don't know how to 'touch' a java class. And my
classes that use native methods are part of the application and
could not be loaded by the URLClassLoader in any case. Or even if
that post is (still) relevant.
I have run out of ideas on what to do or test next. I've been
through doc like
https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html
and many posts on stackoverflow on this topic, and cannot find
anything to help.
Any suggestions would be most welcome.
Where is your libtcnative.so file on the disk? What is your
java.library.path and where/how are you setting it? Did you enable the
APRLifecycleListener? What code are you using to load the library
(which you really should not need)? What code are you using to
actually *call* the native methods?

- -chris
-----BEGIN PGP SIGNATURE-----
Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/

iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAlv0PhMACgkQHPApP6U8
pFj31Q//Tpyp0jAcLATW5k8HktEMW/8r0lIuGqE2LjN8dGxIjsuOgdBSrjNOsBhC
W4T0In1qAdfaEV94YmCUojS9fDUfkj048bab9ucWVkT16YBv+kN++1V0QHd4uswj
FdinRuEX1W152PeMBYt+ts9TSpGQb30qEpXHhP+KMnt+B0oUwM6z32u0LrUCK4NG
jqLUn7OEpK5qGq9YyIGuQ1IFY135NWOwpmbGXIWfO+8EdbnIsOLnqPXjiJlALGNQ
+F1fmC/rFT61cPN5+TvFOFt/V19X4LTEW8XQLP2kKfXOoATB60TfKjq49dfEEfW2
Zfiz7JNIOJqGQuQZJku3P1pM2Ew64Jt4yV5P2BwLMAXZajKUjfniJWD6ZHMEEbgn
Mn3Gb9QOwFaSsd+HCA8pGrns/pGUzvMyIrNknKwwtOQ4ePuw0U82e0Qdkx+TSoER
XGcSmvug1AeVLl+nW+flbjPw+eyJJgzS739swm5TlSghdUZVOy1Yvmq9BH00nJhN
ET4x4Ilxz3iAnqoc5/AVlQutT0zIwtG6b+KbfJw5iyVlyUEtQf9oLk1hDscLNF1i
UFlb7tGZ4LfLyeoo7K7Mp9qdf5QSVgEYbnB/1dAna412+HbzpLBMtUrtul0JhI09
7TXh+mxV6shsjvP0w9emXm60KwhMP2HuoXcYPBx9Okv9tATEkDs=
=fLPo
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-***@tomcat.apache.org
For additional commands, e-mail: users-***@tomcat.apache.org

Loading...