From f5c48efcf546ba4e08e197ccced6df83b57e1755 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Fri, 11 Jul 2014 03:05:41 +0200 Subject: Bug 1024: Add fallback for native-jar-file location via classpath In situations, where the native-jar file is not located within the same parent URI as it's java-jar file, our location mechanism fails. This patch adds a classloader based native-jar file location mechanism as a fallback, requiring the native jar file to be included in the users CLASSPATH. Classloader based location algorithm in JNILibLoaderBase.addNativeJarLibsImpl(..): - Extract the 'module-name' from the given classFromJavaJar's package name, i.e. the last package-part: 'jogamp.common.Debug' -> 'common' Hence it is important to pass a 'classFromJavaJar', which last package segment reflects the module-name! - -> , e.g. linux-amd64 -> linux.amd64 (linux/amd64) - Locate class 'jogamp.nativetag...TAG', e.g. 'jogamp.nativetag.common.linux.amd64.TAG' - Use located class's JarFile URI .. continue as usual Injection of above mentioned TAG class via gluegen-cpptasks-base.xml macro 'native.tag.jar': - Creates dummy TAG.java code - Compiles TAG.java - Creates the native-jar file Example: Note that the manifest file uses a matching Extension-Name: Extension-Name: jogamp.nativetag.common --- .../com/jogamp/common/jvm/JNILibLoaderBase.java | 58 ++++++++++++++++++++-- src/java/com/jogamp/common/os/Platform.java | 2 +- 2 files changed, 54 insertions(+), 6 deletions(-) (limited to 'src/java/com/jogamp') diff --git a/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java b/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java index f69ddd1..4bb68d3 100644 --- a/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java +++ b/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java @@ -150,6 +150,8 @@ public class JNILibLoaderBase { loaderAction = action; } + private static final String nativeJarTagPackage = "jogamp.nativetag"; // TODO: sync with gluegen-cpptasks-base.xml + /** * * @param classFromJavaJar @@ -200,10 +202,17 @@ public class JNILibLoaderBase { // We probably have one big-fat jar file, containing java classes // and all native platform libraries under 'natives/os.and.arch'! final URI nativeJarURI = JarUtil.getJarFileURI(jarUriRoot_s+jarBasename); - if( TempJarCache.addNativeLibs(classFromJavaJar, nativeJarURI, nativeLibraryPath) ) { - ok = true; - if (DEBUG) { - System.err.printf("JNILibLoaderBase: addNativeJarLibsImpl: fat: %s -> %s\n", jarBasename, nativeJarURI); + try { + if( TempJarCache.addNativeLibs(classFromJavaJar, nativeJarURI, nativeLibraryPath) ) { + ok = true; + if (DEBUG) { + System.err.printf("JNILibLoaderBase: addNativeJarLibsImpl: fat: %s -> %s%n", jarBasename, nativeJarURI); + } + } + } catch(final Exception e) { + if(DEBUG) { + System.err.printf("JNILibLoaderBase: addNativeJarLibsImpl: Caught %s%n", e.getMessage()); + e.printStackTrace(); } } } @@ -215,7 +224,46 @@ public class JNILibLoaderBase { System.err.printf("JNILibLoaderBase: addNativeJarLibsImpl: module: %s -> %s%n", nativeJarBasename, nativeJarURI); } - ok = TempJarCache.addNativeLibs(classFromJavaJar, nativeJarURI, null /* nativeLibraryPath */); + try { + ok = TempJarCache.addNativeLibs(classFromJavaJar, nativeJarURI, null /* nativeLibraryPath */); + } catch(final Exception e) { + if(DEBUG) { + System.err.printf("JNILibLoaderBase: addNativeJarLibsImpl: Caught %s%n", e.getMessage()); + e.printStackTrace(); + } + } + } + if (!ok) { + // Attempt to find via ClassLoader and Native-Jar-Tag, + // assuming one slim native jar file per 'os.and.arch'! + final String moduleName; + { + final String packageName = classFromJavaJar.getPackage().getName(); + final int idx = packageName.lastIndexOf('.'); + if( 0 <= idx ) { + moduleName = packageName.substring(idx+1); + } else { + moduleName = packageName; + } + } + final String os_and_arch_dot = PlatformPropsImpl.os_and_arch.replace('-', '.'); + final String nativeJarTagClassName = nativeJarTagPackage + "." + moduleName + "." + os_and_arch_dot + ".TAG" ; // TODO: sync with gluegen-cpptasks-base.xml + try { + if(DEBUG) { + System.err.printf("JNILibLoaderBase: addNativeJarLibsImpl: ClassLoader/TAG: Locating module %s, os.and.arch %s: %s%n", + moduleName, os_and_arch_dot, nativeJarTagClassName); + } + final URI nativeJarTagClassJarURI = JarUtil.getJarURI(nativeJarTagClassName, cl); + if (DEBUG) { + System.err.printf("JNILibLoaderBase: addNativeJarLibsImpl: ClassLoader/TAG: %s -> %s%n", nativeJarTagClassName, nativeJarTagClassJarURI); + } + ok = TempJarCache.addNativeLibs(classFromJavaJar, nativeJarTagClassJarURI, null /* nativeLibraryPath */); + } catch (final Exception e ) { + if(DEBUG) { + System.err.printf("JNILibLoaderBase: addNativeJarLibsImpl: Caught %s%n", e.getMessage()); + e.printStackTrace(); + } + } } if (DEBUG) { diff --git a/src/java/com/jogamp/common/os/Platform.java b/src/java/com/jogamp/common/os/Platform.java index b8e3385..12122a2 100644 --- a/src/java/com/jogamp/common/os/Platform.java +++ b/src/java/com/jogamp/common/os/Platform.java @@ -200,7 +200,7 @@ public class Platform extends PlatformPropsImpl { // load GluegenRT native library if(_USE_TEMP_JAR_CACHE[0] && TempJarCache.initSingleton()) { try { - JNILibLoaderBase.addNativeJarLibs(new Class[] { Platform.class }, null); + JNILibLoaderBase.addNativeJarLibs(new Class[] { jogamp.common.Debug.class }, null); } catch (final Exception e0) { // IllegalArgumentException, IOException System.err.println("Caught "+e0.getClass().getSimpleName()+": "+e0.getMessage()+", while JNILibLoaderBase.addNativeJarLibs(..)"); -- cgit v1.2.3