1cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath/*
2cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * Licensed to the Apache Software Foundation (ASF) under one or more
3cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * contributor license agreements.  See the NOTICE file distributed with
4cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * this work for additional information regarding copyright ownership.
5cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * The ASF licenses this file to You under the Apache License, Version 2.0
6cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * (the "License"); you may not use this file except in compliance with
7cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * the License.  You may obtain a copy of the License at
8cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath *
9cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath *     http://www.apache.org/licenses/LICENSE-2.0
10cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath *
11cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * Unless required by applicable law or agreed to in writing, software
12cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * distributed under the License is distributed on an "AS IS" BASIS,
13cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * See the License for the specific language governing permissions and
15cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * limitations under the License.
16cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath */
17cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
18ab762bb740405d0fefcccf4a0899a234f995be13Narayan Kamathpackage org.apache.harmony.tests.java.lang;
19cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
20cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamathimport junit.framework.TestCase;
2163291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller
2263291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fullerimport java.io.IOException;
238961c5878070790b3768bfbea5ba0c7a8d0df46dNarayan Kamathimport java.io.InputStream;
24ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fullerimport java.net.JarURLConnection;
25ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fullerimport java.net.URL;
26ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fullerimport java.util.Arrays;
27ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fullerimport java.util.jar.JarFile;
28ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fullerimport libcore.io.Streams;
29cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
30cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamathpublic class ClassLoaderTest extends TestCase {
31cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
3263291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller    /** A resource known to be present in the boot classpath. */
3363291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller    private static final String BOOT_RESOURCE_NAME = "java/util/logging/logging.properties";
34cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
3563291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller    /** A resource known to be present in the classpath associated with the test class. */
3663291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller    private static final String TEST_RESOURCE_NAME = ClassTest.RESOURCE_ABS_NAME;
3763291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller
3863291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller    private ClassLoader testClassLoader;
3963291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller
4063291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller    @Override
4163291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller    public void setUp() throws Exception {
4263291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        super.setUp();
4363291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        testClassLoader = getClass().getClassLoader();
44cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    }
45cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
46cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    /**
47cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath     * java.lang.ClassLoader#getSystemClassLoader()
48cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath     */
49cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    public void test_getSystemClassLoader() {
50cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        // Test for method java.lang.ClassLoader
51cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        // java.lang.ClassLoader.getSystemClassLoader()
52cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        ClassLoader cl = ClassLoader.getSystemClassLoader();
5363291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        assertNotNull(cl);
5463291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller
5563291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        // The SystemClassLoader's parent should be the Boot classloader, which is used to load
5663291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        // the various libcore classes.
5763291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        assertNotNull(cl.getParent());
5863291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        Class<?> libcoreClass = Integer.class;
5963291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        assertSame(cl.getParent(), libcoreClass.getClassLoader());
60cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
6163291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        // It is difficult to test further because the CTS tests run as an instrumented TestCase.
6263291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        // Android apps do not have a system classpath, and rely on an application classloader to
6363291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        // load app classes and resources, not the System ClassLoader. The System ClassLoader is not
6463291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        // usually the parent of the application class loader.
65cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    }
66cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
67cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    /**
68cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath     * java.lang.ClassLoader#getSystemResource(java.lang.String)
69cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath     */
70cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    public void test_getSystemResourceLjava_lang_String() {
71cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        // Test for method java.net.URL
72cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        // java.lang.ClassLoader.getSystemResource(java.lang.String)
7363291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller
7463291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        // It is difficult to test this because the CTS tests run as an instrumented TestCase.
7563291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        // Android apps do not have a system classpath, and rely on an application classloader to
7663291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        // load app classes and resources, not the System ClassLoader.
77cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    }
78cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
7963291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller    /**
8063291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller     * java.lang.ClassLoader#getResource(java.lang.String)
8163291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller     */
8263291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller    public void test_testClassLoader_getResourceLjava_lang_String() {
8363291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        // Test for method java.net.URL
8463291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        // java.lang.ClassLoader.getResource(java.lang.String)
8563291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller
8663291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        // Test basic class loader behavior for the ClassLoader that was used to load the test
8763291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        // class while being deliberately vague about which classloader it actually is.
8863291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller
8963291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        ClassLoader parentClassLoader = testClassLoader.getParent();
9063291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        assertNull(parentClassLoader.getResource(TEST_RESOURCE_NAME));
9163291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        assertGetResourceIsValid(parentClassLoader, BOOT_RESOURCE_NAME);
9263291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller
9363291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        assertGetResourceIsValid(testClassLoader, TEST_RESOURCE_NAME);
9463291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        assertGetResourceIsValid(testClassLoader, BOOT_RESOURCE_NAME);
9563291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller    }
9663291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller
9763291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller    /**
9863291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller     * java.lang.ClassLoader#getResourceAsStream(java.lang.String)
9963291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller     */
10063291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller    public void test_testClassLoader_getResourceAsStreamLjava_lang_String() throws Exception {
10163291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        // Test for method java.io.InputStream
10263291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        // java.lang.ClassLoader.getResourceAsStream(java.lang.String)
10363291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller
10463291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        // Test basic class loader behavior for the ClassLoader that was used to load the test
10563291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        // class while being deliberately vague about which classloader it actually is.
10663291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller
10763291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        ClassLoader parentClassLoader = testClassLoader.getParent();
10863291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        assertGetResourceAsStreamNotNull(parentClassLoader, BOOT_RESOURCE_NAME);
10963291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        assertNull(parentClassLoader.getResourceAsStream(TEST_RESOURCE_NAME));
11063291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller
11163291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        assertGetResourceAsStreamNotNull(testClassLoader, BOOT_RESOURCE_NAME);
11263291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        assertGetResourceAsStreamNotNull(testClassLoader, TEST_RESOURCE_NAME);
11363291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller    }
11463291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller
11563291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller    public void test_testClassLoader_loadClass() throws Exception {
11663291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        // Test basic class loader behavior for the ClassLoader that was used to load the test
11763291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        // class while being deliberately vague about which classloader it actually is.
11863291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        String integerClassName = Integer.class.getName();
11963291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        String testClassName = ClassLoaderTest.class.getName();
12063291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller
12163291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        ClassLoader parentClassLoader = testClassLoader.getParent();
12263291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        assertSame(Integer.class, parentClassLoader.loadClass(integerClassName));
12363291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        try {
12463291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller            parentClassLoader.loadClass(testClassName);
12563291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller            fail();
12663291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        } catch (ClassNotFoundException expected) {
12763291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        }
12863291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller
12963291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        assertSame(Integer.class, testClassLoader.loadClass(integerClassName));
13063291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        assertSame(this.getClass(), testClassLoader.loadClass(testClassName));
13163291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller    }
132cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
133cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    //Regression Test for JIRA-2047
13463291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller    public void test_testClassLoader_getResourceAsStream_withSharpChar() throws Exception {
13563291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        assertGetResourceAsStreamNotNull(testClassLoader, ClassTest.SHARP_RESOURCE_ABS_NAME);
13663291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller    }
13763291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller
138ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller    public void testUncachedJarStreamBehavior() throws Exception {
139ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        URL resourceFromJar = testClassLoader.getResource(TEST_RESOURCE_NAME);
140ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        JarURLConnection uncachedConnection = (JarURLConnection) resourceFromJar.openConnection();
141ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        uncachedConnection.setUseCaches(false);
142ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        JarFile uncachedJarFile = uncachedConnection.getJarFile();
143ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        InputStream is = uncachedConnection.getInputStream();
144ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        is.close();
145ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller
146ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        assertTrue("Closing the stream should close a cached connection",
147ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller                isJarUrlConnectClosed(uncachedConnection));
148ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller
149ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        // Closing the stream closes the JarFile.
150ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        assertTrue(isJarFileClosed(uncachedJarFile));
151ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller    }
152ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller
153ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller    public void testCachedJarStreamBehavior() throws Exception {
154ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        URL resourceFromJar = testClassLoader.getResource(TEST_RESOURCE_NAME);
155ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        JarURLConnection cachedConnection1 = (JarURLConnection) resourceFromJar.openConnection();
156ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        assertTrue(cachedConnection1.getUseCaches());
157ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller
158ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        JarURLConnection cachedConnection2 = (JarURLConnection) resourceFromJar.openConnection();
159ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        assertTrue(cachedConnection2.getUseCaches());
160ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller
161ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        InputStream is1 = cachedConnection1.getInputStream();
162ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        byte[] resourceData1 = Streams.readFullyNoClose(is1);
163ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        is1.close();
164ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        assertFalse("Closing the stream should not close a cached connection",
165ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller                isJarUrlConnectClosed(cachedConnection1));
166ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller
167ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        InputStream is2 = cachedConnection2.getInputStream();
168ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        byte[] resourceData2 = Streams.readFullyNoClose(is2);
169ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        is2.close();
170ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        assertFalse("Closing the stream should not close a cached connection",
171ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller                isJarUrlConnectClosed(cachedConnection2));
172ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller
173ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        assertEquals(Arrays.toString(resourceData1), Arrays.toString(resourceData2));
174ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller    }
175ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller
176ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller    public void testResourceJarFileBehavior() throws Exception {
177ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        URL resourceFromJar = testClassLoader.getResource(TEST_RESOURCE_NAME);
178ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        JarURLConnection urlConnection1 = (JarURLConnection) resourceFromJar.openConnection();
179ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        assertTrue(urlConnection1.getUseCaches());
180ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller
181ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        JarURLConnection urlConnection2 = (JarURLConnection) resourceFromJar.openConnection();
182ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        assertTrue(urlConnection1.getUseCaches());
183ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        assertNotSame(urlConnection1, urlConnection2);
184ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller
185ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        JarURLConnection uncachedConnection = (JarURLConnection) resourceFromJar.openConnection();
186ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        assertNotSame(uncachedConnection, urlConnection2);
187ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        uncachedConnection.setUseCaches(false);
188ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller
189ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        JarFile jarFile1 = urlConnection1.getJarFile();
190ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        JarFile jarFile2 = urlConnection2.getJarFile();
191ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        // Note: This implies nobody should ever call JarFile.close() when caching is enabled.
192ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        // We cannot test this, because it will break later tests.
193ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        assertSame(jarFile1, jarFile2);
194ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller
195ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        JarFile uncachedJarFile = uncachedConnection.getJarFile();
196ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        assertNotSame(jarFile1, uncachedJarFile);
197ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        uncachedJarFile.close();
198ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller
199ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        assertFalse(isJarFileClosed(jarFile1));
200ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        assertTrue(isJarFileClosed(uncachedJarFile));
201ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller    }
202ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller
20363291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller    private static void assertGetResourceAsStreamNotNull(ClassLoader classLoader,
20463291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller            String resourceName) throws IOException {
20563291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        InputStream is = null;
20663291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        try {
20763291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller            is = classLoader.getResourceAsStream(resourceName);
20863291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller            assertNotNull(is);
20963291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        } finally {
21063291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller            if (is != null) {
21163291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller                is.close();
21263291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller            }
21363291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        }
21463291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller    }
21563291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller
21663291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller    private static void assertGetResourceIsValid(ClassLoader classLoader, String resourceName) {
21763291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        java.net.URL u = classLoader.getResource(resourceName);
21863291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        assertNotNull(u);
21963291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        InputStream is = null;
22063291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        try {
22163291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller            is = u.openStream();
22263291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller            assertNotNull(is);
22363291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller            is.close();
22463291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        } catch (IOException e) {
22563291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller            fail("IOException getting stream for resource : " + e.getMessage());
22663291dd98b3df687d87c7a95b8813e1cd75f3715Neil Fuller        }
227cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    }
228ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller
229ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller    private static boolean isJarFileClosed(JarFile jarFile) {
230ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        // Indirectly detect that the JarFile has been closed.
231ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        try {
232ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller            jarFile.getEntry("anyName");
233ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller            return false;
234ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        } catch (IllegalStateException expected) {
235ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller            return true;
236ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        }
237ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller    }
238ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller
239ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller    private static boolean isJarUrlConnectClosed(JarURLConnection jarURLConnection)
240ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller            throws IOException {
241ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        // Indirectly detect that the jarURLConnection has been closed.
242ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        try {
243ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller            jarURLConnection.getInputStream();
244ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller            return false;
245ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        } catch (IllegalStateException e) {
246ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller            return true;
247ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller        }
248ef411e4b8932bf0519ebf509817fac8506e44aa5Neil Fuller    }
2498961c5878070790b3768bfbea5ba0c7a8d0df46dNarayan Kamath}