Need preliminary reviewers: Solaris/Linux shared library version changes

Kelly O'Hair kelly.ohair at oracle.com
Thu Mar 17 01:59:36 UTC 2011


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




More information about the build-dev mailing list