summaryrefslogtreecommitdiffstats
path: root/src/java/com/jogamp/common/util/cache
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2012-06-26 10:39:23 +0200
committerSven Gothel <[email protected]>2012-06-26 10:39:23 +0200
commit9a71703904ebfec343fb2c7266343d37a2e4c3db (patch)
tree7ca65a063f218064059743ca5cda7744cfc75c20 /src/java/com/jogamp/common/util/cache
parent2a10f604b65f12ae5e8987bfa73cffcc1d5f796e (diff)
Implement Bug #598 - JOGL ALL JAR File Change incl. it's Native Jar URL Derivation
+++ JNILibLoaderBase.addNativeJarLibs(..): Add API doc JNILibLoaderBase: "addNativeJarLibs(Class<?> classFromJavaJar, String allNativeJarBaseName, String[] atomicNativeJarBaseNames)" -> "addNativeJarLibs(Class<?>[] classesFromJavaJars, String singleJarMarker, String[] stripBasenameSuffixes)" Derive the 'all' (1st choice) native JAR URL solely on the given class's JAR URL. Examples: JOCL: // only: jocl.jar -> jocl-natives-'os.and.arch'.jar addNativeJarLibs(new Class<?>[] { JOCLJNILibLoader.class }, null, null ); JOGL: final ClassLoader cl = GLProfile.class.getClassLoader(); // either: [jogl-all.jar, jogl-all-noawt.jar, jogl-all-mobile.jar] -> jogl-all-natives-<os.and.arch>.jar // or: nativewindow-core.jar -> nativewindow-natives-<os.and.arch>.jar, // jogl-core.jar -> jogl-natives-<os.and.arch>.jar, // (newt-core.jar -> newt-natives-<os.and.arch>.jar)? (if available) final String newtFactoryClassName = "com.jogamp.newt.NewtFactory"; final Class<?>[] classesFromJavaJars = new Class<?>[] { NWJNILibLoader.class, GLProfile.class, null }; if( ReflectionUtil.isClassAvailable(newtFactoryClassName, cl) ) { classesFromJavaJars[2] = ReflectionUtil.getClass(newtFactoryClassName, false, cl); } JNILibLoaderBase.addNativeJarLibs(classesFromJavaJars, "-all", new String[] { "-noawt", "-mobile", "-core" } ); Efficiency / Performance: - Reduced JAR URL lookup calls JarUtil.getJarURL(..) - JNILibLoaderBase, Platform, JarUtil - Attempt loading Jar files (native, class, ..) only once - TempJarCache Code Cleanup (IOUtil, JarUtil, : - IOException if not found - IllegalArgumentException if null argument +++ jogamp.android-launcher.jar -> jogamp-android-launcher.jar +++
Diffstat (limited to 'src/java/com/jogamp/common/util/cache')
-rw-r--r--src/java/com/jogamp/common/util/cache/TempJarCache.java174
1 files changed, 116 insertions, 58 deletions
diff --git a/src/java/com/jogamp/common/util/cache/TempJarCache.java b/src/java/com/jogamp/common/util/cache/TempJarCache.java
index e4a77fe..6f24c68 100644
--- a/src/java/com/jogamp/common/util/cache/TempJarCache.java
+++ b/src/java/com/jogamp/common/util/cache/TempJarCache.java
@@ -39,9 +39,7 @@ import java.net.URL;
import java.security.cert.Certificate;
import java.util.Enumeration;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Map;
-import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
@@ -62,10 +60,24 @@ public class TempJarCache {
// unpacked library file in nativeTmpDir.
private static Map<String, String> nativeLibMap;
- // Set of native jar files added
- private static Set<URL> nativeLibJars;
- private static Set<URL> classFileJars;
- private static Set<URL> resourceFileJars;
+ public enum LoadState {
+ LOOKED_UP, LOADED;
+
+ public boolean compliesWith(LoadState o2) {
+ return null != o2 ? compareTo(o2) >= 0 : false;
+ }
+ }
+ private static boolean testLoadState(LoadState has, LoadState exp) {
+ if(null == has) {
+ return null == exp;
+ }
+ return has.compliesWith(exp);
+ }
+
+ // Set of jar files added
+ private static Map<URL, LoadState> nativeLibJars;
+ private static Map<URL, LoadState> classFileJars;
+ private static Map<URL, LoadState> resourceFileJars;
private static TempFileCache tmpFileCache;
@@ -92,9 +104,9 @@ public class TempJarCache {
if(!staticInitError) {
// Initialize the collections of resources
nativeLibMap = new HashMap<String, String>();
- nativeLibJars = new HashSet<URL>();
- classFileJars = new HashSet<URL>();
- resourceFileJars = new HashSet<URL>();
+ nativeLibJars = new HashMap<URL, LoadState>();
+ classFileJars = new HashMap<URL, LoadState>();
+ resourceFileJars = new HashMap<URL, LoadState>();
}
if(DEBUG) {
System.err.println("TempJarCache.initSingleton(): ok "+(false==staticInitError)+", "+ tmpFileCache.getTempDir());
@@ -163,28 +175,28 @@ public class TempJarCache {
return tmpFileCache;
}
- public static boolean containsNativeLibs(URL jarURL) throws IOException {
+ public synchronized static boolean checkNativeLibs(URL jarURL, LoadState exp) throws IOException {
checkInitialized();
if(null == jarURL) {
throw new IllegalArgumentException("jarURL is null");
}
- return nativeLibJars.contains(jarURL);
+ return testLoadState(nativeLibJars.get(jarURL), exp);
}
- public static boolean containsClasses(URL jarURL) throws IOException {
+ public synchronized static boolean checkClasses(URL jarURL, LoadState exp) throws IOException {
checkInitialized();
if(null == jarURL) {
throw new IllegalArgumentException("jarURL is null");
}
- return classFileJars.contains(jarURL);
+ return testLoadState(classFileJars.get(jarURL), exp);
}
- public static boolean containsResources(URL jarURL) throws IOException {
+ public synchronized static boolean checkResources(URL jarURL, LoadState exp) throws IOException {
checkInitialized();
if(null == jarURL) {
throw new IllegalArgumentException("jarURL is null");
}
- return resourceFileJars.contains(jarURL);
+ return testLoadState(resourceFileJars.get(jarURL), exp);
}
/**
@@ -192,20 +204,23 @@ public class TempJarCache {
*
* @param certClass if class is certified, the JarFile entries needs to have the same certificate
* @param jarURL
- *
- * @throws IOException
+ * @throws IOException if the <code>jarURL</code> could not be loaded or a previous load attempt failed
* @throws SecurityException
*/
- public static final void addNativeLibs(Class<?> certClass, URL jarURL, ClassLoader cl) throws IOException, SecurityException {
- if(!containsNativeLibs(jarURL)) {
- final JarFile jarFile = JarUtil.getJarFile(jarURL, cl);
+ public synchronized static final void addNativeLibs(Class<?> certClass, URL jarURL) throws IOException, SecurityException {
+ final LoadState nativeLibJarsLS = nativeLibJars.get(jarURL);
+ if( !testLoadState(nativeLibJarsLS, LoadState.LOOKED_UP) ) {
+ nativeLibJars.put(jarURL, LoadState.LOOKED_UP);
+ final JarFile jarFile = JarUtil.getJarFile(jarURL);
if(DEBUG) {
System.err.println("TempJarCache: addNativeLibs: "+jarURL+": nativeJar "+jarFile.getName());
}
validateCertificates(certClass, jarFile);
JarUtil.extract(tmpFileCache.getTempDir(), nativeLibMap, jarFile,
true, false, false);
- nativeLibJars.add(jarURL);
+ nativeLibJars.put(jarURL, LoadState.LOADED);
+ } else if( !testLoadState(nativeLibJarsLS, LoadState.LOADED) ) {
+ throw new IOException("TempJarCache: addNativeLibs: "+jarURL+", previous load attempt failed");
}
}
@@ -217,20 +232,23 @@ public class TempJarCache {
*
* @param certClass if class is certified, the JarFile entries needs to have the same certificate
* @param jarFile
- *
- * @throws IOException
+ * @throws IOException if the <code>jarURL</code> could not be loaded or a previous load attempt failed
* @throws SecurityException
*/
- public static final void addClasses(Class<?> certClass, URL jarURL, ClassLoader cl) throws IOException, SecurityException {
- if(!containsClasses(jarURL)) {
- final JarFile jarFile = JarUtil.getJarFile(jarURL, cl);
+ public synchronized static final void addClasses(Class<?> certClass, URL jarURL) throws IOException, SecurityException {
+ final LoadState classFileJarsLS = classFileJars.get(jarURL);
+ if( !testLoadState(classFileJarsLS, LoadState.LOOKED_UP) ) {
+ classFileJars.put(jarURL, LoadState.LOOKED_UP);
+ final JarFile jarFile = JarUtil.getJarFile(jarURL);
if(DEBUG) {
System.err.println("TempJarCache: addClasses: "+jarURL+": nativeJar "+jarFile.getName());
}
validateCertificates(certClass, jarFile);
JarUtil.extract(tmpFileCache.getTempDir(), null, jarFile,
false, true, false);
- classFileJars.add(jarURL);
+ classFileJars.put(jarURL, LoadState.LOADED);
+ } else if( !testLoadState(classFileJarsLS, LoadState.LOADED) ) {
+ throw new IOException("TempJarCache: addClasses: "+jarURL+", previous load attempt failed");
}
}
@@ -239,21 +257,24 @@ public class TempJarCache {
*
* @param certClass if class is certified, the JarFile entries needs to have the same certificate
* @param jarFile
- *
* @return
- * @throws IOException
+ * @throws IOException if the <code>jarURL</code> could not be loaded or a previous load attempt failed
* @throws SecurityException
*/
- public static final void addResources(Class<?> certClass, URL jarURL, ClassLoader cl) throws IOException, SecurityException {
- if(!containsResources(jarURL)) {
- final JarFile jarFile = JarUtil.getJarFile(jarURL, cl);
+ public synchronized static final void addResources(Class<?> certClass, URL jarURL) throws IOException, SecurityException {
+ final LoadState resourceFileJarsLS = resourceFileJars.get(jarURL);
+ if( !testLoadState(resourceFileJarsLS, LoadState.LOOKED_UP) ) {
+ resourceFileJars.put(jarURL, LoadState.LOOKED_UP);
+ final JarFile jarFile = JarUtil.getJarFile(jarURL);
if(DEBUG) {
System.err.println("TempJarCache: addResources: "+jarURL+": nativeJar "+jarFile.getName());
}
validateCertificates(certClass, jarFile);
JarUtil.extract(tmpFileCache.getTempDir(), null, jarFile,
false, false, true);
- resourceFileJars.add(jarURL);
+ resourceFileJars.put(jarURL, LoadState.LOADED);
+ } else if( !testLoadState(resourceFileJarsLS, LoadState.LOADED) ) {
+ throw new IOException("TempJarCache: addResources: "+jarURL+", previous load attempt failed");
}
}
@@ -266,41 +287,62 @@ public class TempJarCache {
*
* @param certClass if class is certified, the JarFile entries needs to have the same certificate
* @param jarFile
- *
- * @throws IOException
+ * @throws IOException if the <code>jarURL</code> could not be loaded or a previous load attempt failed
* @throws SecurityException
*/
- public static final void addAll(Class<?> certClass, URL jarURL, ClassLoader cl) throws IOException, SecurityException {
+ public synchronized static final void addAll(Class<?> certClass, URL jarURL) throws IOException, SecurityException {
checkInitialized();
if(null == jarURL) {
throw new IllegalArgumentException("jarURL is null");
}
- if(!nativeLibJars.contains(jarURL) ||
- !classFileJars.contains(jarURL) ||
- !resourceFileJars.contains(jarURL)) {
- final JarFile jarFile = JarUtil.getJarFile(jarURL, cl);
+ final LoadState nativeLibJarsLS = nativeLibJars.get(jarURL);
+ final LoadState classFileJarsLS = classFileJars.get(jarURL);
+ final LoadState resourceFileJarsLS = resourceFileJars.get(jarURL);
+ if( !testLoadState(nativeLibJarsLS, LoadState.LOOKED_UP) ||
+ !testLoadState(classFileJarsLS, LoadState.LOOKED_UP) ||
+ !testLoadState(resourceFileJarsLS, LoadState.LOOKED_UP) ) {
+
+ final boolean extractNativeLibraries = !testLoadState(nativeLibJarsLS, LoadState.LOADED);
+ final boolean extractClassFiles = !testLoadState(classFileJarsLS, LoadState.LOADED);
+ final boolean extractOtherFiles = !testLoadState(resourceFileJarsLS, LoadState.LOOKED_UP);
+
+ // mark looked-up (those who are not loaded)
+ if(extractNativeLibraries) {
+ nativeLibJars.put(jarURL, LoadState.LOOKED_UP);
+ }
+ if(extractClassFiles) {
+ classFileJars.put(jarURL, LoadState.LOOKED_UP);
+ }
+ if(extractOtherFiles) {
+ resourceFileJars.put(jarURL, LoadState.LOOKED_UP);
+ }
+
+ final JarFile jarFile = JarUtil.getJarFile(jarURL);
if(DEBUG) {
System.err.println("TempJarCache: addAll: "+jarURL+": nativeJar "+jarFile.getName());
}
- final boolean extractNativeLibraries = !nativeLibJars.contains(jarURL);
- final boolean extractClassFiles = !classFileJars.contains(jarURL);
- final boolean extractOtherFiles = !resourceFileJars.contains(jarURL);
validateCertificates(certClass, jarFile);
JarUtil.extract(tmpFileCache.getTempDir(), nativeLibMap, jarFile,
extractNativeLibraries, extractClassFiles, extractOtherFiles);
+
+ // mark loaded (those were just loaded)
if(extractNativeLibraries) {
- nativeLibJars.add(jarURL);
+ nativeLibJars.put(jarURL, LoadState.LOADED);
}
if(extractClassFiles) {
- classFileJars.add(jarURL);
+ classFileJars.put(jarURL, LoadState.LOADED);
}
if(extractOtherFiles) {
- resourceFileJars.add(jarURL);
+ resourceFileJars.put(jarURL, LoadState.LOADED);
}
+ } else if( !testLoadState(nativeLibJarsLS, LoadState.LOADED) ||
+ !testLoadState(classFileJarsLS, LoadState.LOADED) ||
+ !testLoadState(resourceFileJarsLS, LoadState.LOADED) ) {
+ throw new IOException("TempJarCache: addAll: "+jarURL+", previous load attempt failed");
}
}
- public static final String findLibrary(String libName) {
+ public synchronized static final String findLibrary(String libName) {
checkInitialized();
// try with mapped library basename first
String path = nativeLibMap.get(libName);
@@ -331,7 +373,7 @@ public class TempJarCache {
return null;
} */
- public static final String findResource(String name) {
+ public synchronized static final String findResource(String name) {
checkInitialized();
final File f = new File(tmpFileCache.getTempDir(), name);
if(f.exists()) {
@@ -340,7 +382,7 @@ public class TempJarCache {
return null;
}
- public static final URL getResource(String name) throws MalformedURLException {
+ public synchronized static final URL getResource(String name) throws MalformedURLException {
checkInitialized();
final File f = new File(tmpFileCache.getTempDir(), name);
if(f.exists()) {
@@ -360,13 +402,20 @@ public class TempJarCache {
* @throws IOException
* @throws SecurityException
*/
- public static final void bootstrapNativeLib(Class<?> certClass, String libBaseName, URL jarURL, ClassLoader cl)
+ public synchronized static final void bootstrapNativeLib(Class<?> certClass, String libBaseName, URL jarURL)
throws IOException, SecurityException {
checkInitialized();
- if(!nativeLibJars.contains(jarURL) && !nativeLibMap.containsKey(libBaseName) ) {
- final JarFile jarFile = JarUtil.getJarFile(jarURL, cl);
+ boolean ok = false;
+ int countEntries = 0;
+ final LoadState nativeLibJarsLS = nativeLibJars.get(jarURL);
+ if( !testLoadState(nativeLibJarsLS, LoadState.LOOKED_UP) && !nativeLibMap.containsKey(libBaseName) ) {
if(DEBUG) {
- System.err.println("TempJarCache: bootstrapNativeLib: "+jarURL+": nativeJar "+jarFile.getName()+" - libBaseName: "+libBaseName);
+ System.err.println("TempJarCache: bootstrapNativeLib(certClass: "+certClass+", libBaseName "+libBaseName+", jarURL "+jarURL+")");
+ }
+ nativeLibJars.put(jarURL, LoadState.LOOKED_UP);
+ final JarFile jarFile = JarUtil.getJarFile(jarURL);
+ if(DEBUG) {
+ System.err.println("TempJarCache: bootstrapNativeLib: nativeJar "+jarFile.getName());
}
validateCertificates(certClass, jarFile);
final Enumeration<JarEntry> entries = jarFile.entries();
@@ -385,18 +434,27 @@ public class TempJarCache {
try {
final byte[] buf = new byte[ 2048 ];
while (true) {
- int count;
- if ((count = in.read(buf)) == -1) { break; }
- out.write(buf, 0, count);
- numBytes += count;
+ int countBytes;
+ if ((countBytes = in.read(buf)) == -1) { break; }
+ out.write(buf, 0, countBytes);
+ numBytes += countBytes;
}
} finally { in.close(); out.close(); }
if (numBytes>0) {
nativeLibMap.put(libBaseName, destFile.getAbsolutePath());
- nativeLibJars.add(jarURL);
+ nativeLibJars.put(jarURL, LoadState.LOADED);
+ ok = true;
+ countEntries++;
}
}
}
+ } else if( testLoadState(nativeLibJarsLS, LoadState.LOADED) ) {
+ ok = true; // already loaded
+ } else {
+ throw new IOException("TempJarCache: bootstrapNativeLib: "+jarURL+", previous load attempt failed");
+ }
+ if(DEBUG) {
+ System.err.println("TempJarCache: bootstrapNativeLib() done, count "+countEntries+", ok "+ok);
}
}