diff options
author | Sven Gothel <[email protected]> | 2011-11-29 04:59:42 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2011-11-29 04:59:42 +0100 |
commit | 04391a3f417e10e1b6dafbd8becc63659af633c3 (patch) | |
tree | 2b9a5f8dc81b7631d34d306894387d3bac4b9bec | |
parent | 60ea6727f1a089f6afd17fcea3bd7d29353af9b4 (diff) |
JarUtil: Improve Robustness (Bug 522) and API doc, prepare for Jar-In-Jar. Add unit test.
Misc.:
- IOUtil: Add toURL* methods
- TempJarCache: Add 'URL getResource(String)'
-rw-r--r-- | src/java/com/jogamp/common/jvm/JNILibLoaderBase.java | 6 | ||||
-rw-r--r-- | src/java/com/jogamp/common/os/Platform.java | 6 | ||||
-rw-r--r-- | src/java/com/jogamp/common/util/IOUtil.java | 35 | ||||
-rw-r--r-- | src/java/com/jogamp/common/util/JarUtil.java | 217 | ||||
-rw-r--r-- | src/java/com/jogamp/common/util/cache/TempJarCache.java | 13 | ||||
-rw-r--r-- | src/junit/com/jogamp/common/util/TestJarUtil.java | 169 | ||||
-rw-r--r-- | src/junit/com/jogamp/common/util/TestTempJarCache.java | 10 |
7 files changed, 402 insertions, 54 deletions
diff --git a/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java b/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java index 3164b82..31e777a 100644 --- a/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java +++ b/src/java/com/jogamp/common/jvm/JNILibLoaderBase.java @@ -151,11 +151,11 @@ public class JNILibLoaderBase { final String nativeJarName = nativeJarBaseName+"-natives-"+Platform.getOSAndArch()+".jar"; final ClassLoader cl = classFromJavaJar.getClassLoader(); try { - URL jarUrlRoot = JarUtil.getJarURLDirname( JarUtil.getJarURL( classFromJavaJar.getName(), cl ) ); + URL jarUrlRoot = JarUtil.getURLDirname( JarUtil.getJarSubURL( classFromJavaJar.getName(), cl ) ); if(DEBUG) { System.err.println("JNILibLoaderBase: addNativeJarLibs: "+nativeJarBaseName+": url-root "+jarUrlRoot); } - URL nativeJarURL = JarUtil.getJarURL(jarUrlRoot, nativeJarName); + URL nativeJarURL = JarUtil.getJarFileURL(jarUrlRoot, nativeJarName); if(DEBUG) { System.err.println("JNILibLoaderBase: addNativeJarLibs: "+nativeJarBaseName+": nativeJarURL "+nativeJarURL); } @@ -181,7 +181,7 @@ public class JNILibLoaderBase { if(TempJarCache.isInitialized()) { final ClassLoader cl = classFromJavaJar.getClassLoader(); try { - final String jarName = JarUtil.getJarName(classFromJavaJar.getName(), cl); + final String jarName = JarUtil.getJarBasename(classFromJavaJar.getName(), cl); if(jarName!=null) { if( null != allJavaJarPrefix && jarName.startsWith(allJavaJarPrefix) ) { // all-in-one variant diff --git a/src/java/com/jogamp/common/os/Platform.java b/src/java/com/jogamp/common/os/Platform.java index 2c1a18e..ca1a8db 100644 --- a/src/java/com/jogamp/common/os/Platform.java +++ b/src/java/com/jogamp/common/os/Platform.java @@ -306,9 +306,9 @@ public class Platform { final String nativeJarName = "gluegen-rt-natives-"+os_and_arch+".jar"; final ClassLoader cl = Platform.class.getClassLoader(); try { - final URL jarUrlRoot = JarUtil.getJarURLDirname( - JarUtil.getJarURL(Platform.class.getName(), cl) ); - final URL nativeJarURL = JarUtil.getJarURL(jarUrlRoot, nativeJarName); + final URL jarUrlRoot = JarUtil.getURLDirname( + JarUtil.getJarSubURL(Platform.class.getName(), cl) ); + final URL nativeJarURL = JarUtil.getJarFileURL(jarUrlRoot, nativeJarName); final JarFile nativeJar = JarUtil.getJarFile(nativeJarURL, cl); TempJarCache.bootstrapNativeLib(Platform.class, libBaseName, nativeJar); } catch (IOException ioe) { diff --git a/src/java/com/jogamp/common/util/IOUtil.java b/src/java/com/jogamp/common/util/IOUtil.java index f9a34f0..7583172 100644 --- a/src/java/com/jogamp/common/util/IOUtil.java +++ b/src/java/com/jogamp/common/util/IOUtil.java @@ -37,6 +37,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.security.AccessController; import java.net.JarURLConnection; +import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.nio.ByteBuffer; @@ -184,6 +185,31 @@ public class IOUtil { * */ + public static String slashify(String path, boolean startWithSlash, boolean endWithSlash) { + String p = path.replace('\\', '/'); // unify file seperator + if (startWithSlash && !p.startsWith("/")) { + p = "/" + p; + } + if (endWithSlash && !p.endsWith("/")) { + p = p + "/"; + } + return p; + } + + /** Using the proper advertised conversion via File -> URI -> URL */ + public static URL toURL(File file) throws MalformedURLException { + return file.toURI().toURL(); + } + + /** Using the simple conversion via File -> URL, assuming proper characters. */ + public static URL toURLSimple(File file) throws MalformedURLException { + return new URL("file", "", slashify(file.getAbsolutePath(), true, file.isDirectory())); + } + + public static URL toURLSimple(String protocol, String file, boolean isDirectory) throws MalformedURLException { + return new URL(protocol, "", slashify(file, true, isDirectory)); + } + /** * Returns the lowercase suffix of the given file name (the text * after the last '.' in the file name). Returns null if the file @@ -236,7 +262,7 @@ public class IOUtil { * Returns the basename of the given fname w/o directory part */ public static String getBasename(String fname) { - fname = fname.replace('\\', '/'); // unify file seperator + fname = slashify(fname, false, false); int lios = fname.lastIndexOf('/'); // strip off dirname if(lios>=0) { fname = fname.substring(lios+1); @@ -248,7 +274,7 @@ public class IOUtil { * Returns unified '/' dirname including the last '/' */ public static String getDirname(String fname) { - fname = fname.replace('\\', '/'); // unify file seperator + fname = slashify(fname, false, false); int lios = fname.lastIndexOf('/'); // strip off dirname if(lios>=0) { fname = fname.substring(0, lios+1); @@ -318,7 +344,6 @@ public class IOUtil { * @see URL#URL(String) * @see File#File(String) */ - @SuppressWarnings("deprecation") public static URL getResource(String resourcePath, ClassLoader cl) { if(null == resourcePath) { return null; @@ -356,7 +381,7 @@ public class IOUtil { try { File file = new File(resourcePath); if(file.exists()) { - url = file.toURL(); + url = toURLSimple(file); } } catch (Throwable e) { if(DEBUG) { @@ -389,7 +414,7 @@ public class IOUtil { if (baseLocation != null) { final File file = new File(baseLocation, relativeFile); // Handle things on Windows - return file.getPath().replace('\\', '/'); + return slashify(file.getPath(), false, true); } return null; } diff --git a/src/java/com/jogamp/common/util/JarUtil.java b/src/java/com/jogamp/common/util/JarUtil.java index 67cb0ad..517ac1a 100644 --- a/src/java/com/jogamp/common/util/JarUtil.java +++ b/src/java/com/jogamp/common/util/JarUtil.java @@ -52,108 +52,249 @@ public class JarUtil { private static final boolean DEBUG = Debug.debug("JarUtil"); /** - * @param clazzBinName com.jogamp.common.util.cache.TempJarCache + * The Class's <code>"com.jogamp.common.GlueGenVersion"</code> + * URL <code>jar:<i>sub_protocol</i>:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class"</code> + * Jar basename <code>gluegen-rt.jar</code> will be returned. + * <p> + * <i>sub_protocol</i> may be "file", "http", etc.. + * </p> + * + * @param clazzBinName "com.jogamp.common.GlueGenVersion" * @param cl - * @return gluegen-rt.jar + * @return "gluegen-rt.jar" + * @throws IllegalArgumentException if the URL doesn't match the expected formatting * @throws IOException * @see {@link IOUtil#getClassURL(String, ClassLoader)} */ - public static String getJarName(String clazzBinName, ClassLoader cl) throws IOException { + public static String getJarBasename(String clazzBinName, ClassLoader cl) throws IllegalArgumentException, IOException { URL url = IOUtil.getClassURL(clazzBinName, cl); if(null != url) { String urlS = url.toExternalForm(); + if(DEBUG) { + System.out.println("getJarName "+url+", extForm: "+urlS); + } + if(!urlS.startsWith("jar:")) { + throw new IllegalArgumentException("JAR URL doesn't start with 'jar:', got <"+urlS+">"); + } + urlS = urlS.substring(4, urlS.length()); // exclude 'jar:' + + // from + // file:/some/path/gluegen-rt.jar!/com/jogamp/common/util/cache/TempJarCache.class + // to + // file:/some/path/gluegen-rt.jar + int idx = urlS.lastIndexOf('!'); + if (0 <= idx) { + urlS = urlS.substring(0, idx); // exclude '!/' + } else { + throw new IllegalArgumentException("JAR URL does not contain jar url terminator '!', in <"+url.toExternalForm()+">, got <"+urlS+">"); + } + // from - // jar:file:/usr/local/projects/JOGL/gluegen/build-x86_64/gluegen-rt.jar!/com/jogamp/common/util/cache/TempJarCache.class + // file:/some/path/gluegen-rt.jar // to // gluegen-rt.jar - urlS = urlS.substring(0, urlS.lastIndexOf('!')); // exclude !/ - return urlS.substring(urlS.lastIndexOf('/')+1); // just the jar name + idx = urlS.lastIndexOf('/'); + if(0 > idx) { + // no abs-path, check for protocol terminator ':' + idx = urlS.lastIndexOf(':'); + if(0 > idx) { + throw new IllegalArgumentException("JAR URL does not contain protocol terminator ':', in <"+url.toExternalForm()+">, got <"+urlS+">"); + } + } + urlS = urlS.substring(idx+1); // just the jar name + + if(0 >= urlS.lastIndexOf(".jar")) { + throw new IllegalArgumentException("No Jar name in <"+url.toExternalForm()+">, got <"+urlS+">"); + } + if(DEBUG) { + System.out.println("getJarName res: "+urlS); + } + return urlS; } return null; } /** - * @param clazzBinName com.jogamp.common.util.cache.TempJarCache + * The Class's <code>"com.jogamp.common.GlueGenVersion"</code> + * URL <code>jar:<i>sub_protocol</i>:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class"</code> + * Jar file's sub URL <code><i>sub_protocol</i>:/some/path/gluegen-rt.jar</code> will be returned. + * <p> + * <i>sub_protocol</i> may be "file", "http", etc.. + * </p> + * + * @param clazzBinName "com.jogamp.common.GlueGenVersion" * @param cl - * @return jar:file:/usr/local/projects/JOGL/gluegen/build-x86_64/gluegen-rt.jar!/ + * @return "<i>sub_protocol</i>:/some/path/gluegen-rt.jar" + * @throws IllegalArgumentException if the URL doesn't match the expected formatting * @throws IOException * @see {@link IOUtil#getClassURL(String, ClassLoader)} */ - public static URL getJarURL(String clazzBinName, ClassLoader cl) throws IOException { + public static URL getJarSubURL(String clazzBinName, ClassLoader cl) throws IllegalArgumentException, IOException { URL url = IOUtil.getClassURL(clazzBinName, cl); if(null != url) { String urlS = url.toExternalForm(); + if(DEBUG) { + System.out.println("getJarSubURL "+url+", extForm: "+urlS); + } + if(!urlS.startsWith("jar:")) { + throw new IllegalArgumentException("JAR URL doesn't start with 'jar:', got <"+urlS+">"); + } + urlS = urlS.substring(4, urlS.length()); // exclude 'jar:' + // from - // jar:file:/usr/local/projects/JOGL/gluegen/build-x86_64/gluegen-rt.jar!/com/jogamp/common/util/cache/TempJarCache.class + // file:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class // to - // jar:file:/usr/local/projects/JOGL/gluegen/build-x86_64/gluegen-rt.jar!/ - urlS = urlS.substring(0, urlS.lastIndexOf('!')+2); // include !/ + // file:/some/path/gluegen-rt.jar + int idx = urlS.lastIndexOf('!'); + if (0 <= idx) { + urlS = urlS.substring(0, idx); // exclude '!/' + } else { + throw new IllegalArgumentException("JAR URL does not contain jar url terminator '!', url <"+urlS+">"); + } + + if(0 >= urlS.lastIndexOf(".jar")) { + throw new IllegalArgumentException("No Jar name in <"+url.toExternalForm()+">, got <"+urlS+">"); + } + if(DEBUG) { + System.out.println("getJarSubURL res: "+urlS); + } return new URL(urlS); } return null; } /** - * - * @param jarURL jar:file:/usr/local/projects/JOGL/gluegen/build-x86_64/gluegen-rt.jar!/com/jogamp/common/util/cache/TempJarCache.class - * @return file:/usr/local/projects/JOGL/gluegen/build-x86_64/ + * The Class's <code>"com.jogamp.common.GlueGenVersion"</code> + * URL <code>jar:<i>sub_protocol</i>:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class"</code> + * Jar file URL <code>jar:<i>sub_protocol</i>:/some/path/gluegen-rt.jar!/</code> will be returned. + * <p> + * <i>sub_protocol</i> may be "file", "http", etc.. + * </p> + * + * @param clazzBinName "com.jogamp.common.GlueGenVersion" + * @param cl + * @return "jar:<i>sub_protocol</i>:/some/path/gluegen-rt.jar!/" + * @throws IllegalArgumentException if the URL doesn't match the expected formatting * @throws IOException + * @see {@link IOUtil#getClassURL(String, ClassLoader)} */ - public static URL getJarURLDirname(URL jarURL) throws IOException { - String urlS = jarURL.toExternalForm(); - // from - // jar:file:/usr/local/projects/JOGL/gluegen/build-x86_64/gluegen-rt.jar!/com/jogamp/common/util/cache/TempJarCache.class - // to - // jar:file:/usr/local/projects/JOGL/gluegen/build-x86_64/gluegen-rt.jar - urlS = urlS.substring(0, urlS.lastIndexOf('!')); // exclude !/ - + public static URL getJarFileURL(String clazzBinName, ClassLoader cl) throws IllegalArgumentException, IOException { + URL url = getJarSubURL(clazzBinName, cl); + if(null != url) { + url = new URL("jar:"+url.toExternalForm()+"!/"); + if(DEBUG) { + System.out.println("getJarFileURL res: "+url); + } + return url; + } + return null; + } + + /** + * The URL's <code><i>protocol</i>:/some/path/gluegen-rt.jar</code> + * parent dirname URL <code><i>protocol</i>:/some/path/</code> will be returned. + * <p> + * <i>protocol</i> may be "file", "http", etc.. + * </p> + * + * @param aURL "<i>protocol</i>:/some/path/gluegen-rt.jar" + * @return "<i>protocol</i>:/some/path/" + * @throws IllegalArgumentException if the URL doesn't match the expected formatting + * @throws IOException + */ + public static URL getURLDirname(URL aURL) throws IllegalArgumentException, IOException { + String urlS = aURL.toExternalForm(); + if(DEBUG) { + System.out.println("getURLDirname "+aURL+", extForm: "+urlS); + } // from - // jar:file:/usr/local/projects/JOGL/gluegen/build-x86_64/gluegen-rt.jar + // file:/some/path/gluegen-rt.jar // to - // file:/usr/local/projects/JOGL/gluegen/build-x86_64/ - urlS = urlS.substring(4, urlS.lastIndexOf('/')+1); // include / exclude jar: + // file:/some/path/ + int idx = urlS.lastIndexOf('/'); + if (0 <= idx) { + urlS = urlS.substring(0, idx+1); // exclude jar name, include terminal '/' + } + if(DEBUG) { + System.out.println("getJarURLDirname res: "+urlS); + } return new URL(urlS); } /** - * - * @param baseUrl file:/usr/local/projects/JOGL/gluegen/build-x86_64/ + * @param baseUrl file:/some/path/ * @param jarFileName gluegen-rt.jar - * @return jar:file:/usr/local/projects/JOGL/gluegen/build-x86_64/gluegen-rt.jar!/ + * @return jar:file:/some/path/gluegen-rt.jar!/ * @throws IOException */ - public static URL getJarURL(URL baseUrl, String jarFileName) throws IOException { + public static URL getJarFileURL(URL baseUrl, String jarFileName) throws IOException { + if(null == jarFileName) { + throw new IllegalArgumentException("jarFileName is null"); + } return new URL("jar:"+baseUrl.toExternalForm()+jarFileName+"!/"); } /** + * @param jarSubUrl file:/some/path/gluegen-rt.jar + * @return jar:file:/some/path/gluegen-rt.jar!/ + * @throws IOException + */ + public static URL getJarFileURL(URL jarSubUrl) throws IOException { + if(null == jarSubUrl) { + throw new IllegalArgumentException("jarSubUrl is null"); + } + return new URL("jar:"+jarSubUrl.toExternalForm()+"!/"); + } + + /** + * @param jarFileURL jar:file:/some/path/gluegen-rt.jar!/ + * @param jarEntry com/jogamp/common/GlueGenVersion.class + * @return jar:file:/some/path/gluegen-rt.jar!/com/jogamp/common/GlueGenVersion.class + * @throws IOException + */ + public static URL getJarEntryURL(URL jarFileURL, String jarEntry) throws IOException { + if(null == jarEntry) { + throw new IllegalArgumentException("jarEntry is null"); + } + return new URL(jarFileURL.toExternalForm()+jarEntry); + } + + /** * * @param clazzBinName com.jogamp.common.util.cache.TempJarCache * @param cl domain * @return JarFile containing the named class within the given ClassLoader * @throws IOException - * @see {@link #getJarURL(String, ClassLoader)} + * @see {@link #getJarFileURL(String, ClassLoader)} */ public static JarFile getJarFile(String clazzBinName, ClassLoader cl) throws IOException { - return getJarFile(getJarURL(clazzBinName, cl), cl); + return getJarFile(getJarFileURL(clazzBinName, cl), cl); } /** - * - * @param jarURL jar:file:/usr/local/projects/JOGL/gluegen/build-x86_64/gluegen-rt.jar!/ + * @param jarFileURL jar:file:/some/path/gluegen-rt.jar!/ * @param cl domain * @return JarFile as named by URL within the given ClassLoader * @throws IOException */ - public static JarFile getJarFile(URL jarUrl, ClassLoader cl) throws IOException { - if(null != jarUrl) { - URLConnection urlc = jarUrl.openConnection(); + public static JarFile getJarFile(URL jarFileUrl, ClassLoader cl) throws IOException { + if(DEBUG) { + System.out.println("getJarFile: "+jarFileUrl); + } + if(null != jarFileUrl) { + URLConnection urlc = jarFileUrl.openConnection(); if(urlc instanceof JarURLConnection) { - JarURLConnection jarConnection = (JarURLConnection)jarUrl.openConnection(); + JarURLConnection jarConnection = (JarURLConnection)jarFileUrl.openConnection(); JarFile jarFile = jarConnection.getJarFile(); + if(DEBUG) { + System.out.println("getJarFile res: "+jarFile.getName()); + } return jarFile; } } + if(DEBUG) { + System.out.println("getJarFile res: NULL"); + } return null; } diff --git a/src/java/com/jogamp/common/util/cache/TempJarCache.java b/src/java/com/jogamp/common/util/cache/TempJarCache.java index 7e90f7d..71a12e7 100644 --- a/src/java/com/jogamp/common/util/cache/TempJarCache.java +++ b/src/java/com/jogamp/common/util/cache/TempJarCache.java @@ -34,6 +34,8 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.net.MalformedURLException; +import java.net.URL; import java.security.cert.Certificate; import java.util.Enumeration; import java.util.HashMap; @@ -44,6 +46,7 @@ import java.util.jar.JarEntry; import java.util.jar.JarFile; import com.jogamp.common.os.NativeLibrary; +import com.jogamp.common.util.IOUtil; import com.jogamp.common.util.JarUtil; public class TempJarCache { @@ -266,6 +269,16 @@ public class TempJarCache { return null; } + public static final URL getResource(String name) throws MalformedURLException { + checkInitialized(); + final File f = new File(tmpFileCache.getTempDir(), name); + if(f.exists()) { + return IOUtil.toURLSimple(f); + } + return null; + } + + /** * Bootstrapping version extracting the JAR files root entry containing libBaseName, * assuming it's a native library. This is used to get the 'gluegen-rt' diff --git a/src/junit/com/jogamp/common/util/TestJarUtil.java b/src/junit/com/jogamp/common/util/TestJarUtil.java new file mode 100644 index 0000000..fd3b93e --- /dev/null +++ b/src/junit/com/jogamp/common/util/TestJarUtil.java @@ -0,0 +1,169 @@ +/** + * Copyright 2011 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.common.util; + +import java.io.IOException; +import java.net.URL; +import java.net.URLClassLoader; +import java.net.URLConnection; +import java.net.JarURLConnection; +import java.util.Enumeration; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import junit.framework.Assert; + +import org.junit.BeforeClass; +import org.junit.Test; + +import com.jogamp.common.GlueGenVersion; +import com.jogamp.common.util.cache.TempCacheReg; +import com.jogamp.common.util.cache.TempFileCache; +import com.jogamp.common.util.cache.TempJarCache; + +public class TestJarUtil { + static TempFileCache fileCache; + + @BeforeClass + public static void init() { + // may already been initialized by other test + // Assert.assertFalse(TempCacheReg.isTempFileCacheUsed()); + Assert.assertTrue(TempFileCache.initSingleton()); + Assert.assertTrue(TempCacheReg.isTempFileCacheUsed()); + + fileCache = new TempFileCache(); + Assert.assertTrue(fileCache.isValid()); + System.err.println("tmp dir: "+fileCache.getTempDir()); + } + + static class TestClassLoader extends URLClassLoader { + public TestClassLoader(URL[] urls) { + super(urls); + } + public TestClassLoader(URL[] urls, ClassLoader parent) { + super(urls, parent); + } + } + + void validateJarFile(JarFile jarFile) throws IllegalArgumentException, IOException { + Assert.assertNotNull(jarFile); + Assert.assertTrue("jarFile has zero entries: "+jarFile, jarFile.size()>0); + Enumeration<JarEntry> entries = jarFile.entries(); + System.err.println("Entries of "+jarFile.getName()+": "); + int i = 0; + while(entries.hasMoreElements()) { + System.err.println(i+": "+entries.nextElement().getName()); + i++; + } + } + + void validateJarFileURL(URL jarFileURL) throws IllegalArgumentException, IOException { + Assert.assertNotNull(jarFileURL); + URLConnection aURLc = jarFileURL.openConnection(); + Assert.assertTrue("jarFileURL has zero content: "+jarFileURL, aURLc.getContentLength()>0); + System.err.println("URLConnection: "+aURLc); + Assert.assertTrue("Not a JarURLConnection: "+aURLc, (aURLc instanceof JarURLConnection) ); + JarURLConnection jURLc = (JarURLConnection) aURLc; + JarFile jarFile = jURLc.getJarFile(); + validateJarFile(jarFile); + } + + void validateJarUtil(String expJarName, String clazzBinName, ClassLoader cl) throws IllegalArgumentException, IOException { + String jarName= JarUtil.getJarBasename(clazzBinName, cl); + Assert.assertNotNull(jarName); + Assert.assertEquals(expJarName, jarName); + + URL jarSubURL = JarUtil.getJarSubURL(clazzBinName, cl); + Assert.assertNotNull(jarSubURL); + URLConnection urlConn = jarSubURL.openConnection(); + Assert.assertTrue("jarSubURL has zero content: "+jarSubURL, urlConn.getContentLength()>0); + System.err.println("URLConnection of jarSubURL: "+urlConn); + + URL jarFileURL = JarUtil.getJarFileURL(clazzBinName, cl); + validateJarFileURL(jarFileURL); + + JarFile jarFile = JarUtil.getJarFile(clazzBinName, cl); + validateJarFile(jarFile); + } + + @Test + public void testJarUtilFlat01() throws IOException { + System.err.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXX"); + validateJarUtil("TestJarsInJar.jar", "ClassInJar0", this.getClass().getClassLoader()); + System.err.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXX"); + } + + @Test + public void testJarUtilJarInJar01() throws IOException, ClassNotFoundException { + System.err.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXX"); + + Assert.assertTrue(TempJarCache.initSingleton()); + Assert.assertTrue(TempCacheReg.isTempJarCacheUsed()); + Assert.assertTrue(TempJarCache.isInitialized()); + + final ClassLoader rootCL = this.getClass().getClassLoader(); + + // Get containing JAR file "TestJarsInJar.jar" and add it to the TempJarCache + TempJarCache.addAll(GlueGenVersion.class, JarUtil.getJarFile("ClassInJar0", rootCL)); + + // Fetch and load the contained "ClassInJar1.jar" + final URL ClassInJar1_jarFileURL = JarUtil.getJarFileURL(TempJarCache.getResource("ClassInJar1.jar")); + final ClassLoader cl = new URLClassLoader(new URL[] { ClassInJar1_jarFileURL }, rootCL); + Assert.assertNotNull(cl); + validateJarUtil("ClassInJar1.jar", "ClassInJar1", cl); + System.err.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXX"); + } + + @Test + public void testJarUtilJarInJar02() throws IOException, ClassNotFoundException { + System.err.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXX"); + + Assert.assertTrue(TempJarCache.initSingleton()); + Assert.assertTrue(TempCacheReg.isTempJarCacheUsed()); + Assert.assertTrue(TempJarCache.isInitialized()); + + final ClassLoader rootCL = this.getClass().getClassLoader(); + + // Get containing JAR file "TestJarsInJar.jar" and add it to the TempJarCache + TempJarCache.addAll(GlueGenVersion.class, JarUtil.getJarFile("ClassInJar0", rootCL)); + + // Fetch and load the contained "ClassInJar1.jar" + final URL ClassInJar2_jarFileURL = JarUtil.getJarFileURL(TempJarCache.getResource("sub/ClassInJar2.jar")); + final ClassLoader cl = new URLClassLoader(new URL[] { ClassInJar2_jarFileURL }, rootCL); + Assert.assertNotNull(cl); + validateJarUtil("ClassInJar2.jar", "ClassInJar2", cl); + System.err.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXX"); + } + + public static void main(String args[]) throws IOException { + String tstname = TestJarUtil.class.getName(); + org.junit.runner.JUnitCore.main(tstname); + } + +} diff --git a/src/junit/com/jogamp/common/util/TestTempJarCache.java b/src/junit/com/jogamp/common/util/TestTempJarCache.java index e1e47af..199d0aa 100644 --- a/src/junit/com/jogamp/common/util/TestTempJarCache.java +++ b/src/junit/com/jogamp/common/util/TestTempJarCache.java @@ -137,7 +137,7 @@ public class TestTempJarCache { @Test public void testJarUtil01a() throws IOException { JarFile jarFile = JarUtil.getJarFile(GlueGenVersion.class.getName(), this.getClass().getClassLoader()); - Assert.assertNotNull("jarFile: "+jarFile); + Assert.assertNotNull(jarFile); JarUtil.extract(fileCache.getTempDir(), null, jarFile, false, true, true); File f = new File(fileCache.getTempDir(), "META-INF/MANIFEST.MF"); Assert.assertTrue(f.exists()); @@ -185,10 +185,10 @@ public class TestTempJarCache { final String libBaseName = "gluegen-rt"; final ClassLoader cl = getClass().getClassLoader(); - URL jarUrlRoot = JarUtil.getJarURL(TempJarCache.class.getName(), cl); - jarUrlRoot = JarUtil.getJarURLDirname(jarUrlRoot); + URL jarUrlRoot = JarUtil.getJarSubURL(TempJarCache.class.getName(), cl); + jarUrlRoot = JarUtil.getURLDirname(jarUrlRoot); - URL nativeJarURL = JarUtil.getJarURL(jarUrlRoot, nativeJarName); + URL nativeJarURL = JarUtil.getJarFileURL(jarUrlRoot, nativeJarName); JarFile nativeJar = JarUtil.getJarFile(nativeJarURL, cl); TempJarCache.addNativeLibs(TempJarCache.class, nativeJar); @@ -225,7 +225,7 @@ public class TestTempJarCache { @Test public void testTempJarCache04bDiffClassLoader() throws IOException { - URL[] urls = new URL[] { JarUtil.getJarURL(TempJarCache.class.getName(), getClass().getClassLoader()) }; + URL[] urls = new URL[] { JarUtil.getJarFileURL(TempJarCache.class.getName(), getClass().getClassLoader()) }; System.err.println("url: "+urls[0]); ClassLoader cl2 = new TestClassLoader(urls, null); ClassLoader cl3 = new TestClassLoader(urls, null); |