JDK-6753651 : Java 5.0 Update 16 Regression: new URL(url.toString()) does not work anymore
  • Type: Bug
  • Component: deploy
  • Sub-Component: deployment_toolkit
  • Affected Version: 5.0
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86
  • Submitted: 2008-09-29
  • Updated: 2011-02-16
  • Resolved: 2008-10-08
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.5.0_16"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_16-b02)
Java HotSpot(TM) Client VM (build 1.5.0_16-b02, mixed mode, sharing)


ADDITIONAL OS VERSION INFORMATION :
Linux berkeley2 2.6.13-15.8-smp #1 SMP Tue Feb 7 11:07:24 UTC 2006 x86_64 x86_64 x86_64 GNU/Linux


EXTRA RELEVANT SYSTEM CONFIGURATION :
Occurs since Update 16 of Java 5.0.


A DESCRIPTION OF THE PROBLEM :
A regression introduced by 1.5.0_16.

In a Java Webstart application, we used to do this:

URL url = Sample.class.getResource("test.gif");
...
String s = url.toString();
...
URL url2 = new URL(s);

This always worked, however it does not work anymore with update 16 of Java 5.0.

The reason seems a security fix so that url.toString() creates a string
such as "jar:jcp/jnlp/test.gif" which does not contain the jar location. This
happens because test.gif is part of the jar of the Webstart application
itself. But this is not anymore a legal URL specification string, hence
new URL(s) fails.

Note that conversion between URLs and Strings are not always
avoidable, in particular when URLs must be edited in the the GUI or
is part  of external files.

As far as I understand, the security fix of update 16 was introduced
to avoid to make the Webstart cache location explicit. I suggest in
this case that url.toString() creates a crypted string, e.g. "jar:X68zH78623.jar!jcp/jnlp/test.gif"
so that the crypted XX68zH78623.jar hides the location of the jar. Only
the currently running VM knows the real location. Then, new URL(...)
need to take those crypted jar location into account. This would be
better than the current situation wich created illegal URL strings, and
it could solve the problem.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Deploy the simple sample mentioned below as Java Webstart
application and run it via javaws.




EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
It should not fail with an exception.

ACTUAL -
It fails with the following exception:

java.net.MalformedURLException: no !/ in spec
	at java.net.URL.<init>(URL.java:601)
	at java.net.URL.<init>(URL.java:464)
	at java.net.URL.<init>(URL.java:413)
	at jcp.jnlp.Sample.<init>(Unknown Source)
	at jcp.jnlp.Sample.main(Unknown Source)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:585)
	at com.sun.javaws.Launcher.executeApplication(Launcher.java:1175)
	at com.sun.javaws.Launcher.executeMainClass(Launcher.java:1122)
	at com.sun.javaws.Launcher.continueLaunch(Launcher.java:965)
	at com.sun.javaws.Launcher.handleApplicationDesc(Launcher.java:518)
	at com.sun.javaws.Launcher.handleLaunchFile(Launcher.java:218)
	at com.sun.javaws.Launcher.run(Launcher.java:165)
	at java.lang.Thread.run(Thread.java:595)



ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.net.MalformedURLException: no !/ in spec

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
A simple sample:

package jcp.jnlp;

import javax.swing.*;
import java.net.*;

public class Sample extends JFrame {
    public Sample() {
        super("Sample");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                URL url = Sample.class.getResource("test.gif");
        System.err.println("URL: " + url.toString());
        try {
            url = new URL(url.toString());
        } catch (MalformedURLException ex) {
            ex.printStackTrace();
        }
    }

    public static void main(String args[]) {
        Sample frame = new Sample();
        frame.pack();
        frame.setVisible(true);
    }
}

The corresponding jnlp file:

<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+"
  codebase="http://localhost:8080/test"
>
<information>
  <title>Sample</title>
  <vendor>ILOG</vendor>
  <description>Demonstration of URL bug</description>
</information>
<offline-allowed/>
<security>
  <j2ee-application-client-permissions/>
</security>
<resources>
  <j2se version="1.2+" />
  <jar href="test-dep.jar"/>
  <property name="java.compiler" value="NONE" />
</resources>
<application-desc main-class="jcp.jnlp.Sample" />
</jnlp>

You also need to put an image called test.gif into jcp.jnlp.
(You can take any arbitrary image).

---------- END SOURCE ----------

Release Regression From : 5.0u15
The above release value was the last known release where this 
bug was not reproducible. Since then there has been a regression.