summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/java/com/jogamp/common/jvm/JNILibLoaderBase.java45
-rw-r--r--src/java/com/jogamp/common/util/JarUtil.java39
-rw-r--r--src/java/com/jogamp/common/util/cache/TempJarCache.java18
-rw-r--r--src/junit/com/jogamp/common/util/TestTempJarCache.java4
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));