### Eclipse Workspace Patch 1.0 #P jython-trunk Index: src/org/python/core/PySystemState.java =================================================================== --- src/org/python/core/PySystemState.java (revision 7129) +++ src/org/python/core/PySystemState.java (working copy) @@ -16,19 +16,17 @@ import java.nio.charset.Charset; import java.nio.charset.UnsupportedCharsetException; import java.security.AccessControlException; -import java.util.concurrent.Callable; -import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.Map; -import java.util.Map.Entry; import java.util.Properties; import java.util.Set; import java.util.StringTokenizer; +import java.util.Map.Entry; +import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentMap; import java.util.jar.JarEntry; import java.util.jar.JarFile; -import com.google.common.collect.MapMaker; import org.jruby.ext.posix.util.Platform; import org.python.Version; import org.python.core.adapter.ClassicPyObjectAdapter; @@ -55,6 +53,7 @@ private static final String JAR_URL_PREFIX = "jar:file:"; private static final String JAR_SEPARATOR = "!"; + private static final String VFSZIP_PREFIX = "vfszip:"; public static final PyString version = new PyString(Version.getVersion()); public static final int hexversion = ((Version.PY_MAJOR_VERSION << 24) | @@ -1112,12 +1111,15 @@ * @return the full name of the jar file containing this class, null if not available. */ private static String getJarFileName() { - String jarFileName = null; - Class thisClass = PySystemState.class; + Class thisClass = PySystemState.class; String fullClassName = thisClass.getName(); String className = fullClassName.substring(fullClassName.lastIndexOf(".") + 1); URL url = thisClass.getResource(className + ".class"); - // we expect an URL like jar:file:/install_dir/jython.jar!/org/python/core/PySystemState.class + return getJarFileNameFromURL(url); + } + + protected static String getJarFileNameFromURL(URL url) { + String jarFileName = null; if (url != null) { try { // escape plus signs, since the URLDecoder would turn them into spaces @@ -1129,7 +1131,21 @@ urlString = urlString.replaceAll(escapedPlus, plus); int jarSeparatorIndex = urlString.lastIndexOf(JAR_SEPARATOR); if (urlString.startsWith(JAR_URL_PREFIX) && jarSeparatorIndex > 0) { + // jar:file:/install_dir/jython.jar!/org/python/core/PySystemState.class jarFileName = urlString.substring(JAR_URL_PREFIX.length(), jarSeparatorIndex); + } else if (urlString.startsWith(VFSZIP_PREFIX)) { + // vfszip:/some/path/jython.jar/org/python/core/PySystemState.class + final String path = PySystemState.class.getName().replace('.', '/'); + int jarIndex = urlString.indexOf(".jar/".concat(path)); + if (jarIndex > 0) { + jarIndex += 4; + int start = VFSZIP_PREFIX.length(); + if (Platform.IS_WINDOWS) { + // vfszip:/C:/some/path/jython.jar/org/python/core/PySystemState.class + start++; + } + jarFileName = urlString.substring(start, jarIndex); + } } } catch (Exception e) {} } Index: tests/java/org/python/core/PySystemStateTest.java =================================================================== --- tests/java/org/python/core/PySystemStateTest.java (revision 0) +++ tests/java/org/python/core/PySystemStateTest.java (revision 0) @@ -0,0 +1,81 @@ +package org.python.core; + +import java.io.IOException; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; + +import junit.framework.TestCase; + +import org.jruby.ext.posix.util.Platform; + +public class PySystemStateTest extends TestCase { + + public void testGetJarFileNameFromURL() throws Exception { + // null + assertNull(PySystemState.getJarFileNameFromURL(null)); + // plain jar url + String urlString = "jar:file:/some_dir/some.jar!/a/package/with/A.class"; + URL url = new URL(urlString); + assertEquals("/some_dir/some.jar", PySystemState.getJarFileNameFromURL(url)); + // jar url to decode + urlString = "jar:file:/some%20dir/some.jar!/a/package/with/A.class"; + url = new URL(urlString); + assertEquals("/some dir/some.jar", PySystemState.getJarFileNameFromURL(url)); + // jar url with + signs to escape + urlString = "jar:file:/some+dir/some.jar!/a/package/with/A.class"; + url = new URL(urlString); + assertEquals("/some+dir/some.jar", PySystemState.getJarFileNameFromURL(url)); + } + + public void testGetJarFileNameFromURL_jboss() throws Exception { + final String protocol = "vfszip"; + final String host = ""; + final int port = -1; + final URLStreamHandler handler = new TestJBossURLStreamHandler(); + String file; + URL url; + if (Platform.IS_WINDOWS) { + // plain jboss url + file = "/C:/some_dir/some.jar/org/python/core/PySystemState.class"; + url = new URL(protocol, host, port, file, handler); + // tests with jboss on windows gave URL's like this: + assertEquals("vfszip:/C:/some_dir/some.jar/org/python/core/PySystemState.class", url.toString()); + assertEquals("C:/some_dir/some.jar", PySystemState.getJarFileNameFromURL(url)); + // jboss url to decode + file = "/C:/some%20dir/some.jar/org/python/core/PySystemState.class"; + url = new URL(protocol, host, port, file, handler); + assertEquals("vfszip:/C:/some%20dir/some.jar/org/python/core/PySystemState.class", url.toString()); + assertEquals("C:/some dir/some.jar", PySystemState.getJarFileNameFromURL(url)); + // jboss url with + to escape + file = "/C:/some+dir/some.jar/org/python/core/PySystemState.class"; + url = new URL(protocol, host, port, file, handler); + assertEquals("vfszip:/C:/some+dir/some.jar/org/python/core/PySystemState.class", url.toString()); + assertEquals("C:/some+dir/some.jar", PySystemState.getJarFileNameFromURL(url)); + } else { + // plain jboss url + file = "/some_dir/some.jar/org/python/core/PySystemState.class"; + url = new URL(protocol, host, port, file, handler); + assertEquals("vfszip:/some_dir/some.jar/org/python/core/PySystemState.class", url.toString()); + assertEquals("/some_dir/some.jar", PySystemState.getJarFileNameFromURL(url)); + // jboss url to decode + file = "/some%20dir/some.jar/org/python/core/PySystemState.class"; + url = new URL(protocol, host, port, file, handler); + assertEquals("vfszip:/some%20dir/some.jar/org/python/core/PySystemState.class", url.toString()); + assertEquals("/some dir/some.jar", PySystemState.getJarFileNameFromURL(url)); + // jboss url with + to escape + file = "/some+dir/some.jar/org/python/core/PySystemState.class"; + url = new URL(protocol, host, port, file, handler); + assertEquals("vfszip:/some+dir/some.jar/org/python/core/PySystemState.class", url.toString()); + assertEquals("/some+dir/some.jar", PySystemState.getJarFileNameFromURL(url)); + } + } + + protected static class TestJBossURLStreamHandler extends URLStreamHandler { + + @Override + protected URLConnection openConnection(URL u) throws IOException { + throw new RuntimeException("unexpected call to openConnection " + u.toString()); + } + } +} Index: NEWS =================================================================== --- NEWS (revision 7139) +++ NEWS (working copy) @@ -2,6 +2,7 @@ Jython 2.5.2rc1 Bugs Fixed + - [ 1639 ] JBoss 5, vfszip protocol in use for jarFileName in PySystemState - [ 1660 ] threading module memory leak - [ 1452 ] pydoc help() function fails because sys.executable is None in stand-alone Jython - [ 1568 ] sys.stdout.encoding returns wrong value in Windows with Jython 2.5.1 (fixed on Java 6 only)