Hi,

Our download manager http://jdownloader.org/ has millions of customers.
Some of them also suffered from the 13 year old bug http://bugs.java.com/view_bug.do?bug_id=4523159. The issue happens because '!/' is used as seperator between a jar file and its content in URLStreamHandler and JarURLConnection.

I hereby want to suggest our bugfix.

It consists of a modified sun.net.www.protocol.jar.Handler and sun.net.www.protocol.jar.JarURLConnection. Instead of searching for '!/' and using the first hit, our customized sun.net.www.protocol.jar.Handler loops through URL.getFile() via indexof and substring and tests if it specifies the actual jar file on disk. In case the path contains '!/' we return a customized sun.net.www.protocol.jar.JarURLConnection that overrides getJarFileURL(),getJarEntry(),getEntryName() to provide the correct information.

The one disadvantage of this bugfix is the additional IO introduced by File.exits(), but that can be considered//neglectable/./

Please find attached our customized classes.

Best Regards
Daniel Wilhelm

PS: sean.cof...@oracle.com/sean.cof...@oracle.com told me to post this to net-dev

--
-----------------------------------------------
Daniel Wilhelm
CTO, Co-Founder
Appwork GmbH

T: +49 (911)97923112 (Mo-Fr 9:00 - 17:00 CET)

Schwabacherstraße 117,           90763 Fürth,          Germany

public class OracleWorkaroundJarHandler extends sun.net.www.protocol.jar.Handler {

    @Override
    protected URLConnection openConnection(final URL url) throws IOException {
        try {
            // System.out.println("openConnection:" + url);
            final String path = url.getFile();
            URL jarFileURL = null;
            int lastIndex = 0;
            if (path.startsWith("file:")) {
                while (true) {
                    final int indexOf = path.indexOf(".jar", lastIndex);
                    if (indexOf > 0) {
                        final int index = indexOf + 4;
                        lastIndex = index;
                        final String jarFileName = path.substring(0, index);
                        if (jarFileName.contains("!/")) {
                            final File jarFile;
                            final URL jarURL;
                            try {
                                jarURL = new URL(jarFileName);
                                jarFile = new File(jarURL.toURI());
                            } catch (Exception e) {
                                e.printStackTrace();
                                continue;
                            }
                            if (jarFile.exists() && jarFile.isFile()) {
                                jarFileURL = jarURL;
                                break;
                            }
                        }
                    } else {
                        break;
                    }
                }
            }
            if (jarFileURL != null) {
                lastIndex++;// skip !
                final URL finalJarFileURL = jarFileURL;
                final String entryName;
                if (++lastIndex != path.length()) {
                    final String tempEntryName = path.substring(lastIndex, path.length());
                    entryName = sun.net.www.ParseUtil.decode(tempEntryName);
                } else {
                    entryName = null;
                }
                System.out.println("Workaround for URL.openConnection:" + finalJarFileURL + " Entry:" + entryName);
                return new sun.net.www.protocol.jar.JarURLConnection(url, this) {
                    @Override
                    public URL getJarFileURL() {
                        return finalJarFileURL;
                    }

                    @Override
                    public JarEntry getJarEntry() throws IOException {
                        return getJarFile().getJarEntry(getEntryName());
                    }

                    @Override
                    public String getEntryName() {
                        return entryName;
                    }
                };
            }
        } catch (final Throwable e) {
            e.printStackTrace();
        }
        return super.openConnection(url);

    }
}

Reply via email to