Does OpenJDK statically link the C++ runtime?
kelly.ohair at oracle.com
Thu Jan 5 02:18:38 UTC 2012
On Jan 4, 2012, at 5:43 PM, John Von Seggern wrote:
> Thanks for taking the time to answer my question. This information is
> very helpful.
>> So in general, doing static linking is a bad idea and should not be done lightly, if ever.
> As I've been looking into these issues, I've encountered developers
> who advise against dynamically loading any C++ code. For example, a
> coworker referred me to this article:
> If you don't want to do all that reading, the key quotes are:
> 1. "C++ ABI changes have been introduced with every major release of GCC"
> 2. "code compiled against different ABIs is simply not binary compatible."
> 3. "a fairly workable compromise is to link all C++ code into an
> executable while using dynamically loaded C libraries only."
> 4. "for this to work reliably you must not use dynamically loaded C++ code"
> As I understand it, Sun took a similar approach for JDK4.
Yes, and in 2004/2005, this all may have been true.
But there have always been a bit of a battle between the static and dynamic camps on this topic.
The pro-static people will say you are more predictable and maybe even argue about performance being better.
The pro-dynamic people will say that there a very few bugs in the C++ runtime and all you are doing is
making your product bigger and baking in potential C++ runtime bugs that can't be fixed with a system update.
I'm sure the arguments will go on for a long time.
> The blog article and JDK4 are both getting pretty old now, and it
> sounds like maybe the situation has changed since then.
I think it has. Or rather, I hope it has.
>> It is quite possible that we don't need to static link anything anymore, but that would need to be verified.
> What has changed since JDK4?
The g++ and C++ runtimes have gotten more stable, and as I understand it, the versions of the
C++ runtimes are more readily available on many systems.
Adding a new package to a Linux system is pretty simple now even if you needed to.
>> When you distribute a C++ application you always need to worry about compatibility issues.
> Do you know of a general approach that addresses these issues?
> Feel free to ignore me if answering these questions would take up too
> much of your time. I'm mainly just asking now because I'd like to
> know more. (For my application, I can use the file system rather than
> JNI. JNI would have been more efficient, but this part won't be the
> bottle-neck anyway.)
If you can avoid JNI I would.
If you can keep your JNI native code trivial, and use C, I'd do that.
If your JNI native code is complicated enough to need C++, I'd wonder why not Java?
Native code development is one thing, but JNI development is another.
With JNI, you get all the hassles of native code development, and also have to make sure that what
you build will work well with all the native code in the JDK, which may have used a different
C/C++ compiler, and/or may depend on using a specific version of the C/C++ runtime.
C is easier than C++ because the runtime issues are not as complicated.
And each JDK release uses a different C/C++ compiler and potentially a different C++ runtime.
Usually, only one C++ runtime is allowed in a process at a time, or at least sanity requires that. ;^)
> Thanks again,
> On Wed, Jan 4, 2012 at 5:15 PM, Kelly O'Hair <kelly.ohair at oracle.com> wrote:
>> On Jan 3, 2012, at 10:16 PM, John Von Seggern wrote:
>> Does OpenJDK continue to take this approach?
>> Depends on who does the build. The default might be to statically link,
>> pretty sure anyway.
>> I'm asking because I would like to use the Java Native Interface to
>> call functions in a C++ library (that statically links the C++
>> runtime). When I distribute my application, do I need to worry about
>> C++ ABI compatibility issues?
>> When you distribute a C++ application you always need to worry
>> about compatibility issues.
>> If you statically link in a C++ library, you need to make sure you are not
>> also providing those
>> interfaces as your own public exported interfaces, if you use the proper
>> version scripts (mapfiles) this
>> kind of thing can work fine. But it means that you have baked in the
>> implementation of code that
>> you don't maintain, and any bugs in that code requires you to rebuild your
>> product and re-ship.
>> There is a maintenance cost to static linking.
>> So in general, doing static linking is a bad idea and should not be done
>> lightly, if ever.
>> On Solaris, in OpenJDK makefiles, there is no static linking, or shouldn't
>> be any.
>> On Windows, we do static linking of some DLLs, but not the primary one
>> except in rare cases, which I try to burn from my memory every time I see
>> and we have lots of debates on that issue. With Windows you have to ship the
>> MSVC*.DLLs with your product, so there are space considerations, big DLLs
>> On Linux, we shouldn't use static linking, but we had to a long time ago,
>> and we just haven't undone
>> it completely. Obviously the distros don't want static linking, but when
>> Oracle builds a Linux
>> distribution, the binaries need to run on a variety of Linux systems, so we
>> need to be careful, and
>> we don't want to build a separate Oracle JDK for every Linux distro.
>> It is quite possible that we don't need to static link anything anymore, but
>> that would need to be verified.
>> When the initial JDK4 work was done on Linux, static links of the C++
>> runtime was the only way
>> for us to create binaries that had any chance of running on a variety of
>> distributions of Linux.
>> Of course, then there is the other sharing issue, the one where you copy the
>> source into your
>> repository and build your own private version of a library that also ships
>> with the underlying system.
>> That's another story.
More information about the build-dev