17dd252788645e940eada959bdde927426e2531c9Paul Duffin/* 27dd252788645e940eada959bdde927426e2531c9Paul Duffin * Copyright (C) 2012 The Guava Authors 37dd252788645e940eada959bdde927426e2531c9Paul Duffin * 47dd252788645e940eada959bdde927426e2531c9Paul Duffin * Licensed under the Apache License, Version 2.0 (the "License"); 57dd252788645e940eada959bdde927426e2531c9Paul Duffin * you may not use this file except in compliance with the License. 67dd252788645e940eada959bdde927426e2531c9Paul Duffin * You may obtain a copy of the License at 77dd252788645e940eada959bdde927426e2531c9Paul Duffin * 87dd252788645e940eada959bdde927426e2531c9Paul Duffin * http://www.apache.org/licenses/LICENSE-2.0 97dd252788645e940eada959bdde927426e2531c9Paul Duffin * 107dd252788645e940eada959bdde927426e2531c9Paul Duffin * Unless required by applicable law or agreed to in writing, software 117dd252788645e940eada959bdde927426e2531c9Paul Duffin * distributed under the License is distributed on an "AS IS" BASIS, 127dd252788645e940eada959bdde927426e2531c9Paul Duffin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137dd252788645e940eada959bdde927426e2531c9Paul Duffin * See the License for the specific language governing permissions and 147dd252788645e940eada959bdde927426e2531c9Paul Duffin * limitations under the License. 157dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 167dd252788645e940eada959bdde927426e2531c9Paul Duffin 177dd252788645e940eada959bdde927426e2531c9Paul Duffinpackage com.google.common.reflect; 187dd252788645e940eada959bdde927426e2531c9Paul Duffin 197dd252788645e940eada959bdde927426e2531c9Paul Duffinimport static org.truth0.Truth.ASSERT; 207dd252788645e940eada959bdde927426e2531c9Paul Duffin 217dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.base.Charsets; 227dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.ImmutableMap; 237dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.Maps; 247dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.collect.Sets; 250888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.io.Closer; 260888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.io.Resources; 277dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.reflect.ClassPath.ClassInfo; 287dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.reflect.ClassPath.ResourceInfo; 297dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.reflect.subpackage.ClassInSubPackage; 307dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.testing.EqualsTester; 317dd252788645e940eada959bdde927426e2531c9Paul Duffinimport com.google.common.testing.NullPointerTester; 327dd252788645e940eada959bdde927426e2531c9Paul Duffin 337dd252788645e940eada959bdde927426e2531c9Paul Duffinimport junit.framework.TestCase; 347dd252788645e940eada959bdde927426e2531c9Paul Duffinimport org.junit.Test; 357dd252788645e940eada959bdde927426e2531c9Paul Duffin 367dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.io.ByteArrayInputStream; 377dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.io.File; 380888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.io.FileOutputStream; 397dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.io.IOException; 407dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.io.InputStream; 417dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.net.URI; 427dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.net.URISyntaxException; 437dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.net.URL; 447dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.net.URLClassLoader; 457dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Map; 467dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.Set; 470888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.jar.Attributes; 480888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.jar.JarFile; 490888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.jar.JarOutputStream; 507dd252788645e940eada959bdde927426e2531c9Paul Duffinimport java.util.jar.Manifest; 510888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.zip.ZipEntry; 527dd252788645e940eada959bdde927426e2531c9Paul Duffin 537dd252788645e940eada959bdde927426e2531c9Paul Duffin/** 547dd252788645e940eada959bdde927426e2531c9Paul Duffin * Functional tests of {@link ClassPath}. 557dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 567dd252788645e940eada959bdde927426e2531c9Paul Duffinpublic class ClassPathTest extends TestCase { 577dd252788645e940eada959bdde927426e2531c9Paul Duffin 587dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testGetResources() throws Exception { 597dd252788645e940eada959bdde927426e2531c9Paul Duffin Map<String, ResourceInfo> byName = Maps.newHashMap(); 607dd252788645e940eada959bdde927426e2531c9Paul Duffin Map<String, ResourceInfo> byToString = Maps.newHashMap(); 617dd252788645e940eada959bdde927426e2531c9Paul Duffin ClassPath classpath = ClassPath.from(getClass().getClassLoader()); 627dd252788645e940eada959bdde927426e2531c9Paul Duffin for (ResourceInfo resource : classpath.getResources()) { 630888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(resource.getResourceName()).isNotEqualTo(JarFile.MANIFEST_NAME); 640888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(resource.toString()).isNotEqualTo(JarFile.MANIFEST_NAME); 657dd252788645e940eada959bdde927426e2531c9Paul Duffin byName.put(resource.getResourceName(), resource); 667dd252788645e940eada959bdde927426e2531c9Paul Duffin byToString.put(resource.toString(), resource); 677dd252788645e940eada959bdde927426e2531c9Paul Duffin // TODO: This will fail on maven resources in the classes directory on a mac. 687dd252788645e940eada959bdde927426e2531c9Paul Duffin // assertNotNull(resource.url()); 697dd252788645e940eada959bdde927426e2531c9Paul Duffin } 707dd252788645e940eada959bdde927426e2531c9Paul Duffin String testResourceName = "com/google/common/reflect/test.txt"; 710888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(byName.keySet()).has().allOf( 727dd252788645e940eada959bdde927426e2531c9Paul Duffin "com/google/common/reflect/ClassPath.class", 737dd252788645e940eada959bdde927426e2531c9Paul Duffin "com/google/common/reflect/ClassPathTest.class", 747dd252788645e940eada959bdde927426e2531c9Paul Duffin "com/google/common/reflect/ClassPathTest$Nested.class", 757dd252788645e940eada959bdde927426e2531c9Paul Duffin testResourceName); 760888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(byToString.keySet()).has().allOf( 777dd252788645e940eada959bdde927426e2531c9Paul Duffin "com.google.common.reflect.ClassPath", 787dd252788645e940eada959bdde927426e2531c9Paul Duffin "com.google.common.reflect.ClassPathTest", 790888a09821a98ac0680fad765217302858e70fa4Paul Duffin "com.google.common.reflect.ClassPathTest$Nested", 807dd252788645e940eada959bdde927426e2531c9Paul Duffin testResourceName); 817dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(getClass().getClassLoader().getResource(testResourceName), 827dd252788645e940eada959bdde927426e2531c9Paul Duffin byName.get("com/google/common/reflect/test.txt").url()); 837dd252788645e940eada959bdde927426e2531c9Paul Duffin } 847dd252788645e940eada959bdde927426e2531c9Paul Duffin 850888a09821a98ac0680fad765217302858e70fa4Paul Duffin public void testGetAllClasses() throws Exception { 860888a09821a98ac0680fad765217302858e70fa4Paul Duffin Set<String> names = Sets.newHashSet(); 870888a09821a98ac0680fad765217302858e70fa4Paul Duffin Set<String> strings = Sets.newHashSet(); 880888a09821a98ac0680fad765217302858e70fa4Paul Duffin Set<Class<?>> classes = Sets.newHashSet(); 890888a09821a98ac0680fad765217302858e70fa4Paul Duffin Set<String> packageNames = Sets.newHashSet(); 900888a09821a98ac0680fad765217302858e70fa4Paul Duffin Set<String> simpleNames = Sets.newHashSet(); 910888a09821a98ac0680fad765217302858e70fa4Paul Duffin ClassPath classpath = ClassPath.from(getClass().getClassLoader()); 920888a09821a98ac0680fad765217302858e70fa4Paul Duffin for (ClassInfo classInfo : classpath.getAllClasses()) { 930888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (!classInfo.getPackageName().equals(ClassPathTest.class.getPackage().getName())) { 940888a09821a98ac0680fad765217302858e70fa4Paul Duffin continue; 950888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 960888a09821a98ac0680fad765217302858e70fa4Paul Duffin names.add(classInfo.getName()); 970888a09821a98ac0680fad765217302858e70fa4Paul Duffin strings.add(classInfo.toString()); 980888a09821a98ac0680fad765217302858e70fa4Paul Duffin classes.add(classInfo.load()); 990888a09821a98ac0680fad765217302858e70fa4Paul Duffin packageNames.add(classInfo.getPackageName()); 1000888a09821a98ac0680fad765217302858e70fa4Paul Duffin simpleNames.add(classInfo.getSimpleName()); 1010888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1020888a09821a98ac0680fad765217302858e70fa4Paul Duffin class LocalClass {} 1030888a09821a98ac0680fad765217302858e70fa4Paul Duffin Class<?> anonymousClass = new Object() {}.getClass(); 1040888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(names).has().allOf(anonymousClass.getName(), LocalClass.class.getName(), 1050888a09821a98ac0680fad765217302858e70fa4Paul Duffin ClassPath.class.getName(), ClassPathTest.class.getName()); 1060888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(strings).has().allOf(anonymousClass.getName(), LocalClass.class.getName(), 1070888a09821a98ac0680fad765217302858e70fa4Paul Duffin ClassPath.class.getName(), ClassPathTest.class.getName()); 1080888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(classes).has().allOf(anonymousClass, LocalClass.class, ClassPath.class, 1090888a09821a98ac0680fad765217302858e70fa4Paul Duffin ClassPathTest.class); 1100888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(packageNames).has().exactly(ClassPath.class.getPackage().getName()); 1110888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(simpleNames).has().allOf("", "Local", "ClassPath", "ClassPathTest"); 1120888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1130888a09821a98ac0680fad765217302858e70fa4Paul Duffin 1140888a09821a98ac0680fad765217302858e70fa4Paul Duffin public void testGetTopLevelClasses() throws Exception { 1157dd252788645e940eada959bdde927426e2531c9Paul Duffin Set<String> names = Sets.newHashSet(); 1167dd252788645e940eada959bdde927426e2531c9Paul Duffin Set<String> strings = Sets.newHashSet(); 1177dd252788645e940eada959bdde927426e2531c9Paul Duffin Set<Class<?>> classes = Sets.newHashSet(); 1187dd252788645e940eada959bdde927426e2531c9Paul Duffin Set<String> packageNames = Sets.newHashSet(); 1197dd252788645e940eada959bdde927426e2531c9Paul Duffin Set<String> simpleNames = Sets.newHashSet(); 1207dd252788645e940eada959bdde927426e2531c9Paul Duffin ClassPath classpath = ClassPath.from(getClass().getClassLoader()); 1217dd252788645e940eada959bdde927426e2531c9Paul Duffin for (ClassInfo classInfo 1227dd252788645e940eada959bdde927426e2531c9Paul Duffin : classpath.getTopLevelClasses(ClassPathTest.class.getPackage().getName())) { 1237dd252788645e940eada959bdde927426e2531c9Paul Duffin names.add(classInfo.getName()); 1247dd252788645e940eada959bdde927426e2531c9Paul Duffin strings.add(classInfo.toString()); 1257dd252788645e940eada959bdde927426e2531c9Paul Duffin classes.add(classInfo.load()); 1267dd252788645e940eada959bdde927426e2531c9Paul Duffin packageNames.add(classInfo.getPackageName()); 1277dd252788645e940eada959bdde927426e2531c9Paul Duffin simpleNames.add(classInfo.getSimpleName()); 1287dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1290888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(names).has().allOf(ClassPath.class.getName(), ClassPathTest.class.getName()); 1300888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(strings).has().allOf(ClassPath.class.getName(), ClassPathTest.class.getName()); 1310888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(classes).has().allOf(ClassPath.class, ClassPathTest.class); 1320888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(packageNames).has().item(ClassPath.class.getPackage().getName()); 1330888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(simpleNames).has().allOf("ClassPath", "ClassPathTest"); 1347dd252788645e940eada959bdde927426e2531c9Paul Duffin assertFalse(classes.contains(ClassInSubPackage.class)); 1357dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1367dd252788645e940eada959bdde927426e2531c9Paul Duffin 1370888a09821a98ac0680fad765217302858e70fa4Paul Duffin public void testGetTopLevelClassesRecursive() throws Exception { 1387dd252788645e940eada959bdde927426e2531c9Paul Duffin Set<Class<?>> classes = Sets.newHashSet(); 1397dd252788645e940eada959bdde927426e2531c9Paul Duffin ClassPath classpath = ClassPath.from(ClassPathTest.class.getClassLoader()); 1407dd252788645e940eada959bdde927426e2531c9Paul Duffin for (ClassInfo classInfo 1417dd252788645e940eada959bdde927426e2531c9Paul Duffin : classpath.getTopLevelClassesRecursive(ClassPathTest.class.getPackage().getName())) { 1420888a09821a98ac0680fad765217302858e70fa4Paul Duffin if (classInfo.getName().contains("ClassPathTest")) { 1430888a09821a98ac0680fad765217302858e70fa4Paul Duffin System.err.println(""); 1440888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1457dd252788645e940eada959bdde927426e2531c9Paul Duffin classes.add(classInfo.load()); 1467dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1470888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(classes).has().allOf(ClassPathTest.class, ClassInSubPackage.class); 1487dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1497dd252788645e940eada959bdde927426e2531c9Paul Duffin 1500888a09821a98ac0680fad765217302858e70fa4Paul Duffin public void testGetTopLevelClasses_diamond() throws Exception { 1517dd252788645e940eada959bdde927426e2531c9Paul Duffin ClassLoader parent = ClassPathTest.class.getClassLoader(); 1527dd252788645e940eada959bdde927426e2531c9Paul Duffin ClassLoader sub1 = new ClassLoader(parent) {}; 1537dd252788645e940eada959bdde927426e2531c9Paul Duffin ClassLoader sub2 = new ClassLoader(parent) {}; 1547dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(findClass(ClassPath.from(sub1).getTopLevelClasses(), ClassPathTest.class), 1557dd252788645e940eada959bdde927426e2531c9Paul Duffin findClass(ClassPath.from(sub2).getTopLevelClasses(), ClassPathTest.class)); 1567dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1577dd252788645e940eada959bdde927426e2531c9Paul Duffin 1587dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testEquals() { 1597dd252788645e940eada959bdde927426e2531c9Paul Duffin new EqualsTester() 1607dd252788645e940eada959bdde927426e2531c9Paul Duffin .addEqualityGroup(classInfo(ClassPathTest.class), classInfo(ClassPathTest.class)) 1617dd252788645e940eada959bdde927426e2531c9Paul Duffin .addEqualityGroup(classInfo(Test.class), classInfo(Test.class, getClass().getClassLoader())) 1627dd252788645e940eada959bdde927426e2531c9Paul Duffin .addEqualityGroup( 1637dd252788645e940eada959bdde927426e2531c9Paul Duffin new ResourceInfo("a/b/c.txt", getClass().getClassLoader()), 1647dd252788645e940eada959bdde927426e2531c9Paul Duffin new ResourceInfo("a/b/c.txt", getClass().getClassLoader())) 1657dd252788645e940eada959bdde927426e2531c9Paul Duffin .addEqualityGroup( 1667dd252788645e940eada959bdde927426e2531c9Paul Duffin new ResourceInfo("x.txt", getClass().getClassLoader())) 1677dd252788645e940eada959bdde927426e2531c9Paul Duffin .testEquals(); 1687dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1697dd252788645e940eada959bdde927426e2531c9Paul Duffin 1707dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testClassPathEntries_emptyURLClassLoader_noParent() { 1710888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(ClassPath.getClassPathEntries(new URLClassLoader(new URL[0], null)).keySet()) 1727dd252788645e940eada959bdde927426e2531c9Paul Duffin .isEmpty(); 1737dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1747dd252788645e940eada959bdde927426e2531c9Paul Duffin 1757dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testClassPathEntries_URLClassLoader_noParent() throws Exception { 1767dd252788645e940eada959bdde927426e2531c9Paul Duffin URL url1 = new URL("file:/a"); 1777dd252788645e940eada959bdde927426e2531c9Paul Duffin URL url2 = new URL("file:/b"); 1787dd252788645e940eada959bdde927426e2531c9Paul Duffin URLClassLoader classloader = new URLClassLoader(new URL[] {url1, url2}, null); 1797dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals( 1807dd252788645e940eada959bdde927426e2531c9Paul Duffin ImmutableMap.of(url1.toURI(), classloader, url2.toURI(), classloader), 1817dd252788645e940eada959bdde927426e2531c9Paul Duffin ClassPath.getClassPathEntries(classloader)); 1827dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1837dd252788645e940eada959bdde927426e2531c9Paul Duffin 1847dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testClassPathEntries_URLClassLoader_withParent() throws Exception { 1857dd252788645e940eada959bdde927426e2531c9Paul Duffin URL url1 = new URL("file:/a"); 1867dd252788645e940eada959bdde927426e2531c9Paul Duffin URL url2 = new URL("file:/b"); 1877dd252788645e940eada959bdde927426e2531c9Paul Duffin URLClassLoader parent = new URLClassLoader(new URL[] {url1}, null); 1887dd252788645e940eada959bdde927426e2531c9Paul Duffin URLClassLoader child = new URLClassLoader(new URL[] {url2}, parent) {}; 1897dd252788645e940eada959bdde927426e2531c9Paul Duffin ImmutableMap<URI, ClassLoader> classPathEntries = ClassPath.getClassPathEntries(child); 1907dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(ImmutableMap.of(url1.toURI(), parent, url2.toURI(), child), classPathEntries); 1910888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(classPathEntries.keySet()).has().exactly(url1.toURI(), url2.toURI()).inOrder(); 1927dd252788645e940eada959bdde927426e2531c9Paul Duffin } 1937dd252788645e940eada959bdde927426e2531c9Paul Duffin 1947dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testClassPathEntries_duplicateUri_parentWins() throws Exception { 1957dd252788645e940eada959bdde927426e2531c9Paul Duffin URL url = new URL("file:/a"); 1967dd252788645e940eada959bdde927426e2531c9Paul Duffin URLClassLoader parent = new URLClassLoader(new URL[] {url}, null); 1977dd252788645e940eada959bdde927426e2531c9Paul Duffin URLClassLoader child = new URLClassLoader(new URL[] {url}, parent) {}; 1987dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(ImmutableMap.of(url.toURI(), parent), ClassPath.getClassPathEntries(child)); 1997dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2007dd252788645e940eada959bdde927426e2531c9Paul Duffin 2017dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testClassPathEntries_notURLClassLoader_noParent() { 2020888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(ClassPath.getClassPathEntries(new ClassLoader(null) {}).keySet()).isEmpty(); 2037dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2047dd252788645e940eada959bdde927426e2531c9Paul Duffin 2057dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testClassPathEntries_notURLClassLoader_withParent() throws Exception { 2067dd252788645e940eada959bdde927426e2531c9Paul Duffin URL url = new URL("file:/a"); 2077dd252788645e940eada959bdde927426e2531c9Paul Duffin URLClassLoader parent = new URLClassLoader(new URL[] {url}, null); 2087dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals( 2097dd252788645e940eada959bdde927426e2531c9Paul Duffin ImmutableMap.of(url.toURI(), parent), 2107dd252788645e940eada959bdde927426e2531c9Paul Duffin ClassPath.getClassPathEntries(new ClassLoader(parent) {})); 2117dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2127dd252788645e940eada959bdde927426e2531c9Paul Duffin 2137dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testClassPathEntries_notURLClassLoader_withParentAndGrandParent() throws Exception { 2147dd252788645e940eada959bdde927426e2531c9Paul Duffin URL url1 = new URL("file:/a"); 2157dd252788645e940eada959bdde927426e2531c9Paul Duffin URL url2 = new URL("file:/b"); 2167dd252788645e940eada959bdde927426e2531c9Paul Duffin URLClassLoader grandParent = new URLClassLoader(new URL[] {url1}, null); 2177dd252788645e940eada959bdde927426e2531c9Paul Duffin URLClassLoader parent = new URLClassLoader(new URL[] {url2}, grandParent); 2187dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals( 2197dd252788645e940eada959bdde927426e2531c9Paul Duffin ImmutableMap.of(url1.toURI(), grandParent, url2.toURI(), parent), 2207dd252788645e940eada959bdde927426e2531c9Paul Duffin ClassPath.getClassPathEntries(new ClassLoader(parent) {})); 2217dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2227dd252788645e940eada959bdde927426e2531c9Paul Duffin 2237dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testClassPathEntries_notURLClassLoader_withGrandParent() throws Exception { 2247dd252788645e940eada959bdde927426e2531c9Paul Duffin URL url = new URL("file:/a"); 2257dd252788645e940eada959bdde927426e2531c9Paul Duffin URLClassLoader grandParent = new URLClassLoader(new URL[] {url}, null); 2267dd252788645e940eada959bdde927426e2531c9Paul Duffin ClassLoader parent = new ClassLoader(grandParent) {}; 2277dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals( 2287dd252788645e940eada959bdde927426e2531c9Paul Duffin ImmutableMap.of(url.toURI(), grandParent), 2297dd252788645e940eada959bdde927426e2531c9Paul Duffin ClassPath.getClassPathEntries(new ClassLoader(parent) {})); 2307dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2317dd252788645e940eada959bdde927426e2531c9Paul Duffin 2320888a09821a98ac0680fad765217302858e70fa4Paul Duffin public void testScan_classPathCycle() throws IOException { 2330888a09821a98ac0680fad765217302858e70fa4Paul Duffin File jarFile = File.createTempFile("with_circular_class_path", ".jar"); 2340888a09821a98ac0680fad765217302858e70fa4Paul Duffin try { 2350888a09821a98ac0680fad765217302858e70fa4Paul Duffin writeSelfReferencingJarFile(jarFile, "test.txt"); 2360888a09821a98ac0680fad765217302858e70fa4Paul Duffin ClassPath.Scanner scanner = new ClassPath.Scanner(); 2370888a09821a98ac0680fad765217302858e70fa4Paul Duffin scanner.scan(jarFile.toURI(), ClassPathTest.class.getClassLoader()); 2380888a09821a98ac0680fad765217302858e70fa4Paul Duffin assertEquals(1, scanner.getResources().size()); 2390888a09821a98ac0680fad765217302858e70fa4Paul Duffin } finally { 2400888a09821a98ac0680fad765217302858e70fa4Paul Duffin jarFile.delete(); 2410888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 2420888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 2430888a09821a98ac0680fad765217302858e70fa4Paul Duffin 2440888a09821a98ac0680fad765217302858e70fa4Paul Duffin public void testScanFromFile_fileNotExists() throws IOException { 2457dd252788645e940eada959bdde927426e2531c9Paul Duffin ClassLoader classLoader = ClassPathTest.class.getClassLoader(); 2460888a09821a98ac0680fad765217302858e70fa4Paul Duffin ClassPath.Scanner scanner = new ClassPath.Scanner(); 2470888a09821a98ac0680fad765217302858e70fa4Paul Duffin scanner.scanFrom(new File("no/such/file/anywhere"), classLoader); 2480888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(scanner.getResources()).isEmpty(); 2497dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2507dd252788645e940eada959bdde927426e2531c9Paul Duffin 2510888a09821a98ac0680fad765217302858e70fa4Paul Duffin public void testScanFromFile_notJarFile() throws IOException { 2527dd252788645e940eada959bdde927426e2531c9Paul Duffin ClassLoader classLoader = ClassPathTest.class.getClassLoader(); 2537dd252788645e940eada959bdde927426e2531c9Paul Duffin File notJar = File.createTempFile("not_a_jar", "txt"); 2540888a09821a98ac0680fad765217302858e70fa4Paul Duffin ClassPath.Scanner scanner = new ClassPath.Scanner(); 2557dd252788645e940eada959bdde927426e2531c9Paul Duffin try { 2560888a09821a98ac0680fad765217302858e70fa4Paul Duffin scanner.scanFrom(notJar, classLoader); 2577dd252788645e940eada959bdde927426e2531c9Paul Duffin } finally { 2587dd252788645e940eada959bdde927426e2531c9Paul Duffin notJar.delete(); 2597dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2600888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(scanner.getResources()).isEmpty(); 2617dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2627dd252788645e940eada959bdde927426e2531c9Paul Duffin 2637dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testGetClassPathEntry() throws URISyntaxException { 2647dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(URI.create("file:/usr/test/dep.jar"), 2650888a09821a98ac0680fad765217302858e70fa4Paul Duffin ClassPath.Scanner.getClassPathEntry( 2660888a09821a98ac0680fad765217302858e70fa4Paul Duffin new File("/home/build/outer.jar"), "file:/usr/test/dep.jar")); 2677dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(URI.create("file:/home/build/a.jar"), 2680888a09821a98ac0680fad765217302858e70fa4Paul Duffin ClassPath.Scanner.getClassPathEntry(new File("/home/build/outer.jar"), "a.jar")); 2697dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(URI.create("file:/home/build/x/y/z"), 2700888a09821a98ac0680fad765217302858e70fa4Paul Duffin ClassPath.Scanner.getClassPathEntry(new File("/home/build/outer.jar"), "x/y/z")); 2717dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(URI.create("file:/home/build/x/y/z.jar"), 2720888a09821a98ac0680fad765217302858e70fa4Paul Duffin ClassPath.Scanner.getClassPathEntry(new File("/home/build/outer.jar"), "x/y/z.jar")); 2737dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2747dd252788645e940eada959bdde927426e2531c9Paul Duffin 2757dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testGetClassPathFromManifest_nullManifest() { 2760888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(ClassPath.Scanner.getClassPathFromManifest(new File("some.jar"), null)).isEmpty(); 2777dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2787dd252788645e940eada959bdde927426e2531c9Paul Duffin 2797dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testGetClassPathFromManifest_noClassPath() throws IOException { 2807dd252788645e940eada959bdde927426e2531c9Paul Duffin File jarFile = new File("base.jar"); 2810888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest(""))) 2827dd252788645e940eada959bdde927426e2531c9Paul Duffin .isEmpty(); 2837dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2847dd252788645e940eada959bdde927426e2531c9Paul Duffin 2857dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testGetClassPathFromManifest_emptyClassPath() throws IOException { 2867dd252788645e940eada959bdde927426e2531c9Paul Duffin File jarFile = new File("base.jar"); 2870888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifestClasspath(""))) 2887dd252788645e940eada959bdde927426e2531c9Paul Duffin .isEmpty(); 2897dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2907dd252788645e940eada959bdde927426e2531c9Paul Duffin 2917dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testGetClassPathFromManifest_badClassPath() throws IOException { 2927dd252788645e940eada959bdde927426e2531c9Paul Duffin File jarFile = new File("base.jar"); 2937dd252788645e940eada959bdde927426e2531c9Paul Duffin Manifest manifest = manifestClasspath("an_invalid^path"); 2940888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest)) 2957dd252788645e940eada959bdde927426e2531c9Paul Duffin .isEmpty(); 2967dd252788645e940eada959bdde927426e2531c9Paul Duffin } 2977dd252788645e940eada959bdde927426e2531c9Paul Duffin 2987dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testGetClassPathFromManifest_relativeDirectory() throws IOException { 2997dd252788645e940eada959bdde927426e2531c9Paul Duffin File jarFile = new File("base/some.jar"); 3007dd252788645e940eada959bdde927426e2531c9Paul Duffin // with/relative/directory is the Class-Path value in the mf file. 3017dd252788645e940eada959bdde927426e2531c9Paul Duffin Manifest manifest = manifestClasspath("with/relative/dir"); 3020888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest)) 3030888a09821a98ac0680fad765217302858e70fa4Paul Duffin .has().exactly(new File("base/with/relative/dir").toURI()).inOrder(); 3047dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3057dd252788645e940eada959bdde927426e2531c9Paul Duffin 3067dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testGetClassPathFromManifest_relativeJar() throws IOException { 3077dd252788645e940eada959bdde927426e2531c9Paul Duffin File jarFile = new File("base/some.jar"); 3087dd252788645e940eada959bdde927426e2531c9Paul Duffin // with/relative/directory is the Class-Path value in the mf file. 3097dd252788645e940eada959bdde927426e2531c9Paul Duffin Manifest manifest = manifestClasspath("with/relative.jar"); 3100888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest)) 3110888a09821a98ac0680fad765217302858e70fa4Paul Duffin .has().exactly(new File("base/with/relative.jar").toURI()).inOrder(); 3127dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3137dd252788645e940eada959bdde927426e2531c9Paul Duffin 3147dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testGetClassPathFromManifest_jarInCurrentDirectory() throws IOException { 3157dd252788645e940eada959bdde927426e2531c9Paul Duffin File jarFile = new File("base/some.jar"); 3167dd252788645e940eada959bdde927426e2531c9Paul Duffin // with/relative/directory is the Class-Path value in the mf file. 3177dd252788645e940eada959bdde927426e2531c9Paul Duffin Manifest manifest = manifestClasspath("current.jar"); 3180888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest)) 3190888a09821a98ac0680fad765217302858e70fa4Paul Duffin .has().exactly(new File("base/current.jar").toURI()).inOrder(); 3207dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3217dd252788645e940eada959bdde927426e2531c9Paul Duffin 3227dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testGetClassPathFromManifest_absoluteDirectory() throws IOException { 3237dd252788645e940eada959bdde927426e2531c9Paul Duffin File jarFile = new File("base/some.jar"); 3247dd252788645e940eada959bdde927426e2531c9Paul Duffin Manifest manifest = manifestClasspath("file:/with/absolute/dir"); 3250888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest)) 3260888a09821a98ac0680fad765217302858e70fa4Paul Duffin .has().exactly(new File("/with/absolute/dir").toURI()).inOrder(); 3277dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3287dd252788645e940eada959bdde927426e2531c9Paul Duffin 3297dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testGetClassPathFromManifest_absoluteJar() throws IOException { 3307dd252788645e940eada959bdde927426e2531c9Paul Duffin File jarFile = new File("base/some.jar"); 3317dd252788645e940eada959bdde927426e2531c9Paul Duffin Manifest manifest = manifestClasspath("file:/with/absolute.jar"); 3320888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest)) 3330888a09821a98ac0680fad765217302858e70fa4Paul Duffin .has().exactly(new File("/with/absolute.jar").toURI()).inOrder(); 3347dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3357dd252788645e940eada959bdde927426e2531c9Paul Duffin 3367dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testGetClassPathFromManifest_multiplePaths() throws IOException { 3377dd252788645e940eada959bdde927426e2531c9Paul Duffin File jarFile = new File("base/some.jar"); 3387dd252788645e940eada959bdde927426e2531c9Paul Duffin Manifest manifest = manifestClasspath("file:/with/absolute.jar relative.jar relative/dir"); 3390888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest)) 3400888a09821a98ac0680fad765217302858e70fa4Paul Duffin .has().exactly( 3417dd252788645e940eada959bdde927426e2531c9Paul Duffin new File("/with/absolute.jar").toURI(), 3427dd252788645e940eada959bdde927426e2531c9Paul Duffin new File("base/relative.jar").toURI(), 3437dd252788645e940eada959bdde927426e2531c9Paul Duffin new File("base/relative/dir").toURI()) 3447dd252788645e940eada959bdde927426e2531c9Paul Duffin .inOrder(); 3457dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3467dd252788645e940eada959bdde927426e2531c9Paul Duffin 3477dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testGetClassPathFromManifest_leadingBlanks() throws IOException { 3487dd252788645e940eada959bdde927426e2531c9Paul Duffin File jarFile = new File("base/some.jar"); 3497dd252788645e940eada959bdde927426e2531c9Paul Duffin Manifest manifest = manifestClasspath(" relative.jar"); 3500888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest)) 3510888a09821a98ac0680fad765217302858e70fa4Paul Duffin .has().exactly(new File("base/relative.jar").toURI()).inOrder(); 3527dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3537dd252788645e940eada959bdde927426e2531c9Paul Duffin 3547dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testGetClassPathFromManifest_trailingBlanks() throws IOException { 3557dd252788645e940eada959bdde927426e2531c9Paul Duffin File jarFile = new File("base/some.jar"); 3567dd252788645e940eada959bdde927426e2531c9Paul Duffin Manifest manifest = manifestClasspath("relative.jar "); 3570888a09821a98ac0680fad765217302858e70fa4Paul Duffin ASSERT.that(ClassPath.Scanner.getClassPathFromManifest(jarFile, manifest)) 3580888a09821a98ac0680fad765217302858e70fa4Paul Duffin .has().exactly(new File("base/relative.jar").toURI()).inOrder(); 3597dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3607dd252788645e940eada959bdde927426e2531c9Paul Duffin 3617dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testGetClassName() { 3627dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals("abc.d.Abc", ClassPath.getClassName("abc/d/Abc.class")); 3637dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3647dd252788645e940eada959bdde927426e2531c9Paul Duffin 3657dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testResourceInfo_of() { 3667dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(ClassInfo.class, resourceInfo(ClassPathTest.class).getClass()); 3677dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(ClassInfo.class, resourceInfo(ClassPath.class).getClass()); 3680888a09821a98ac0680fad765217302858e70fa4Paul Duffin assertEquals(ClassInfo.class, resourceInfo(Nested.class).getClass()); 3697dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3707dd252788645e940eada959bdde927426e2531c9Paul Duffin 3717dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testGetSimpleName() { 3727dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals("Foo", 3737dd252788645e940eada959bdde927426e2531c9Paul Duffin new ClassInfo("Foo.class", getClass().getClassLoader()).getSimpleName()); 3747dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals("Foo", 3757dd252788645e940eada959bdde927426e2531c9Paul Duffin new ClassInfo("a/b/Foo.class", getClass().getClassLoader()).getSimpleName()); 3760888a09821a98ac0680fad765217302858e70fa4Paul Duffin assertEquals("Foo", 3770888a09821a98ac0680fad765217302858e70fa4Paul Duffin new ClassInfo("a/b/Bar$Foo.class", getClass().getClassLoader()).getSimpleName()); 3780888a09821a98ac0680fad765217302858e70fa4Paul Duffin assertEquals("", 3790888a09821a98ac0680fad765217302858e70fa4Paul Duffin new ClassInfo("a/b/Bar$1.class", getClass().getClassLoader()).getSimpleName()); 3800888a09821a98ac0680fad765217302858e70fa4Paul Duffin assertEquals("Foo", 3810888a09821a98ac0680fad765217302858e70fa4Paul Duffin new ClassInfo("a/b/Bar$Foo.class", getClass().getClassLoader()).getSimpleName()); 3820888a09821a98ac0680fad765217302858e70fa4Paul Duffin assertEquals("", 3830888a09821a98ac0680fad765217302858e70fa4Paul Duffin new ClassInfo("a/b/Bar$1.class", getClass().getClassLoader()).getSimpleName()); 3840888a09821a98ac0680fad765217302858e70fa4Paul Duffin assertEquals("Local", 3850888a09821a98ac0680fad765217302858e70fa4Paul Duffin new ClassInfo("a/b/Bar$1Local.class", getClass().getClassLoader()).getSimpleName()); 3860888a09821a98ac0680fad765217302858e70fa4Paul Duffin 3877dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3887dd252788645e940eada959bdde927426e2531c9Paul Duffin 3897dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testGetPackageName() { 3907dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals("", 3917dd252788645e940eada959bdde927426e2531c9Paul Duffin new ClassInfo("Foo.class", getClass().getClassLoader()).getPackageName()); 3927dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals("a.b", 3937dd252788645e940eada959bdde927426e2531c9Paul Duffin new ClassInfo("a/b/Foo.class", getClass().getClassLoader()).getPackageName()); 3947dd252788645e940eada959bdde927426e2531c9Paul Duffin } 3957dd252788645e940eada959bdde927426e2531c9Paul Duffin 3967dd252788645e940eada959bdde927426e2531c9Paul Duffin private static class Nested {} 3977dd252788645e940eada959bdde927426e2531c9Paul Duffin 3987dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testNulls() throws IOException { 3997dd252788645e940eada959bdde927426e2531c9Paul Duffin new NullPointerTester().testAllPublicStaticMethods(ClassPath.class); 4007dd252788645e940eada959bdde927426e2531c9Paul Duffin new NullPointerTester() 4017dd252788645e940eada959bdde927426e2531c9Paul Duffin .testAllPublicInstanceMethods(ClassPath.from(getClass().getClassLoader())); 4027dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4037dd252788645e940eada959bdde927426e2531c9Paul Duffin 4047dd252788645e940eada959bdde927426e2531c9Paul Duffin private static ClassPath.ClassInfo findClass( 4057dd252788645e940eada959bdde927426e2531c9Paul Duffin Iterable<ClassPath.ClassInfo> classes, Class<?> cls) { 4067dd252788645e940eada959bdde927426e2531c9Paul Duffin for (ClassPath.ClassInfo classInfo : classes) { 4077dd252788645e940eada959bdde927426e2531c9Paul Duffin if (classInfo.getName().equals(cls.getName())) { 4087dd252788645e940eada959bdde927426e2531c9Paul Duffin return classInfo; 4097dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4107dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4117dd252788645e940eada959bdde927426e2531c9Paul Duffin throw new AssertionError("failed to find " + cls); 4127dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4137dd252788645e940eada959bdde927426e2531c9Paul Duffin 4147dd252788645e940eada959bdde927426e2531c9Paul Duffin private static ResourceInfo resourceInfo(Class<?> cls) { 4157dd252788645e940eada959bdde927426e2531c9Paul Duffin return ResourceInfo.of(cls.getName().replace('.', '/') + ".class", cls.getClassLoader()); 4167dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4177dd252788645e940eada959bdde927426e2531c9Paul Duffin 4187dd252788645e940eada959bdde927426e2531c9Paul Duffin private static ClassInfo classInfo(Class<?> cls) { 4197dd252788645e940eada959bdde927426e2531c9Paul Duffin return classInfo(cls, cls.getClassLoader()); 4207dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4217dd252788645e940eada959bdde927426e2531c9Paul Duffin 4227dd252788645e940eada959bdde927426e2531c9Paul Duffin private static ClassInfo classInfo(Class<?> cls, ClassLoader classLoader) { 4237dd252788645e940eada959bdde927426e2531c9Paul Duffin return new ClassInfo(cls.getName().replace('.', '/') + ".class", classLoader); 4247dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4257dd252788645e940eada959bdde927426e2531c9Paul Duffin 4267dd252788645e940eada959bdde927426e2531c9Paul Duffin private static Manifest manifestClasspath(String classpath) throws IOException { 4277dd252788645e940eada959bdde927426e2531c9Paul Duffin return manifest("Class-Path: " + classpath + "\n"); 4287dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4297dd252788645e940eada959bdde927426e2531c9Paul Duffin 4300888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static void writeSelfReferencingJarFile(File jarFile, String... entries) 4310888a09821a98ac0680fad765217302858e70fa4Paul Duffin throws IOException { 4320888a09821a98ac0680fad765217302858e70fa4Paul Duffin Manifest manifest = new Manifest(); 4330888a09821a98ac0680fad765217302858e70fa4Paul Duffin // Without version, the manifest is silently ignored. Ugh! 4340888a09821a98ac0680fad765217302858e70fa4Paul Duffin manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0"); 4350888a09821a98ac0680fad765217302858e70fa4Paul Duffin manifest.getMainAttributes().put(Attributes.Name.CLASS_PATH, jarFile.getName()); 4360888a09821a98ac0680fad765217302858e70fa4Paul Duffin 4370888a09821a98ac0680fad765217302858e70fa4Paul Duffin Closer closer = Closer.create(); 4380888a09821a98ac0680fad765217302858e70fa4Paul Duffin try { 4390888a09821a98ac0680fad765217302858e70fa4Paul Duffin FileOutputStream fileOut = closer.register(new FileOutputStream(jarFile)); 4400888a09821a98ac0680fad765217302858e70fa4Paul Duffin JarOutputStream jarOut = closer.register(new JarOutputStream(fileOut)); 4410888a09821a98ac0680fad765217302858e70fa4Paul Duffin for (String entry : entries) { 4420888a09821a98ac0680fad765217302858e70fa4Paul Duffin jarOut.putNextEntry(new ZipEntry(entry)); 4430888a09821a98ac0680fad765217302858e70fa4Paul Duffin Resources.copy(ClassPathTest.class.getResource(entry), jarOut); 4440888a09821a98ac0680fad765217302858e70fa4Paul Duffin jarOut.closeEntry(); 4450888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 4460888a09821a98ac0680fad765217302858e70fa4Paul Duffin } catch (Throwable e) { 4470888a09821a98ac0680fad765217302858e70fa4Paul Duffin throw closer.rethrow(e); 4480888a09821a98ac0680fad765217302858e70fa4Paul Duffin } finally { 4490888a09821a98ac0680fad765217302858e70fa4Paul Duffin closer.close(); 4500888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 4510888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 4520888a09821a98ac0680fad765217302858e70fa4Paul Duffin 4537dd252788645e940eada959bdde927426e2531c9Paul Duffin private static Manifest manifest(String content) throws IOException { 4547dd252788645e940eada959bdde927426e2531c9Paul Duffin InputStream in = new ByteArrayInputStream(content.getBytes(Charsets.US_ASCII.name())); 4557dd252788645e940eada959bdde927426e2531c9Paul Duffin Manifest manifest = new Manifest(); 4567dd252788645e940eada959bdde927426e2531c9Paul Duffin manifest.read(in); 4577dd252788645e940eada959bdde927426e2531c9Paul Duffin return manifest; 4587dd252788645e940eada959bdde927426e2531c9Paul Duffin } 4597dd252788645e940eada959bdde927426e2531c9Paul Duffin} 460