Login  Register

Re: Running a JOGL app from a single JAR file

Posted by gouessej on Jan 15, 2015; 2:04pm
URL: https://forum.jogamp.org/Running-a-JOGL-app-from-a-single-JAR-file-tp4033846p4033866.html

sasq wrote
<p>You're right. The version I installed a couple of days ago (which I thought will be the most recent), is jogl-2.0_rc8-r1</p>
Oh my .... Both Jar-in-Jar, multi-Jar and fat JARs aren't supported by JOGL 2.0.

sasq wrote
<p>OK, so I downloaded the 2.2.4, branch "origin/b22x" commit "78f641de80d1c37cd61e5300eeba369c6aa9b1a1" version from the JOGL website and put the selected JAR libs into my project's <code>lib</code> directory.</p>
It's far better.

sasq wrote
<p>So that's where we misunderstood each other: when you were speaking about "fat JAR", I thought it means putting the library JARs into my app's JAR and loading them from there. Now I see that I was supposed to repack all the particular files into a directory structure into my app's JAR.</p>

<p>So I did, and it seems to work now.<br/>
Well, almost:<br/>
It works on Linux and MacOS X, but on Windows I get:</p>

<pre>Starting up the application.
Exception in thread "main" java.lang.UnsatisfiedLinkError: Can't load library: C:\Users\drott_000\Documents\gluegen-rt.dll
        at java.lang.ClassLoader.loadLibrary(Unknown Source)
        at java.lang.Runtime.load0(Unknown Source)
        at java.lang.System.load(Unknown Source)
        at com.jogamp.common.jvm.JNILibLoaderBase.loadLibraryInternal(JNILibLoaderBase.java:596)
        at com.jogamp.common.jvm.JNILibLoaderBase.access$000(JNILibLoaderBase.java:64)
        at com.jogamp.common.jvm.JNILibLoaderBase$DefaultAction.loadLibrary(JNILibLoaderBase.java:96)
        at com.jogamp.common.jvm.JNILibLoaderBase.loadLibrary(JNILibLoaderBase.java:459)
        at com.jogamp.common.os.DynamicLibraryBundle$GlueJNILibLoader.loadLibrary(DynamicLibraryBundle.java:388)
        at com.jogamp.common.os.Platform$1.run(Platform.java:209)
        at java.security.AccessController.doPrivileged(Native Method)
        at com.jogamp.common.os.Platform.<clinit>(Platform.java:179)
        at javax.media.opengl.GLProfile.<clinit>(GLProfile.java:120)
        at texQuads.Main.main(Unknown Source)
</pre>

<p>from one user, and the following from another user:</p>

<pre>c:\> java -jar TextureQuads.jar
Starting up the application.
Exception in thread "main" java.lang.UnsatisfiedLinkError: Can't load library: c:\\gluegen-rt.dll
        at java.lang.ClassLoader.loadLibrary(Unknown Source)
        at java.lang.Runtime.load0(Unknown Source)
        at java.lang.System.load(Unknown Source)
        at com.jogamp.common.jvm.JNILibLoaderBase.loadLibraryInternal(JNILibLoaderBase.java:596)
        at com.jogamp.common.jvm.JNILibLoaderBase.access$000(JNILibLoaderBase.java:64)
        at com.jogamp.common.jvm.JNILibLoaderBase$DefaultAction.loadLibrary(JNILibLoaderBase.java:96)
        at com.jogamp.common.jvm.JNILibLoaderBase.loadLibrary(JNILibLoaderBase.java:459)
        at com.jogamp.common.os.DynamicLibraryBundle$GlueJNILibLoader.loadLibrary(DynamicLibraryBundle.java:388)
        at com.jogamp.common.os.Platform$1.run(Platform.java:209)
        at java.security.AccessController.doPrivileged(Native Method)
        at com.jogamp.common.os.Platform.<clinit>(Platform.java:179)
        at javax.media.opengl.GLProfile.<clinit>(GLProfile.java:120)
        at texQuads.Main.main(Unknown Source)
</pre>

<p>The "Starting up the application." piece comes from my app's <code>main</code> function, so it seems that at least the Java libs are properly being loaded and the application runs. But there is some problem with loading the native libs on Windows (<code>gluegen-rt.dll</code> in particular). On other platforms (Linux and MacOS X) it runs fine.</p>

<p>I have the Windows native libs in my JAR, I checked. Here's how it looks like:</p>

<pre>$ jar  tf  build/jar/TextureQuads.jar  natives
natives/
natives/linux-amd64/
natives/linux-amd64/libjogl_desktop.so
natives/linux-amd64/libjogl_mobile.so
natives/linux-amd64/libnativewindow_awt.so
natives/linux-amd64/libnativewindow_x11.so
natives/linux-amd64/libnewt.so
natives/linux-amd64/libgluegen-rt.so
natives/windows-amd64/
natives/windows-amd64/jogl_desktop.dll
natives/windows-amd64/jogl_mobile.dll
natives/windows-amd64/nativewindow_awt.dll
natives/windows-amd64/nativewindow_win32.dll
natives/windows-amd64/newt.dll
natives/windows-amd64/gluegen-rt.dll
natives/macosx-universal/
natives/macosx-universal/libjogl_desktop.jnilib
natives/macosx-universal/libjogl_mobile.jnilib
natives/macosx-universal/libnativewindow_awt.jnilib
natives/macosx-universal/libnativewindow_macosx.jnilib
natives/macosx-universal/libnewt.jnilib
natives/macosx-universal/libgluegen-rt.jnilib
</pre>

<p>so everything seems to be in place. But Windows says otherwise...</p>
You forgot to put the 32-bit native libraries into your fat JAR. Keep in mind that it is possible to use a 32-bit JRE on a 64-bit operating system. A 32-bit JRE on a 64-bit machine requires 32-bit binaries.

sasq wrote
<p>Well, though I'm an experienced programmer in C++ and a bunch of other languages, I'm still a noob when it comes to Java. I learn how to use JOGL since a week so far, and it's still hard to me to grasp some of these things. I already wasted a couple of days trying to make it compile, and then run, by setting up all these classpaths & stuff and testing lots of different combinations. Then I wasted another couple of days trying to figure out how to make those JARs according to your directions. Although I appreciate your help, I must admit that the information you provide is very scarce and enigmatic, it is all very poorly documented (otherwise I would figure it out myself from reading the docs & wikis). I know that you have a clear picture in your head of how it all works, but I don't, and I have a hard time having to actively dig these informations out from your head, and figuring out what question should I ask next to get another important piece you forgot to tell me.</p>

<p>That's the point: I don't know which solutions are "unnecessary complications" as long as I don't have a clear picture of how it all works internally. I must do a lot of experimenting in a trial-and-error approach and waste a lot of time – a time which could be saved if you state all these little details clearly from the very beginning instead of waiting for me to dig them up from your head. I'm not clairvoyant yet.</p>

<p>One of these important details I missed was the fact that JOGL has its own fancy mechanism for loading these native libraries from the JAR file, and that they have to be put in special locations with hard-coded names to make it work. Not knowing that, I must have to go through several failed attempts with different combinations of these paths before it finally worked. I did read the links you provided, and I did use the <zipfileset> trick, just in a wrong way, with wrong paths.</p>

<p>But that was only after you enlightened me that you didn't mean putting entire JARs into my app's JAR under the "fat JAR" name, but repacking them as plain files in a particular directory structure. You could tell me that a couple of posts ago, when I first asked about putting these JARs into my app's JAR, and you would save me some random erring then.</p>

<p>So is it me who makes unnecessary complications? Or is it the whole jumping through hoops I experience here which actually makes it harder?</p>
I just put a link to 20 lines of XML (Ant script) that you could simply copy/paste/modify to do the job. I think that our misunderstanding (fat JAR vs Jar-in-Jar) made us waste some time. Be patient, you're close to the aim. I warned you several times but you'll probably have some other troubles even with a fat JAR. For example, imagine that an end user tries to use an old Apple JRE 1.6 whereas your code uses Java 1.7... I hope that the extraction of the native libraries doesn't fail in some cases under Windows.
Julien Gouesse | Personal blog | Website