diff options
4 files changed, 73 insertions, 33 deletions
diff --git a/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java b/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java index 022ec0e..f0ff69d 100644 --- a/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java +++ b/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java @@ -44,6 +44,7 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URI; import java.net.URISyntaxException; +import java.net.URL; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Arrays; @@ -153,22 +154,38 @@ public class JNILibLoaderBase { msg.setLength(0); // reset msg.append("addNativeJarLibsImpl(classFromJavaJar ").append(classFromJavaJar).append(", classJarURI ").append(classJarURI).append(", nativeJarBaseName ").append(nativeJarBasename).append("): "); boolean ok = false; - if(TempJarCache.isInitialized()) { - final String nativeJarName = nativeJarBasename+"-natives-"+PlatformPropsImpl.os_and_arch+".jar"; - msg.append(nativeJarName); - final URI jarSubURI = JarUtil.getJarSubURI( classJarURI ); - if(null == jarSubURI) { - throw new IllegalArgumentException("JarSubURI is null of: "+classJarURI); + if(TempJarCache.isInitialized()) { + final String nativeLibraryPath = "natives/"+PlatformPropsImpl.os_and_arch+"/"; + final ClassLoader cl = classFromJavaJar.getClassLoader(); + final URL nativeLibraryURI = cl.getResource(nativeLibraryPath); + if( null != nativeLibraryURI ) { + // We probably have one big-fat jar file, containing java classes + // and all native platform libraries under 'natives/os.and.arch'! + if( TempJarCache.addNativeLibs(classFromJavaJar, classJarURI, nativeLibraryPath) ) { + ok = true; + msg.append(classJarURI).append(" (fat)"); + if(DEBUG) { + System.err.println(msg.toString()); + } + } } - final String jarUriRoot_s = IOUtil.getURIDirname( jarSubURI.toString() ); - msg.append(" + ").append(jarUriRoot_s); - final URI nativeJarURI = JarUtil.getJarFileURI(jarUriRoot_s+nativeJarName); - msg.append(" -> ").append(nativeJarURI); - if(DEBUG) { - System.err.println(msg.toString()); + if( !ok ) { + // We assume one slim native jar file per 'os.and.arch'! + final String nativeJarName = nativeJarBasename+"-natives-"+PlatformPropsImpl.os_and_arch+".jar"; + msg.append(nativeJarName); + final URI jarSubURI = JarUtil.getJarSubURI( classJarURI ); + if(null == jarSubURI) { + throw new IllegalArgumentException("JarSubURI is null of: "+classJarURI); + } + final String jarUriRoot_s = IOUtil.getURIDirname( jarSubURI.toString() ); + msg.append(" + ").append(jarUriRoot_s); + final URI nativeJarURI = JarUtil.getJarFileURI(jarUriRoot_s+nativeJarName); + msg.append(" -> ").append(nativeJarURI).append(" (slim)"); + if(DEBUG) { + System.err.println(msg.toString()); + } + ok = TempJarCache.addNativeLibs(classFromJavaJar, nativeJarURI, null /* nativeLibraryPath */); } - TempJarCache.addNativeLibs(classFromJavaJar, nativeJarURI); - ok = true; } return ok; } diff --git a/src/java/com/jogamp/common/util/JarUtil.java b/src/java/com/jogamp/common/util/JarUtil.java index 41d68d4..665e196 100644 --- a/src/java/com/jogamp/common/util/JarUtil.java +++ b/src/java/com/jogamp/common/util/JarUtil.java @@ -514,22 +514,23 @@ public class JarUtil { * @param dest * @param nativeLibMap * @param jarFile - * @param deepDirectoryTraversal + * @param nativeLibraryPath if not null, only extracts native libraries within this path. * @param extractNativeLibraries * @param extractClassFiles * @param extractOtherFiles + * @param deepDirectoryTraversal * @return * @throws IOException */ public static final int extract(File dest, Map<String, String> nativeLibMap, JarFile jarFile, + String nativeLibraryPath, boolean extractNativeLibraries, - boolean extractClassFiles, - boolean extractOtherFiles) throws IOException { + boolean extractClassFiles, boolean extractOtherFiles) throws IOException { if (DEBUG) { System.err.println("JarUtil: extract: "+jarFile.getName()+" -> "+dest+ - ", extractNativeLibraries "+extractNativeLibraries+ + ", extractNativeLibraries "+extractNativeLibraries+" ("+nativeLibraryPath+")"+ ", extractClassFiles "+extractClassFiles+ ", extractOtherFiles "+extractOtherFiles); } @@ -543,11 +544,29 @@ public class JarUtil { // Match entries with correct prefix and suffix (ignoring case) final String libBaseName = NativeLibrary.isValidNativeLibraryName(entryName, false); final boolean isNativeLib = null != libBaseName; - if(isNativeLib && !extractNativeLibraries) { - if (DEBUG) { - System.err.println("JarUtil: JarEntry : " + entryName + " native-lib skipped"); + if(isNativeLib) { + if(!extractNativeLibraries) { + if (DEBUG) { + System.err.println("JarUtil: JarEntry : " + entryName + " native-lib skipped, skip all native libs"); + } + continue; + } + if(null != nativeLibraryPath) { + final String nativeLibraryPathS; + final String dirnameS; + try { + nativeLibraryPathS = IOUtil.slashify(nativeLibraryPath, false /* startWithSlash */, true /* endWithSlash */); + dirnameS = IOUtil.getDirname(entryName); + } catch (URISyntaxException e) { + throw new IOException(e); + } + if( !nativeLibraryPathS.equals(dirnameS) ) { + if (DEBUG) { + System.err.println("JarUtil: JarEntry : " + entryName + " native-lib skipped, not in path: "+nativeLibraryPathS); + } + continue; + } } - continue; } final boolean isClassFile = entryName.endsWith(".class"); @@ -581,14 +600,14 @@ public class JarUtil { if (DEBUG) { System.err.println("JarUtil: MKDIR: " + entryName + " -> " + destFile ); } - destFile.mkdir(); + destFile.mkdirs(); } else { final File destFolder = new File(destFile.getParent()); if(!destFolder.exists()) { if (DEBUG) { System.err.println("JarUtil: MKDIR (parent): " + entryName + " -> " + destFolder ); } - destFolder.mkdir(); + destFolder.mkdirs(); } final InputStream in = new BufferedInputStream(jarFile.getInputStream(entry)); final OutputStream out = new BufferedOutputStream(new FileOutputStream(destFile)); diff --git a/src/java/com/jogamp/common/util/cache/TempJarCache.java b/src/java/com/jogamp/common/util/cache/TempJarCache.java index 3943633..e2a33e0 100644 --- a/src/java/com/jogamp/common/util/cache/TempJarCache.java +++ b/src/java/com/jogamp/common/util/cache/TempJarCache.java @@ -197,12 +197,14 @@ public class TempJarCache { * * @param certClass if class is certified, the JarFile entries needs to have the same certificate * @param jarURI + * @param nativeLibraryPath if not null, only extracts native libraries within this path. + * @return true if native libraries were added or previously loaded from given jarURI, otherwise false * @throws IOException if the <code>jarURI</code> could not be loaded or a previous load attempt failed * @throws SecurityException * @throws URISyntaxException * @throws IllegalArgumentException */ - public synchronized static final void addNativeLibs(Class<?> certClass, URI jarURI) throws IOException, SecurityException, IllegalArgumentException, URISyntaxException { + public synchronized static final boolean addNativeLibs(Class<?> certClass, URI jarURI, String nativeLibraryPath) throws IOException, SecurityException, IllegalArgumentException, URISyntaxException { final LoadState nativeLibJarsLS = nativeLibJars.get(jarURI); if( !testLoadState(nativeLibJarsLS, LoadState.LOOKED_UP) ) { nativeLibJars.put(jarURI, LoadState.LOOKED_UP); @@ -211,11 +213,13 @@ public class TempJarCache { System.err.println("TempJarCache: addNativeLibs: "+jarURI+": nativeJar "+jarFile.getName()); } validateCertificates(certClass, jarFile); - JarUtil.extract(tmpFileCache.getTempDir(), nativeLibMap, jarFile, true, false, false); + final int num = JarUtil.extract(tmpFileCache.getTempDir(), nativeLibMap, jarFile, nativeLibraryPath, true, false, false); nativeLibJars.put(jarURI, LoadState.LOADED); - } else if( !testLoadState(nativeLibJarsLS, LoadState.LOADED) ) { - throw new IOException("TempJarCache: addNativeLibs: "+jarURI+", previous load attempt failed"); + return num > 0; + } else if( testLoadState(nativeLibJarsLS, LoadState.LOADED) ) { + return true; } + throw new IOException("TempJarCache: addNativeLibs: "+jarURI+", previous load attempt failed"); } /** @@ -241,7 +245,7 @@ public class TempJarCache { } validateCertificates(certClass, jarFile); JarUtil.extract(tmpFileCache.getTempDir(), null, jarFile, - false, true, false); + null /* nativeLibraryPath */, false, true, false); classFileJars.put(jarURI, LoadState.LOADED); } else if( !testLoadState(classFileJarsLS, LoadState.LOADED) ) { throw new IOException("TempJarCache: addClasses: "+jarURI+", previous load attempt failed"); @@ -269,7 +273,7 @@ public class TempJarCache { } validateCertificates(certClass, jarFile); JarUtil.extract(tmpFileCache.getTempDir(), null, jarFile, - false, false, true); + null /* nativeLibraryPath */, false, false, true); resourceFileJars.put(jarURI, LoadState.LOADED); } else if( !testLoadState(resourceFileJarsLS, LoadState.LOADED) ) { throw new IOException("TempJarCache: addResources: "+jarURI+", previous load attempt failed"); @@ -323,7 +327,7 @@ public class TempJarCache { } validateCertificates(certClass, jarFile); JarUtil.extract(tmpFileCache.getTempDir(), nativeLibMap, jarFile, - extractNativeLibraries, extractClassFiles, extractOtherFiles); + null /* nativeLibraryPath */, extractNativeLibraries, extractClassFiles, extractOtherFiles); // mark loaded (those were just loaded) if(extractNativeLibraries) { diff --git a/src/junit/com/jogamp/common/util/TestTempJarCache.java b/src/junit/com/jogamp/common/util/TestTempJarCache.java index 29fe4c5..7ddf52a 100644 --- a/src/junit/com/jogamp/common/util/TestTempJarCache.java +++ b/src/junit/com/jogamp/common/util/TestTempJarCache.java @@ -147,7 +147,7 @@ public class TestTempJarCache extends JunitTracer { if(AndroidVersion.isAvailable) { System.err.println("n/a on Android"); return; } JarFile jarFile = JarUtil.getJarFile(GlueGenVersion.class.getName(), this.getClass().getClassLoader()); Assert.assertNotNull(jarFile); - JarUtil.extract(fileCache.getTempDir(), null, jarFile, false, true, true); + JarUtil.extract(fileCache.getTempDir(), null, jarFile, null, false, true, true); File f = new File(fileCache.getTempDir(), "META-INF/MANIFEST.MF"); Assert.assertTrue(f.exists()); f = new File(fileCache.getTempDir(), IOUtil.getClassFileName(GlueGenVersion.class.getName())); @@ -207,7 +207,7 @@ public class TestTempJarCache extends JunitTracer { URI nativeJarURI = JarUtil.getJarFileURI(jarUriRoot, nativeJarName); - TempJarCache.addNativeLibs(TempJarCache.class, nativeJarURI); + TempJarCache.addNativeLibs(TempJarCache.class, nativeJarURI, null /* nativeLibraryPath */); String libFullPath = TempJarCache.findLibrary(libBaseName); Assert.assertNotNull(libFullPath); Assert.assertEquals(libBaseName, NativeLibrary.isValidNativeLibraryName(libFullPath, true)); |