You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by dj...@apache.org on 2006/08/11 01:16:47 UTC
svn commit: r430581 - in /geronimo/trunk/modules/kernel/src:
java/org/apache/geronimo/kernel/classloader/JarFileUrlStreamHandler.java
test/org/apache/geronimo/kernel/classloader/UrlResourceFinderTest.java
Author: djencks
Date: Thu Aug 10 16:16:47 2006
New Revision: 430581
URL: http://svn.apache.org/viewvc?rev=430581&view=rev
Log:
GERONIMO-2305 fix JarFileUrlStreamHandler to work with any entry in the jarfile
Modified:
geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/classloader/JarFileUrlStreamHandler.java
geronimo/trunk/modules/kernel/src/test/org/apache/geronimo/kernel/classloader/UrlResourceFinderTest.java
Modified: geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/classloader/JarFileUrlStreamHandler.java
URL: http://svn.apache.org/viewvc/geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/classloader/JarFileUrlStreamHandler.java?rev=430581&r1=430580&r2=430581&view=diff
==============================================================================
--- geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/classloader/JarFileUrlStreamHandler.java (original)
+++ geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/classloader/JarFileUrlStreamHandler.java Thu Aug 10 16:16:47 2006
@@ -16,13 +16,15 @@
*/
package org.apache.geronimo.kernel.classloader;
+import java.io.File;
+import java.io.IOException;
+import java.io.FileNotFoundException;
+import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
-import java.net.MalformedURLException;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
-import java.io.File;
/**
* @version $Rev$ $Date$
@@ -56,11 +58,48 @@
this.expectedUrl = expectedUrl;
}
- public URLConnection openConnection(URL url) throws MalformedURLException {
+ public URLConnection openConnection(URL url) throws IOException {
if (expectedUrl == null) throw new IllegalStateException("expectedUrl was not set");
- // alternatively we could return a connection using the normal jar url connection
- if (!expectedUrl.equals(url)) throw new IllegalArgumentException("Expected url [" + expectedUrl + "], but was [" + url + "]");
+ // the caller copied the URL reusing a stream handler from a previous call
+ if (!expectedUrl.equals(url)) {
+ // the new url is supposed to be within our context, so it must have a jar protocol
+ if (!url.getProtocol().equals("jar")) {
+ throw new IllegalArgumentException("Unsupported protocol " + url.getProtocol());
+ }
+
+ // split the path at "!/" into the file part and entry part
+ String path = url.getPath();
+ String[] chunks = path.split("!/", 2);
+
+ // if we only got only one chunk, it didn't contain the required "!/" delimiter
+ if (chunks.length == 1) {
+ throw new MalformedURLException("Url does not contain a '!' character: " + url);
+ }
+
+ String file = chunks[0];
+ String entryPath = chunks[1];
+
+ // this handler only supports jars on the local file system
+ if (!file.startsWith("file:")) {
+ // let the system handler deal with this
+ return new URL(url.toExternalForm()).openConnection();
+ }
+ file = file.substring("file:".length());
+
+ // again the new url is supposed to be within our context so it must reference the same jar file
+ if (!jarFile.getName().equals(file)) {
+ // let the system handler deal with this
+ return new URL(url.toExternalForm()).openConnection();
+ }
+
+ // get the entry
+ JarEntry newEntry = jarFile.getJarEntry(entryPath);
+ if (newEntry == null) {
+ throw new FileNotFoundException("Entry not found: " + url);
+ }
+ return new JarFileUrlConnection(url, jarFile, newEntry);
+ }
return new JarFileUrlConnection(url, jarFile, jarEntry);
}
Modified: geronimo/trunk/modules/kernel/src/test/org/apache/geronimo/kernel/classloader/UrlResourceFinderTest.java
URL: http://svn.apache.org/viewvc/geronimo/trunk/modules/kernel/src/test/org/apache/geronimo/kernel/classloader/UrlResourceFinderTest.java?rev=430581&r1=430580&r2=430581&view=diff
==============================================================================
--- geronimo/trunk/modules/kernel/src/test/org/apache/geronimo/kernel/classloader/UrlResourceFinderTest.java (original)
+++ geronimo/trunk/modules/kernel/src/test/org/apache/geronimo/kernel/classloader/UrlResourceFinderTest.java Thu Aug 10 16:16:47 2006
@@ -18,6 +18,7 @@
package org.apache.geronimo.kernel.classloader;
import java.net.URL;
+import java.net.MalformedURLException;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.jar.JarOutputStream;
@@ -27,6 +28,7 @@
import java.io.IOException;
import java.io.File;
import java.io.FileOutputStream;
+import java.io.FileNotFoundException;
import junit.framework.TestCase;
@@ -38,6 +40,8 @@
private File jarFile;
private Manifest manifest;
private Attributes resourceAttributes;
+ private File alternateJarFile;
+ private File testResource;
/**
* There are 2 "jars" with a "resource" inside. Make sure the enumeration has exactly 2 elements and
@@ -48,7 +52,7 @@
public void testResourceEnumeration() throws Exception {
URL jar1 = new File(basedir, "src/test-data/resourceFinderTest/jar1/").toURL();
URL jar2 = new File(basedir, "src/test-data/resourceFinderTest/jar2/").toURL();
- UrlResourceFinder resourceFinder = new UrlResourceFinder(new URL[] {jar1, jar2});
+ UrlResourceFinder resourceFinder = new UrlResourceFinder(new URL[]{jar1, jar2});
Enumeration enumeration = resourceFinder.findResources("resource");
@@ -70,7 +74,7 @@
public void testDirectoryResource() throws Exception {
URL jar = new File(basedir, "src/test-data/resourceFinderTest/jar1/").toURL();
- UrlResourceFinder resourceFinder = new UrlResourceFinder(new URL[] {jar});
+ UrlResourceFinder resourceFinder = new UrlResourceFinder(new URL[]{jar});
ResourceHandle resource = resourceFinder.getResource("resource");
assertNotNull(resource);
@@ -109,7 +113,7 @@
public void testJarResource() throws Exception {
URL jar = jarFile.toURL();
- UrlResourceFinder resourceFinder = new UrlResourceFinder(new URL[] {jar});
+ UrlResourceFinder resourceFinder = new UrlResourceFinder(new URL[]{jar});
ResourceHandle resource = resourceFinder.getResource("resource");
assertNotNull(resource);
@@ -148,7 +152,7 @@
public void testAddURL() throws Exception {
URL jar1 = new File(basedir, "src/test-data/resourceFinderTest/jar1/").toURL();
- UrlResourceFinder resourceFinder = new UrlResourceFinder(new URL[] {jar1});
+ UrlResourceFinder resourceFinder = new UrlResourceFinder(new URL[]{jar1});
Enumeration enumeration = resourceFinder.findResources("resource");
@@ -196,7 +200,7 @@
public void testConcurrentAddURL() throws Exception {
URL jar1 = new File(basedir, "src/test-data/resourceFinderTest/jar1/").toURL();
URL jar2 = new File(basedir, "src/test-data/resourceFinderTest/jar2/").toURL();
- UrlResourceFinder resourceFinder = new UrlResourceFinder(new URL[] {jar1, jar2});
+ UrlResourceFinder resourceFinder = new UrlResourceFinder(new URL[]{jar1, jar2});
Enumeration enumeration = resourceFinder.findResources("resource");
@@ -239,16 +243,121 @@
public void testDirectoryDestroy() throws Exception {
URL jar = new File(basedir, "src/test-data/resourceFinderTest/jar1/").toURL();
- UrlResourceFinder resourceFinder = new UrlResourceFinder(new URL[] {jar});
+ UrlResourceFinder resourceFinder = new UrlResourceFinder(new URL[]{jar});
assertDestroyed(resourceFinder, "resource1", null);
}
public void testJarDestroy() throws Exception {
URL jar = jarFile.toURL();
- UrlResourceFinder resourceFinder = new UrlResourceFinder(new URL[] {jar});
+ UrlResourceFinder resourceFinder = new UrlResourceFinder(new URL[]{jar});
assertDestroyed(resourceFinder, "resource3", manifest);
}
+ public void testUrlCopy() throws Exception {
+ URL jar = jarFile.toURL();
+ UrlResourceFinder resourceFinder = new UrlResourceFinder(new URL[]{jar});
+
+ // get the resource
+ URL resource = resourceFinder.findResource("resource");
+ assertNotNull(resource);
+ assertEquals("resource3", toString(resource.openStream()));
+
+ // copy resource with string
+ URL stringCopy = new URL(resource.toExternalForm());
+ assertEquals("resource3", toString(stringCopy.openStream()));
+
+ // copy resource perserving the url handler
+ URL handlerCopy = new URL(resource, resource.toExternalForm());
+ assertEquals("resource3", toString(handlerCopy.openStream()));
+
+ // access the other resource using the original url as a starting point
+ URL other = new URL(resource, "jar3");
+ assertEquals("jar3", toString(other.openStream()));
+ }
+
+ public void testUrlAccess() throws Exception {
+ URL jar = jarFile.toURL();
+ UrlResourceFinder resourceFinder = new UrlResourceFinder(new URL[]{jar});
+
+ // get geronimo url from the resource finder
+ URL geronimoUrl = resourceFinder.findResource("resource");
+ assertNotNull(geronimoUrl);
+ assertEquals("resource3", toString(geronimoUrl.openStream()));
+
+ // get a system url by copying the url by string
+ URL systemUrl = new URL(geronimoUrl.toExternalForm());
+ assertEquals("resource3", toString(systemUrl.openStream()));
+
+ // verify both can see the jar3 file withing the jar file
+ assertEquals("jar3", toString(new URL(systemUrl, "jar3").openStream()));
+ assertEquals("jar3", toString(new URL(geronimoUrl, "jar3").openStream()));
+
+ // verify both can see the jar3 file withing the jar file using a full url spec
+ String mainEntry = "jar:" + jarFile.toURL().toExternalForm() + "!/jar3";
+ assertEquals("jar3", toString(new URL(systemUrl, mainEntry).openStream()));
+ assertEquals("jar3", toString(new URL(geronimoUrl, mainEntry).openStream()));
+
+ // verify both throw a FileNotFoundExcetion for an unknown file
+ try {
+ new URL(systemUrl, "unknown").openStream();
+ fail("Expected a FileNotFoundException");
+ } catch (FileNotFoundException expected) {
+ }
+ try {
+ new URL(geronimoUrl, "unknown").openStream();
+ fail("Expected a FileNotFoundException");
+ } catch (FileNotFoundException expected) {
+ }
+
+ // verify both can see the alternate jar
+ String alternateEntry = "jar:" + alternateJarFile.toURL().toExternalForm() + "!/jar4";
+ assertEquals("jar4", toString(new URL(systemUrl, alternateEntry).openStream()));
+ assertEquals("jar4", toString(new URL(geronimoUrl, alternateEntry).openStream()));
+
+ // verify both throw a FileNotFoundExcetion for an unknown entry in the alternate file
+ String alternateUnknownEntry = "jar:" + alternateJarFile.toURL().toExternalForm() + "!/unknown";
+ try {
+ new URL(systemUrl, alternateUnknownEntry).openStream();
+ fail("Expected a FileNotFoundException");
+ } catch (FileNotFoundException expected) {
+ }
+ try {
+ new URL(geronimoUrl, alternateUnknownEntry).openStream();
+ fail("Expected a FileNotFoundException");
+ } catch (FileNotFoundException expected) {
+ }
+
+ // verify both work an excepton for a non-jar entry
+ assertEquals("testResource", toString(new URL(systemUrl, testResource.toURL().toExternalForm()).openStream()));
+ assertEquals("testResource", toString(new URL(geronimoUrl, testResource.toURL().toExternalForm()).openStream()));
+
+ // verify both fail for a spec without a !/
+ String badEntry = "jar:" + alternateJarFile.toURL().toExternalForm();
+ try {
+ new URL(systemUrl, badEntry).openStream();
+ fail("Expected a FileNotFoundException");
+ } catch (MalformedURLException expected) {
+ }
+ try {
+ new URL(geronimoUrl, badEntry).openStream();
+ fail("Expected a FileNotFoundException");
+ } catch (MalformedURLException expected) {
+ }
+
+ // verify both throw FileNotFoundException for a nested jar file
+ badEntry = "jar:" + alternateJarFile.toURL().toExternalForm() + "!/foo.jar!/bar";
+ try {
+ new URL(systemUrl, badEntry).openStream();
+ fail("Expected a FileNotFoundException");
+ } catch (FileNotFoundException expected) {
+ }
+ try {
+ new URL(geronimoUrl, badEntry).openStream();
+ fail("Expected a FileNotFoundException");
+ } catch (FileNotFoundException expected) {
+ }
+ }
+
public void assertDestroyed(UrlResourceFinder resourceFinder, String resourceValue, Manifest expectedManifest) throws Exception {
ResourceHandle resource = resourceFinder.getResource("resource");
assertNotNull(resource);
@@ -268,7 +377,6 @@
URL directUrlCopy = new URL(directUrl.toExternalForm());
assertEquals(resourceValue, toString(directUrlCopy.openStream()));
-
// destroy
resourceFinder.destroy();
@@ -327,7 +435,7 @@
protected void setUp() throws Exception {
super.setUp();
-
+
//
// Build a simple Jar file to test with
//
@@ -338,7 +446,7 @@
resourceAttributes = new Attributes();
resourceAttributes.putValue("drink", "margarita");
manifest.getEntries().put("resource", resourceAttributes);
-
+
File targetDir = new File(basedir, "target");
jarFile = new File(targetDir, "resourceFinderTest.jar");
JarOutputStream jarOutputStream = new JarOutputStream(new FileOutputStream(jarFile), manifest);
@@ -347,6 +455,20 @@
jarOutputStream.putNextEntry(new ZipEntry("jar3"));
jarOutputStream.write("jar3".getBytes());
IoUtil.close(jarOutputStream);
+
+ alternateJarFile = new File(targetDir, "alternate.jar");
+ System.out.println(alternateJarFile.getAbsolutePath());
+ jarOutputStream = new JarOutputStream(new FileOutputStream(alternateJarFile), manifest);
+ jarOutputStream.putNextEntry(new ZipEntry("resource"));
+ jarOutputStream.write("resource4".getBytes());
+ jarOutputStream.putNextEntry(new ZipEntry("jar4"));
+ jarOutputStream.write("jar4".getBytes());
+ IoUtil.close(jarOutputStream);
+
+ testResource = new File(targetDir, "testResource");
+ FileOutputStream fileOutputStream = new FileOutputStream(testResource);
+ fileOutputStream.write("testResource".getBytes());
+ IoUtil.close(fileOutputStream);
}
protected void tearDown() throws Exception {