-
Notifications
You must be signed in to change notification settings - Fork 232
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
effects of classloader injection and multiple wars in servlet container #24
Comments
Native code injection checks whether snappy-java is already loaded by another webapp, so the problem you mentioned would not happen. |
Current snappy-java appends version number to the extracted native library, and SnappyNativeLoader.java injected to the root class loader can load different versions of snappy-java. I can say that your proposed solution is partly implemented. But I havent't fully tested this scenario. |
Appending the version to the extracted library may cover my primary concern. Do you change the name of the class which are you are loading via bytecode for each version as well? I guess I just question the value of the finding the parent classloader and injecting the bytecode. It would allow multiple wars/ears in the same jee runtime to share the same library (if using same version). But it also introduces some complexity in that while wars can be stopped/undeployed it does not appear (at least that I can see) that the injected class(es) can ever be cleaned up. If the library were given a completely unique name when it is copied out to be loaded, then there would be no need for injecting byte code into a parent classloader. Then individual wars being stopped/started/undeployed can clean up after themselves and not impact other wars in the same runtime. |
The name of injected classes aren't changed. As you mentioned, unloading injected codes would be difficult. But the current approach solves many other problems, including UnsatisfiedLinkError observed when snappy-java is used in multiple web containers or in different class loaders. Eclipse and various testing frameworks use custom class loaders. Without the native code injection, we cannot use these development tools with snappy-java. Even if you assign unique names to native libraries, it might be necessary to change the function names defined in the libraries to avoid name collisions. Changing function names in the c++ library needs re-compilation, and I don't know how to do it without adding complexities to the building process. |
Java classes and c++ codes must use corresponding function names, so both of them need to be changed to make your solution work. Is there any example that shows using different library file names can avoid function name collision? |
I added a small test to confirm whether changing lib file names works: It succeeded in loading different versions of native libraries in separate class loaders. Great! I haven't noticed to such a simple solution. |
What I believe should work is having SnappyNative actually have a static block that determines the appropriate native library to load, copies it to a unique location in the file system, then calls System.loadLibrary with that absolute path. |
Thanks for the suggestion, and it makes simple the native lib loading part. Merged in to #27 |
What happens if multiple wars in the same tomcat instance contain snappy-java? It would appear that would require that each contain the same version of snappy-java (at least the jni interface must be the same).
Would a better solution to the library problems in a jee environment be to modify the name of the library for each class loader? So in the process of SnappyLoader.loadNativeLibrary method, copy the os/arch specific library to a temp file with a modified name (i.e. libsnappyjava1234.so). Then for that class loader make a static call to System.load(snappyjava1234). The same library may end up being loaded multiple times in the same container, but there will never be any issue with different versions.
The text was updated successfully, but these errors were encountered: