GlueGen v2.6.0-rc-20250712
GlueGen, Native Binding Generator for Java™ (public API).
TestJarUtil.java
Go to the documentation of this file.
1/**
2 * Copyright 2011 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28
29package com.jogamp.common.util;
30
31import java.io.IOException;
32import java.net.MalformedURLException;
33import java.net.URISyntaxException;
34import java.net.URL;
35import java.net.URLClassLoader;
36import java.net.URLConnection;
37import java.net.JarURLConnection;
38import java.net.URLStreamHandler;
39import java.util.Enumeration;
40import java.util.jar.JarEntry;
41import java.util.jar.JarFile;
42
43import org.junit.Assert;
44import org.junit.BeforeClass;
45import org.junit.Test;
46
47import com.jogamp.common.GlueGenVersion;
48import com.jogamp.common.net.URIDumpUtil;
49import com.jogamp.common.net.Uri;
50import com.jogamp.common.os.AndroidVersion;
51import com.jogamp.common.util.cache.TempCacheReg;
52import com.jogamp.common.util.cache.TempFileCache;
53import com.jogamp.common.util.cache.TempJarCache;
54import com.jogamp.junit.util.SingletonJunitCase;
55
56import org.junit.FixMethodOrder;
57import org.junit.runners.MethodSorters;
58
59@FixMethodOrder(MethodSorters.NAME_ASCENDING)
60public class TestJarUtil extends SingletonJunitCase {
61 static TempFileCache fileCache;
62
63 @BeforeClass
64 public static void init() {
66 // ClassLoader -> JarURL doesn't work w/ Dalvik
67 setTestSupported(false);
68 // we allow basic TempFileCache initialization (test) ..
69 }
70 // may already been initialized by other test
71 // Assert.assertFalse(TempCacheReg.isTempFileCacheUsed());
72 Assert.assertTrue(TempFileCache.initSingleton());
73 Assert.assertTrue(TempCacheReg.isTempFileCacheUsed());
74
75 fileCache = new TempFileCache();
76 Assert.assertTrue(fileCache.isValid(false));
77 System.err.println("tmp dir: "+fileCache.getTempDir());
78 }
79
80 static class TestClassLoader extends URLClassLoader {
81 public TestClassLoader(final URL[] urls) {
82 super(urls);
83 }
84 public TestClassLoader(final URL[] urls, final ClassLoader parent) {
85 super(urls, parent);
86 }
87 }
88
89 void validateJarFile(final JarFile jarFile) throws IllegalArgumentException, IOException {
90 Assert.assertNotNull(jarFile);
91 Assert.assertTrue("jarFile has zero entries: "+jarFile, jarFile.size()>0);
92 final Enumeration<JarEntry> entries = jarFile.entries();
93 System.err.println("Entries of "+jarFile.getName()+": ");
94 int i = 0;
95 while(entries.hasMoreElements()) {
96 System.err.println(i+": "+entries.nextElement().getName());
97 i++;
98 }
99 }
100
101 void validateJarFileURL(final Uri jarFileURI) throws IllegalArgumentException, IOException, URISyntaxException {
102 Assert.assertNotNull(jarFileURI);
103 final URL jarFileURL = jarFileURI.toURL();
104 final URLConnection aURLc = jarFileURL.openConnection();
105 Assert.assertTrue("jarFileURI/URL has zero content: "+jarFileURL, aURLc.getContentLength()>0);
106 System.err.println("URLConnection: "+aURLc);
107 Assert.assertTrue("Not a JarURLConnection: "+aURLc, (aURLc instanceof JarURLConnection) );
108 final JarURLConnection jURLc = (JarURLConnection) aURLc;
109 final JarFile jarFile = jURLc.getJarFile();
110 validateJarFile(jarFile);
111 }
112
113 void validateJarUtil(final String expJarName, final String clazzBinName, final ClassLoader cl) throws IllegalArgumentException, IOException, URISyntaxException {
114 final Uri.Encoded expJarNameE = Uri.Encoded.cast(expJarName);
115 final Uri.Encoded jarName= JarUtil.getJarBasename(clazzBinName, cl);
116 Assert.assertNotNull(jarName);
117 Assert.assertEquals(expJarNameE, jarName);
118
119 final Uri jarUri = JarUtil.getJarUri(clazzBinName, cl);
120 Assert.assertNotNull(jarUri);
121 System.err.println("1 - jarUri:");
122 URIDumpUtil.showUri(jarUri);
123
124 final Uri jarSubUri = jarUri.getContainedUri();
125 Assert.assertNotNull(jarSubUri);
126 System.err.println("2 - jarSubUri:");
127 URIDumpUtil.showUri(jarSubUri);
128
129 final URL jarSubURL= jarSubUri.toURL();
130 final URLConnection urlConn = jarSubURL.openConnection();
131 Assert.assertTrue("jarSubURL has zero content: "+jarSubURL, urlConn.getContentLength()>0);
132 System.err.println("URLConnection of jarSubURL: "+urlConn);
133
134 final Uri jarFileURL = JarUtil.getJarFileUri(clazzBinName, cl);
135 validateJarFileURL(jarFileURL);
136
137 final JarFile jarFile = JarUtil.getJarFile(clazzBinName, cl);
138 validateJarFile(jarFile);
139 }
140
141 @Test
142 public void testJarUtilFlat01() throws IOException, IllegalArgumentException, URISyntaxException {
143 System.err.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXX");
144 validateJarUtil("TestJarsInJar.jar", "ClassInJar0", this.getClass().getClassLoader());
145 System.err.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXX");
146 }
147
148 @Test
149 public void testJarUtilJarInJar01() throws IOException, ClassNotFoundException, IllegalArgumentException, URISyntaxException {
150 System.err.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXX");
151
152 Assert.assertTrue(TempJarCache.initSingleton());
153 Assert.assertTrue(TempCacheReg.isTempJarCacheUsed(false));
154 Assert.assertTrue(TempJarCache.isInitialized(false));
155
156 final ClassLoader rootCL = this.getClass().getClassLoader();
157
158 // Get containing JAR file "TestJarsInJar.jar" and add it to the TempJarCache
159 TempJarCache.addAll(GlueGenVersion.class, JarUtil.getJarFileUri("ClassInJar0", rootCL));
160
161 // Fetch and load the contained "ClassInJar1.jar"
162 final URL ClassInJar1_jarFileURL = JarUtil.getJarFileUri(TempJarCache.getResourceUri("ClassInJar1.jar")).toURL();
163 final ClassLoader cl = new URLClassLoader(new URL[] { ClassInJar1_jarFileURL }, rootCL);
164 Assert.assertNotNull(cl);
165 validateJarUtil("ClassInJar1.jar", "ClassInJar1", cl);
166 System.err.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXX");
167 }
168
169 @Test
170 public void testJarUtilJarInJar02() throws IOException, ClassNotFoundException, IllegalArgumentException, URISyntaxException {
171 System.err.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXX");
172
173 Assert.assertTrue(TempJarCache.initSingleton());
174 Assert.assertTrue(TempCacheReg.isTempJarCacheUsed(false));
175 Assert.assertTrue(TempJarCache.isInitialized(false));
176
177 final ClassLoader rootCL = this.getClass().getClassLoader();
178
179 // Get containing JAR file "TestJarsInJar.jar" and add it to the TempJarCache
180 TempJarCache.addAll(GlueGenVersion.class, JarUtil.getJarFileUri("ClassInJar0", rootCL));
181
182 // Fetch and load the contained "ClassInJar1.jar"
183 final URL ClassInJar2_jarFileURL = JarUtil.getJarFileUri(TempJarCache.getResourceUri("sub/ClassInJar2.jar")).toURL();
184 final ClassLoader cl = new URLClassLoader(new URL[] { ClassInJar2_jarFileURL }, rootCL);
185 Assert.assertNotNull(cl);
186 validateJarUtil("ClassInJar2.jar", "ClassInJar2", cl);
187 System.err.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXX");
188 }
189
190 /**
191 * Tests JarUtil's ability to resolve non-JAR URLs with a custom resolver. Meant to be used
192 * in cases like an OSGi plugin, where all classes are loaded with custom classloaders and
193 * therefore return URLs that don't start with "jar:". Adapted from test 02 above.
194 * @throws URISyntaxException
195 * @throws IllegalArgumentException
196 */
197 @Test
198 public void testJarUtilJarInJar03() throws IOException, ClassNotFoundException, IllegalArgumentException, URISyntaxException {
199 System.err.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXX");
200
201 Assert.assertTrue(TempJarCache.initSingleton());
202 Assert.assertTrue(TempCacheReg.isTempJarCacheUsed(false));
203 Assert.assertTrue(TempJarCache.isInitialized(false));
204
205 /** This classloader mimics what OSGi's does -- it takes jar: URLs and makes them into bundleresource: URLs
206 * where the JAR is not directly accessible anymore. Here I leave the JAR name at the end of the URL so I can
207 * retrieve it later in the resolver, but OSGi obscures it completely and returns URLs like
208 * "bundleresource:4.fwk1990213994:1/Something.class" where the JAR name not present. */
209 class CustomClassLoader extends ClassLoader {
210 CustomClassLoader() {
211 super(TestJarUtil.this.getClass().getClassLoader());
212 }
213
214 /** Override normal method to return un-resolvable URL. */
215 public URL getResource(final String name) {
216 final URL url = super.getResource(name);
217 if(url == null)
218 return(null);
219 URL urlReturn = null;
220 try {
221 // numbers to mimic OSGi -- can be anything
222 urlReturn = new URL("bundleresource", "4.fwk1990213994", 1, url.getFile(),
223 new URLStreamHandler() {
224 @Override
225 protected URLConnection openConnection(final URL u) throws IOException {
226 return null;
227 }
228 });
229 } catch(final MalformedURLException e) {
230 // shouldn't happen, since I create the URL correctly above
231 Assert.assertTrue(false);
232 }
233 return urlReturn;
234 }
235 };
236
237 /* This resolver converts bundleresource: URLs back into jar: URLs. OSGi does this by consulting
238 * opaque bundle data inside its custom classloader to find the stored JAR path; we do it here
239 * by simply retrieving the JAR name from where we left it at the end of the URL. */
241 public URL resolve( final URL url ) {
242 if( url.getProtocol().equals("bundleresource") ) {
243 try {
244 return new URL( Uri.JAR_SCHEME, "", url.getFile() );
245 } catch(final MalformedURLException e) {
246 return url;
247 }
248 } else {
249 return url;
250 }
251 }
252 } );
253
254 final ClassLoader rootCL = new CustomClassLoader();
255
256 // Get containing JAR file "TestJarsInJar.jar" and add it to the TempJarCache
257 TempJarCache.addAll(GlueGenVersion.class, JarUtil.getJarFileUri("ClassInJar0", rootCL));
258
259 // Fetch and load the contained "ClassInJar1.jar"
260 final URL ClassInJar2_jarFileURL = JarUtil.getJarFileUri(TempJarCache.getResourceUri("sub/ClassInJar2.jar")).toURL();
261 final ClassLoader cl = new URLClassLoader(new URL[] { ClassInJar2_jarFileURL }, rootCL);
262 Assert.assertNotNull(cl);
263 validateJarUtil("ClassInJar2.jar", "ClassInJar2", cl);
264 System.err.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXX");
265 }
266
267 public static void main(final String args[]) throws IOException {
268 final String tstname = TestJarUtil.class.getName();
269 org.junit.runner.JUnitCore.main(tstname);
270 }
271
272}
This class implements an immutable Uri as defined by RFC 2396.
Definition: Uri.java:160
final java.net.URL toURL()
Returns a new URL instance using the encoded input string, new URL(uri.input), i.e.
Definition: Uri.java:1369
static final String JAR_SCHEME
{@value}
Definition: Uri.java:289
static Uri getJarFileUri(final String clazzBinName, final ClassLoader cl)
The Class's "com.jogamp.common.GlueGenVersion" Uri jar:sub_protocol:/some/path/gluegen-rt....
Definition: JarUtil.java:303
static void setResolver(final Resolver r)
Setting a custom Resolver instance.
Definition: JarUtil.java:86
static void main(final String args[])
void testJarUtilJarInJar03()
Tests JarUtil's ability to resolve non-JAR URLs with a custom resolver.
static boolean isTempJarCacheUsed(final boolean forExecutables)
File getTempDir()
Temporary directory for individual files (eg.
boolean isValid(final boolean forExecutables)
static boolean initSingleton()
Documented way to kick off static initialization.
Static Jar file cache handler using an underlying instance of TempFileCache, see getTempFileCache().
static synchronized final void addAll(final Class<?> certClass, final Uri jarUri)
Adds all types, native libraries, class files and other files (resources) if not yet added.
static boolean isInitialized(final boolean forExecutables)
static boolean initSingleton()
Documented way to kick off static initialization.
static synchronized final Uri getResourceUri(final String name)
Similar to ClassLoader#getResource(String).
Interface allowing users to provide an URL resolver that will convert custom classloader URLs like Ec...
Definition: JarUtil.java:71