3

I got this working great on Windows -- application loads my plugin (C++, Qt), my plugin does a smart search to find an installed JRE, sets the library search path accordingly, and then calls a function in the JVM which forces the jvm.dll to be loaded at that point. (Previous question: How can I deploy a mixed C++/Java (JNI) application?)

Now I'm trying to get it working on Linux. From what I read, lazy linking/loading was the default, so I thought it would just work.... doesn't seem like it.

I'd like to avoid dlopen() and dlsym(), LD_LIBRARY_PATH, ldconfig, etc. The idea is that users of this plugin shouldn't have to know how any of that works, they just put the plugin.so in the right place, and when it's loaded, the plugin has the smarts to find the JRE (or tell the user to install a JRE).

Can this be done?

EDIT

Just to be clear... the error I get when the plugin is loaded: "Cannot load library /home/dan/blah/blah/libMyPlugin.so: (libjawt.so: cannot open shared object file: No such file or directory)"

EDIT

If it matters... this needs to work on Ubuntu 10.10 and up, on CentOS 5.4, and OSX 10.6+.

On Ubuntu 10.10, I did apt-get install openjdk-6-jdk and then to get things to run correctly I had to

export LD_LIBRARY_PATH=
  /usr/lib/jvm/java-6-openjdk/jre/lib/i386:
  /usr/lib/jvm/java-6-openjdk/jre/lib/i386/client:
  /usr/lib/jvm/java-6-openjdk/jre/lib/i386/xawt

(newlines for legibility)

But if someone had a different JDK installed (e.g., Sun's) then the directories would probably differ (?).

Community
  • 1
  • 1
Dan
  • 5,929
  • 6
  • 42
  • 52
  • The Sun JRE gets `/usr/lib/jvm/java-6-sun-1.6.0.26/jre/lib/...` on my Ubuntu system. – sarnold Mar 01 '12 at 23:18
  • I think this question: http://stackoverflow.com/questions/2009183/how-to-load-a-shared-library-without-loading-its-dependencies is essentially the same issue as my question – Dan Mar 05 '12 at 23:04
  • .. and I think using `dlopen()` is my best option, using the trick described here: http://stackoverflow.com/a/1067684 – Dan Mar 05 '12 at 23:06

2 Answers2

1

How did you conduct the smart search on windows? There are a couple of "normal" places to look in Linux.

A lot of times the $JAVA_HOME environment variable is set to the current JRE.

I don't have ready access to all of the systems you listed, but on some distros, you have a symlink /usr/java/latest which will point to the latest installed version.

In general, if there's a JRE installed, it will probably be in one of /usr/lib/jvm*, /usr/java*, /usr/lib/java*, or possibly one of the lib64 varieties of the above.

Of course, the above methods will most likely point you to a JRE. Deciding which to use might be tricky, but if your code doesn't rely on the latest and greatest, it will probably be okay.

I suppose as part of asking your user to install a JRE if one can't be found, you could ask them to set $JAVA_HOME as that's fairly standard practice.

I don't know of a sure fire way for it to work on all distros, since part of the problem stems from the nature of *nix distributions. There may be an additional convention that I'm missing, however.

zje
  • 3,824
  • 4
  • 25
  • 31
  • On Win I can check the registry and a few well-know locations -- not perfect, but good enough. Those are some great suggestions for *how* to find a JRE, but the problem I'm having is I can't even get the opportunity to do the search, since the loader expects the libjvm.so etc. to be visible right when the plugin is loaded. – Dan Mar 01 '12 at 23:37
0

If your program simply runs java /path/to/foo.jar then the solution is easy on Debian-derived systems:

$ ls -l /usr/bin/java /etc/alternatives/java /usr/lib/jvm/java-6-sun/jre/bin/java | awk '{print $1, $8, $9, $10}'
lrwxrwxrwx /etc/alternatives/java -> /usr/lib/jvm/java-6-sun/jre/bin/java
lrwxrwxrwx /usr/bin/java -> /etc/alternatives/java
-rwxr-xr-x /usr/lib/jvm/java-6-sun/jre/bin/java  
$ 

The java in /usr/bin/java is a symlink to a symlink to the real JRE.

sarnold
  • 102,305
  • 22
  • 181
  • 238
  • The C++ plugin is dynamically linked against libjvm.so. I'm using the JNI invocation interface to create a JVM from a C++ thread. So finding the java executable isn't really the problem, though it may provide a good hint to where there's a JRE installed. – Dan Mar 01 '12 at 23:41