Solaris/Linux shared library versioning and LD_LIBRARY_PATH

Kelly O'Hair kelly.ohair at oracle.com
Wed Feb 23 22:53:17 UTC 2011


Originally I only sent this out to Oracle mailing lists, but should  
have sent it to
the openjdk alias.

----

Sorry for the wide email. If you don't know anything about Solaris/ 
Linux shared library
versioning, or don't care to know, delete now.
If you do know something about them, please read and comment, I'd like  
to address this issue
quickly.

Windows is not a factor here, although it may have a similar issue,  
this is a Solaris/Linux topic.

The Linker Libraries manual is the Solaris source of information on  
this:
  http://download.oracle.com/docs/cd/E19253-01/817-1984/chapter5-84101/index.html

With JDK7 the internal use of LD_LIBRARY_PATH has been removed, which  
is a good thing, however,
this has created some issues where a JDK6 process (which has  
LD_LIBRARY_PATH defined to point
at the JDK6 directories) doing an exec of JDK7 java causes the JDK7  
java process to get .so files
from the JDK6 image. Not good, and usually fatal or at least bizarre  
behavior time.
LD_LIBRARY_PATH will override the internal RPATH/RUNPATH of a shared  
library, so even though
you explicitly might dlopen a full path to JDK7 libzip.so, if it has a  
dependency on libjava.so,
and has RPATH/RUNPATH set to get the JDK7 version, the LD_LIBRARY_PATH  
overrides it.
This is exactly what has happened to us recently, via an ant process  
running with JDK6 and
exec'ing a JDK7 process. It had seemed to work, but then we found out  
it wasn't right in the head. :^(

There are two ways we load shared libraries, with dlopen (where we  
should ALL be using full
paths to the libraries we are loading, and getting the right ones,  
right?), and via shared library
dependencies. It's the shared library dependencies that can be broken  
here.

The ld mapfiles used in the JDK7 build have declared that all the JDK7  
shared libraries have
the version name SUNWprivate_1.0 or sometimes SUNWprivate_1.1.
This means when we link up our shared libraries, they become dependent  
on that version name
(a unique global object per .so of that name is created in the .so,  
and other .so's require it).

I am proposing we change this name and make it named based on the JDK  
release to prevent
any mixing of shared libraries between JDK releases.
This will be done in stages to avoid a flag day and also isolate any  
flaws in the plan:

Stage 1: Change hotspot

For hotspot, I would like to change the mapfiles to be more like:
  SUNWprivate_1.1 { ... };
  JDK1.7.0 {  } SUNWprivate_1.1;

Integrate that into hotspot and get it promoted.
That will allow the JDK7 hotspot to work in a JDK6 (like when you  
hotspot guys do your
gamma/Queens dance in the makefiles), but when people link directly  
against this libjvm.so, they
will require a JDK1.7.0 versioned one at runtime.
IF someone on the hotspot team wanted to properly sort out the  
interfaces that were introduced
in JDK7, they could construct this more along the lines that this  
original concept expected,
but I'd leave that to the hotspot team. We technically should be using  
this versioning to
explicitly list what interfaces were introduced in what version of the  
shared library.


Stage 2: Change the jdk

Once the above hotspot is promoted, I would go into the rest of the  
JDK7 mapfiles and change
them to be:
  JDK1.7.0  { ... };
Essentially rename SUNWprivate_1.0 to JDK1.7.0. A more restrictive  
change and abandonment of SUNWprivate.

Once this is done, accidental use of a JDK6 .so in a JDK7 process will  
cause a runtime linker error.
This may cause some ripple effects to anyone purposely mixing JDK6  
shared libraries
with JDK7.
JNI users might be impacted because once they have built a .so for  
JDK7, it may not
work in a JDK6 environment, if they were dependent on a JDK7 library.
And if the JNI library was built for JDK6, and had a dependency on the  
old SUNWprivate
interface, it will also fail to load with JDK7. So some JNI users  
could easily be impacted
but only those that created a direct shared library dependence on a  
JDK library.

So if you read this far. Please send me your comments. If I've missed  
some issues let me know.

-kto



More information about the build-dev mailing list