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

Reply via email to