I discourage this design, since such deployment removes our artifacts as stored in the jar's manifest file, which helps identifying the jogamp modules for bug reports etc. Further more, adding all native library files for all supported platforms will add-up to +3M of _compressed_ jar data! However, since we don't want to patronize our user base, we shall add this capability to our native JAR lib loading mechanism.
http://jogamp.org/git/?p=gluegen.git;a=commit;h=4aa1478b2e4f1401b08d093461b37a14c9501c29 JNILibLoaderBase.addNativeJarLibsImpl(..): If the modules's jar file contains the folder 'natives/<os.and.arch>/' we assume a big-fat jar and attempt to load all native libraries from the same. The test for above folder is performed via the class ClassLoader's getResource(..) and is considered inexpensive. If the folder exists and native libraries could be loaded, the method returns successfull. Otherwise, the 'slim' jar file is attempted to be loaded, even if such folder exist.
.. doesn't work w/ a JOGL test case .. NativeLibrary.findLibrary(<nativewindow_x11>) (TempJarCache): /tmp/jogamp_0000/file_cache/jln7213615344288012373/jln7163851605135055114/natives/linux-amd64/libnativewindow_x11.so JNILibLoaderBase: loadLibraryInternal(nativewindow_x11), TempJarCache: /tmp/jogamp_0000/file_cache/jln7213615344288012373/jln7163851605135055114/natives/linux-amd64/libnativewindow_x11.so JNILibLoaderBase: System.load(/tmp/jogamp_0000/file_cache/jln7213615344288012373/jln7163851605135055114/natives/linux-amd64/libnativewindow_x11.so) - mode 2 JNILibLoaderBase: loadLibraryInternal(nativewindow_x11): OK - mode 2 JNILibLoaderBase: Loaded Native Library: nativewindow_x11 JNILibLoaderBase: loaded nativewindow_x11 main - DynamicLibraryBundle.init start with: jogamp.opengl.x11.glx.X11GLXDynamicLibraryBundleInfo NativeLibrary.findLibrary(<libGL.so.1>) (TempJarCache): null NativeLibrary.findLibrary(<libGL.so.1>, sun.misc.Launcher$AppClassLoader@13de6be9) (CL): null NativeLibrary.open(global true): Trying to load libGL.so.1 ... Stack: [0x00007f14ab43d000,0x00007f14ab53e000], sp=0x00007f14ab5396b0, free space=1009k Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) C [ld-linux-x86-64.so.2+0x907b] _dl_rtld_di_serinfo+0xa7b C 0x00007f14ab57a548 Java frames: (J=compiled Java code, j=interpreted, Vv=VM code) j java.lang.ClassLoader$NativeLibrary.find(Ljava/lang/String;)J+0 j java.lang.ClassLoader.findNative(Ljava/lang/ClassLoader;Ljava/lang/String;)J+49 v ~StubRoutines::call_stub j jogamp.common.os.UnixDynamicLinkerImpl.dlopen(Ljava/lang/String;I)J+0 j jogamp.common.os.UnixDynamicLinkerImpl.openLibraryImpl(Ljava/lang/String;IZ)J+6 j jogamp.common.os.PosixDynamicLinkerImpl.openLibraryGlobal(Ljava/lang/String;Z)J+6 j com.jogamp.common.os.NativeLibrary.open(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLjava/lang/ClassLoader;Z)Lcom/jogamp/common/os/NativeLibrary;+103 j com.jogamp.common.os.NativeLibrary.open(Ljava/lang/String;Ljava/lang/ClassLoader;Z)Lcom/jogamp/common/os/NativeLibrary;+6 j com.jogamp.common.os.DynamicLibraryBundle.loadFirstAvailable(Ljava/util/List;Ljava/lang/ClassLoader;Z)Lcom/jogamp/common/os/NativeLibrary;+27 j com.jogamp.common.os.DynamicLibraryBundle.loadLibraries()V+77 j com.jogamp.common.os.DynamicLibraryBundle.access$000(Lcom/jogamp/common/os/DynamicLibraryBundle;)V+1 j com.jogamp.common.os.DynamicLibraryBundle$1.run()V+4 j com.jogamp.common.util.RunnableExecutor$CurrentThreadExecutor.invoke(ZLjava/lang/Runnable;)V+1 j com.jogamp.common.os.DynamicLibraryBundle.<init>(Lcom/jogamp/common/os/DynamicLibraryBundleInfo;)V+250 j jogamp.opengl.GLDynamicLookupHelper.<init>(Ljogamp/opengl/GLDynamicLibraryBundleInfo;)V+2 j jogamp.opengl.DesktopGLDynamicLookupHelper.<init>(Ljogamp/opengl/DesktopGLDynamicLibraryBundleInfo;)V+2 j jogamp.opengl.x11.glx.X11GLXDrawableFactory$1.run()Ljogamp/opengl/DesktopGLDynamicLookupHelper;+11 j jogamp.opengl.x11.glx.X11GLXDrawableFactory$1.run()Ljava/lang/Object;+1
Bug 845: Fix JNILibLoaderBase.addNativeJarLibsImpl(..) fat-jar case. Always use the jar-basename when calling TempJarCache.addNativeLibs(..), otherwise it is mapped and loaded multiple times leading to different native libraries. Simplify addNativeJarLibsImpl(..) argument semantics by passing complete jarBasename and nativeJarBasename (w/ suffix). Added manual test scripts validating [gluegen + jogl] usage with multi (Bug 843) and fat (Bug 845) jar configurations.
(In reply to comment #0) > I discourage this design, since such deployment removes our artifacts as > stored in > the jar's manifest file, which helps identifying the jogamp modules for bug > reports etc. > > Further more, adding all native library files for all supported platforms > will add-up to +3M of _compressed_ jar data! > > However, since we don't want to patronize our user base, > we shall add this capability to our native JAR lib loading mechanism. Moreover, some web browsers may modify the content of JARs when downloading them which de facto prevents from "running" them. The default archivers under GNU Linux and Windows often open them as ZIP archives which prevents from running them once again. A fat JAR should only be used in the following cases: - with Java Web Start (and JARs signed with a "trusted" certificate), when the OCSP requests take a very long time because of an high number of JARs and/or slow OCSP servers. Oracle plans to replace OCSP by another mechanism - with another installer in order to improve the native integration of an application based on JOGL, for example with IzPack. Using a native installer is very helpful to work around the limitations of the deployment of applications as JARs as double-clicking on them is not guaranteed to work as I've just explained above. Fat JARs can be created with some build tools including Ant. For example, you can use the "zip" task with the "zipgroupfileset" task to merge JARs but the raw result is a bit messy.
At first, there is a risk of crash Ant when updating a JAR/ZIP with duplicate entries, I advise to use at least Ant 1.9.2: https://issues.apache.org/bugzilla/show_bug.cgi?id=54967 This is an example of macro that merges jogl-all.jar, gluegen-rt.jar, gluegen-rt-natives-windows-i586.jar and jogl-all-natives-windows-i586.jar into a single fat jar: <macrodef name="create_jogamp_fatjar"> <attribute name="src" /> <attribute name="dest" /> <sequential> <delete file="@{dest}" failonerror="false" /> <unzip src="@{src}/gluegen-rt-natives-windows-i586.jar" dest="@{src}/natives/windows-i586"> <patternset> <include name="*.dll" /> </patternset> </unzip> <unzip src="@{src}/jogl-all-natives-windows-i586.jar" dest="@{src}/natives/windows-i586"> <patternset> <include name="*.dll" /> </patternset> </unzip> <zip destfile="@{dest}"> <zipgroupfileset dir="@{src}" includes="*.jar" excludes="*-natives-*.jar" /> <zipfileset dir="@{src}" includes="**/*.dll" /> <zipfileset dir="@{src}" includes="**/*.so" /> </zip> <delete dir="@{src}/natives" /> </sequential> </macrodef>
Any chance of supporting loading all libraries from / as a fall-back if not found ind /natives/<os.and.arch>/? When using maven-shade-plugin to generate a fat-jar, it squashes them all into where they are located in their original jars. Another idea might be to nest them into their natives/<os.and.arch>/ in their native jars instead of at the root level.
(In reply to comment #6) > Any chance of supporting loading all libraries from / as a fall-back if not > found ind /natives/<os.and.arch>/? > > When using maven-shade-plugin to generate a fat-jar, it squashes them all > into where they are located in their original jars. > > Another idea might be to nest them into their natives/<os.and.arch>/ in > their native jars instead of at the root level. Maybe you could use a post-treatment rather than asking us to modify JOGL JAR file handling. We won't support tens of different conventions. You can use Maven Ant plugin and modify the resulting JARs by yourself.