Need preliminary reviewers: Solaris/Linux shared library version changes Long story, but the background may be important. It's not a slam dunk that these changes will go into JDK7, we may decide to do this in JDK8. I recognize it is late to be doing this in JDK7.
If you have any experience with native shared library versioning or JNI usage, I would really appreciate you taking the time to look at this. Background: A while back, the JDK7 launchers were changed to NOT set LD_LIBRARY_PATH in the environment or use it in anyway to launch the jdk. This was and still is considered a good thing for us to have done. No applications should rely on LD_LIBRARY_PATH, it's a workaround mechanism and comes with some old baggage. But it comes with a cost. Low and behold, what we discovered was that a JDK6 process, if doing an exec of a JDK7 launcher, or anything that might cause an exec of a JDK7, was leaving the LD_LIBRARY_PATH settings for JDK6 libraries in the environment for the JDK7 process to find. And, low and behold, it found the JDK6 shared libraries in some cases. So the JDK7 process would be running with a mix of JDK7 shared libraries and JDK6 shared libraries. This is considered a very very bad thing, but sometimes things appeared to work, and sometimes things would crash, missing newer extern symbols. Workaround: The workaround/solution has been to unset LD_LIBRARY_PATH in the appropriate place, if you have an appropriate place. The difficulty arises when LD_LIBRARY_PATH is being used for some other reason or tool, so just unsetting it needs to be done with care. After running into a situation where the build utility ant (a popular Java application) was running JDK6, and after doing a build of some Java code with JDK7 crashed, I decided to see what could be done to guarantee no mixing happened. Goal/Approach: My goal here is to prevent the mixing of JDK7 shared libraries with those of other JDK releases. My approach was to use shared library versioning to see I could group all the JDK7 shared libraries with the same version, a unique version for this release, and then have any shared library dependencies between them insist on that same shared library version. Any mixing would trigger a runtime linker error. Proposed Changes: There are 2 webrevs here, one for hotspot and one for the jdk. 7021644: Consider using a new version name on all jdk7 shared libraries http://cr.openjdk.java.net/~ohair/openjdk7/jdk7-build-jdk-mapfile/webrev/ http://cr.openjdk.java.net/~ohair/openjdk7/jdk7-build-hotspot-mapfile/webrev/ The libjvm.so and libjawt.so libraries will also provide the older version name. Mapfiles: Sometimes called version scripts, do lots of things, or can, the only part of the mapfiles of interest here is the version name. When you link, the version names of the shared libraries used and seen at link time are baked into your executable or shared library so that at runtime, the runtime linker will make sure you run with the right versions. The error message may be a cryptic runtime linker error, but it will refuse to run. Issues: * On the question of JNI usage, and user's JNI shared libraries being dependent on the older shared library version names from JDK6 and older. The JNI book references: http://java.sun.com/docs/books/jni/html/invoke.html#4944 http://java.sun.com/docs/books/jni/html/invoke.html#24891 Implies that any explicit shared library dependencies on libjvm.so or libjava.so would result in a JNI shared library that is tied to that particular implementation. It recommends using dynamic linking if multiple JDKs would be used. My proposal does not impact dynamic linking, but could catch problems where the dynamic linking was done with LD_LIBRARY_PATH set to other JDKs. It is an accepted fact that not everyone followed this advice, as good as it was. * Native apps linking directly to libjvm.so or any JDK shared library. The JDK is not a native library interface provider, with a few exceptions, libjawt.so and libjvm.so, all the extern symbols in the JDK shared libraries are not public interfaces. Having said that, I'm sure there are some people who may have purposely or accidently become dependent on certain extern symbols in our libraries. * Dynamic linking, which is usually the way most of our shared libraries get loaded into the process, is not an issue here. However, if the shared library has a dependency on another JDK7 shared library, that is where LD_LIBRARY_PATH could kick in and cause the wrong one to be loaded. So you might think that the answer would be to dynamically link everything, and in fact that might be the direction we go with JDK8, that remains to be seen. But that effort is much more work that this person was willing to do. Please, if you read this far, please send me comments. -kto