JSR-231: Getting more control over native library loading

Howdy-

I’m trying to produce a jar file which contains within it my application, the jogl.jar, and native libraries. (Actually, I’m including native libraries for a number of platforms.) I have code to extract the libraries from my jar file so that I can loadLibrary() them, and I’d like to do this with the jogl libraries. My goal is to make things more self-contained and not to have to fiddle with command line arguments (-Djava.library.path and friends.)

I’ve discovered that I can disable NativeLibLoader by calling disableLoading(), but this is giving me grief with JSR231 beta 3. There seem to be dependencies on libjawt, and in turn on libmawt. I can load jawt myself, but loadLIbrary(“mawt”) seems to fail consistently (it can’t find it).

In any event, this is cumbersome. I’m open to a better way of doing things. Alternatively, it would be nice if I could tell JOGL where to look for the libraries. E.g., NativeLibLoader.prependSearchPath(<the directory where I’ve just extracted the libraries>).

Also, for style, shouldn’t disableLoading and enableLoading be combined into “setEnableLoading(bool)”?

-Ed

What JDK version do you need to support? If you can assume 5.0 as a minimum then you can use the new import facility of Java Web Start described here so you can just use Java Web Start as you would as if deploying over the web. Personally I would recommend that approach if you can use it.

If you make sure the Toolkit is initialized at the point you try to load the JOGL libraries (Toolkit.getDefaultToolkit() should do this) then you shouldn’t need to try to call loadLibrary() for the AWT. The JAWT you will probably have to do, though, by replicating the code in JOGL’s NativeLibLoader.

I am very reluctant to try to standardize a distribution mechanism for JOGL’s native libraries in the JOGL package. This is what Java Web Start was designed for. We have done a little hack in the JOGLAppletLauncher just for the purpose of bootstrapping JOGL-enabled applets but there are some issues first with applets and second with all of the issues around versioning, updating and unstallation which Java Web Start handles transparently.

Probably, but it’s a matter of taste. I still go back and forth between following the JavaBeans style and writing more terse code.

Regarding the distribution of Jogl, I wanted to throw in my 2 cents. I think Java Web Start is great, but I can’t use it at all.

I distribute an application which uses jogl and I have a terrible time getting jogl installed. The machines that the application is used on are not connected to the internet, and in general aren’t connected to any network. Moreover, I don’t know what’s installed on them other then the jre version I specify. I’ve found no way for my applications to load the jogl jars and dll’s that I distribute other that with a second wrapper application, which frankly is embarassing. It’s hard to extol the greatness of java over .net to my colleagues when they had to write a .net wrapper to get my java programs to reliably run.

It is my hope that jogl would have an official release (when its out of beta) like the other optional java packages.

you could just put the dlls beside your application jar and you are finished. If you create an installer, just make sure, the working directory in the generated .lnk file points to the directory, the dlls are in.

Again, if you assume JRE >= 1.5 then you can just give them a .jnlp file plus the associated jars and Java Web Start will “import” that into its cache without needing to go out on the network. From a distribution point of view it works exactly like a web-based Web Started app, but you don’t need network connectivity and can import from sources like a CD-ROM. Have you looked into this possibility? What are the issues you see with using it?

You can also do similar tricks to what the JOGLAppletLauncher does to decompress the native libraries yourself using Java code and call System.load() instead of System.loadLibrary() in order to load up the native code (calling NativeLibLoader.disableLoading() first). You don’t need a separate wrapper application, though as I mentioned above we’re avoiding standardizing a process like this.

I’ve been reluctant to advocate an installer for JOGL dropping it into the JRE, but perhaps once we reach the final version of the spec and the first version of the RI (and have to maintain strict backward compatibility, etc.) we’ll end up having to go this route.

I prefer not to have JOGL dlls in JRE folders even after v1.0 stable release. It just break all apps still using a bit older version for some reason or other. And maintaining a strict backward compatibility might be a very hard task, look at the java core libraries especially Swing. I say it has not been a joy ride from Swing JRE1.2 to JRE1.5 era.

Or atleast should have a ability to force using app’s own lib folder for jogl.jar and .dll files intead ones in jre folder.

I haven’t had a single problem attributed to moving from 1.2 to Java 5 with Swing. ???

I see the point of keeping things isolated… but it also is a bit irritating to get multiple copies of the same stuff all over the place. I guess that’s where Web Start helps.

I’m not terribly familiar with JNLP, but for my purposes, I don’t think it fits too well. I’m developing research code for myself (primarily), and not redistributing it. I have a single jar file with MANY applications inside it, which I invoke manually… each with a wide variety of ever-changing command line arguments.

I used to just copy the JOGL libraries into the JRE folder, but as others have mentioned, that’s a bad idea for a lot of reasons.

Loading the native libraries can be cumbersome (what with DRIHacks), so what I’d like to be able to do is to reuse the JOGL loader (which knows about DRIHacks and other future work-arounds), but to control it a little better. For example, provide a directory from which the libraries should be loaded.

Or does JNLP still sound like the right solution?

The solution is very simple – just setenv LD_LIBRARY_PATH to contain the directory in which the JOGL native libraries (.so’s) are, as described in the JOGL User’s Guide.

Ken,

I can’t figure out how to launch a app using jnpl that retreives files from a local dir. I imagine you mean to set codebase to point to the current working directory, but I don’t think this it possible. At least it doesnt work for me. Can you point me to the docs on how to setup the scenario you described?

There doesn’t seem to be good documentation on this but some searching turned up a forum posting:

http://forum.java.sun.com/thread.jspa?forumID=38&threadID=595047

Basically you want to use the -import argument to javaws as well as a codebase argument like “file:.”.

JNLP files are just not an option. They don’t accept relative codebase arguments in the .jnlp file, only on the command line. Since JWS wasn’t designed to run applications this way, it is probably a hack that it even works from the command line. Moreover, since one has to pass command line options I’d have to create a batch file to call JWS to call my app… which is not pretty.

The bottom line is that there is no easy way to run non-web java applications using jogl.

The problem is with java of course, but jogl is going to continue getting a slew of bug reports and help requests originating from people moving the jogl.jar and dll’s all over the place trying to get their apps to just run.

FYI, I’ve decided to use JexePack http://www.duckware.com/jexepack/ which is a $100 commercial program. It will bundle all the jars and dlls into one .exe so things just work. I didn’t notice an opensource option (JSmooth, launch4j,…) that would work with JNI dlls.

I’ve attached my jexepack ini file for anyone intereted. It’s pretty simple.

For my game (using JOGL), I’m using Install4j to create an exe wrapper, and NSIS to create an installer. The dlls are provided at installation time by NSIS, and install4j takes care of java installation if not present.

I only use it for windows so far (dmg for mac, ??? for linux)

Lilian

To follow up, I’ve been in contact with the Java Web Start team here at Sun and they’ve basically confirmed that it isn’t currently possible to double-click a JNLP file in order to initiate a CD install. I’ll file an RFE about this if one isn’t filed already.

However, it really shouldn’t be that difficult to initiate installation on the command line. A one-line batch file for Windows and one-line shell script for Unix platforms (including Mac OS X) should suffice to invoke javaws with the appropriate codebase and import arguments. Beyond that, Java Web Start manages everything including installation of the associated native libraries. (Actually, I’m not yet 100% clear on how to import the JOGL extension JNLP – perhaps a two line shell script, one importing JOGL and one importing the app.) Doesn’t that seem like a fairly straightforward solution that also has the advantage of being compatible with web-based upgrades?