Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4754763
Votes 0
Synopsis getResourceAsStream() fails with JNLPClassLoader
Category javawebstart:i18n
Reported Against 1.2 , mantis , sdk3.1_fcs
Release Fixed 1.2.0_03
State 10-Fix Delivered, bug
Priority: 3-Medium
Related Bugs 4776437 , 4777431 , 4778185
Submit Date 27-SEP-2002
Description




FULL PRODUCT VERSION :
java version "1.4.1"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-b21)
Java HotSpot(TM) Client VM (build 1.4.1-b21, mixed mode)

FULL OPERATING SYSTEM VERSION :
glibc-2.2.5, linux 2.4.19, Mandrake8.3
 
ADDITIONAL OPERATING SYSTEMS :


A DESCRIPTION OF THE PROBLEM :
getResourceAsStream throws an exception with the following
resource name:
World/Fran?ais/Commerce_et_?conomie
 
It works fine with something like Arts/Television
(no utf-8 specific characters)

The problem is with how the 
JNLPClassLoader makes HTTP GET requests - specifically how it encodes the 
HTTP Request header. You see, while JWS deals with utf-8 fine internally, it 
_mangles_ the HTTP Request header to the point where the JNLPDownloadServlet 
receives unrecognizable characters!

Take a simple case:
http://localhost/sw/Fran?ais.jar
(note the strange 'c' character - I see your html forms destroyed this 
utf-8/iso8859-1 character into a '?' ... hopefully your email client will be 
able to see it)

JWS seems to deal with it just fine, until it asks a webserver for the jar. 
JWS will then incorrectly create a request like this:
http://localhost/sw/Fran?ais.jar
(note the '?' instead of the '?')

You will note in rfc 1630 that only 7-bit ASCII characters are allowed in a 
URI. Therefore JWS MUST call URLEncode() before using the URL to make a 
connection.

http://www.ietf.org/rfc/rfc1630.txt?number=1630

There is no other way. This is simply how it is done.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1.create Fran?ais.jar
2. try to specify this in a jnlp file
3.try to access something in the Fran?ais.jar with
getResourceAsStream() - it will fail.
4. using the jnlpdownloadservlet, it will not accept the
Fran?ais.jar as a valid name as the C (with an accent) character
is not parsed right.


EXPECTED VERSUS ACTUAL BEHAVIOR :
I expect to be able to be able to use Fran?ais.jar.
Actual, this is imopssible.


ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.IllegalArgumentException
    at sun.net.www.ParseUtil.decode(ParseUtil.java:155)
    at sun.net.www.protocol.file.Handler.openConnection(Handler.java:57)
    at java.net.URL.openConnection(URL.java:943)
    at sun.net.www.protocol.jar.JarURLConnection.<init>(JarURLConnection.java:64)
    at sun.net.www.protocol.jar.Handler.openConnection(Handler.java:24)
    at java.net.URL.openConnection(URL.java:943)
    at com.sun.javaws.security.JNLPClassPath.check(JNLPClassPath.java:355)
    at
com.sun.javaws.security.JNLPClassPath$JarLoader.getResource(JNLPClassPath.java:495)
    at
com.sun.javaws.security.JNLPClassPath.findNamedResource(JNLPClassPath.java:224)
    at com.sun.javaws.security.JNLPClassPath.getResource(JNLPClassPath.java:265)
    at com.sun.jnlp.JNLPClassLoader$2.run(JNLPClassLoader.java:400)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.jnlp.JNLPClassLoader.findResource(JNLPClassLoader.java:398)
    at java.lang.ClassLoader.getResource(ClassLoader.java:780)
    at com.sun.jnlp.JNLPClassLoader.getResource(JNLPClassLoader.java:181)
    at java.lang.ClassLoader.getResourceAsStream(ClassLoader.java:941)
    at com.wss.calendar.client.swing.Main.test(Main.java:45)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
Source - the main() method specifiied in the jnlp file:
 
    public void test() throws Exception {
        String resource = "World/Fran?ais/Commerce_et_?conomie";
        System.out.println("resource (" + resource + ")");
        ClassLoader cl = this.getClass().getClassLoader();
        InputStream is = cl.getResourceAsStream(resource);
        // The above getResourceAsStream will throw()
        if (is == null)
            throw new Exception( "Did not contain the required resource:" +
                resource);
	// you will never see this println output
        System.out.println("Fran?ais/Commerce_et_?conomie worked!");
    }
---------- END SOURCE ----------

CUSTOMER WORKAROUND :
There was a work-around in 1.2-rc, but 1.2 has broken it. Now
there is no possible way to use utf-8 characters.
(Review ID: 164800) 
======================================================================
Work Around
N/A
Evaluation
Discription may be off - but must fix in mantis.
 xxxxx@xxxxx  2002-09-30

This is bouth "not a bug" and "fixed" , I will explain:
Section 3.4 of the JNLP 1.0.1 spec clearly states that all URL's
and partial URL's entered in a jnlp file must be "escaped" or "url encoded"
Thus "Fran?ias" must be entered in the jnlp file as: "Fran%e9ias"

That being said these is still a bug in the DiskCache implementation that 
causes the exception shown in the description.  This I have now fixed so
encoded urls with names such as "Fran%e9ias" will now work.
 xxxxx@xxxxx  2002-10-15
Comments
  
  Include a link with my name & email   

Submitted On 06-NOV-2002
randytidd
I believe that I have run into a variation of this bug, and I 
suspect it has the same root cause, and I think it's a little 
more serious than described above.

I have a JWS application that uses some XML files which have 
DOCTYPE and ENTITY declarations as follows:

<!DOCTYPE descriptor-repository 
SYSTEM "../dao/repository.dtd" [ 
  <!ENTITY alexpriced SYSTEM "../dao/repository-
alexpriced.xml"> 
  <!ENTITY internal SYSTEM "../dao/repository-internal.xml"> 
]>

Note the relative URL's defining the dtd and included xml 
files.  This poses a problem for JWS in a roundabout way as 
follows. In my example, I invoke a high level class like this:

   PBKey repositoryPBKey = new PBKey
("resources/ojb/repository.xml"); 
   broker = PersistenceBrokerFactory.createPersistenceBroker
(repositoryPBKey); 

Deep in the bowels of OJB (a third party database mapping 
framework from Jakarta), it needs to obtain a URL to this XML 
file and does so like this:

URL url = Thread.currentThread().getContextClassLoader
().getResource(repositoryFileName);

In the case of a JWS application, the class loader is an 
instance of JNLPClassLoader.  In my case, this is running on a 
Windows machine and the URL returned by the above 
statement is this:

jar:file:/C:/Documents and 
Settings/g1urct/.javaws/cache/http/Ddfin01/P7777/DMLittleAl
ex/DMcommon/DMdist/RMLittleAlex-
common.jar!/resources/ojb/repository.xml

The prefix up to ".javaws" is the JWS cache directory on the 
local machine.  Note the spaces imbedded in the URL -- 
in "Documents and Settings" -- which are part of the 
standard Windows path.  This is the problem.

This URL is passed to the XML parser -- by default the jaxp 
parser, but I've also tried Xerces.  While the XML parser is 
interpreting the file, it needs to read the DTD file.  It tries to 
create an aboslute URL for the DTD file by adding the relative 
URL it found to its base URL.  This results in code 
approximately like this:

   URL url = new URL("jar:file:/C:/Documents and 
Settings/g1urct/.javaws/cache/http/Ddfin01/P7777/DMLittleAl
ex/DMcommon/DMdist/RMLittleAlex-
common.jar!/resources/ojb/../dao/repository.dtd");

This causes a MalformedURLException deep in the bowels of 
Xerces which leads to the parser being unable to obtain the 
DTD.

The root of the bug is that the JNLPClassLoader does not 
encode the URL's it creates when loading files.  By contrast. 
the sun.misc.Launcher$AppClassLoader does perform this 
encoding, which means that this bug doesn't appear in 
standalone Java applications.  The implications I believe can 
be very widespread since basically any resource obtained 
through JWS's class loader can have an invalid URL if the base 
directory path contains characters not allowed in URL's such 
as a space.

I gave this roundabout explanation (sorry for taking up a little 
extra of your time) to demonstrate that an application 
developer does not have a hook to work around the problem.  
For obvious security reasons, it isn't possible to subclass the 
JNLPClassLoader, substitute a different class path or base dir, 
etc.  Resources are often obtained from the class loader deep 
in the bowels of toolkit code (in my example OJB and Xerces 
but it could be anywhere).  This really needs to be fixed in 
JWS.


Submitted On 15-NOV-2006
aaa



PLEASE NOTE: JDK6 is formerly known as Project Mustang