JDK-6483788 : DefaultFileManager.ZipFileObject.toUri() fails to escape space characters
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_vista
  • CPU: x86
  • Submitted: 2006-10-19
  • Updated: 2012-01-13
  • Resolved: 2012-01-13
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 Other
7 b72Fixed OpenJDK6Fixed
Description
FULL PRODUCT VERSION :
java version "1.6.0-beta2"
Java(TM) SE Runtime Environment (build 1.6.0-beta2-b86)
Java HotSpot(TM) Client VM (build 1.6.0-beta2-b86, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.0.5744]

A DESCRIPTION OF THE PROBLEM :
com.sun.tools.javac.util.DefaultFileManager.ZipFileObject.toUri() throws an IllegalArgumentException if the path includes a space.  This will occur frequently as the default Windows installation directory is "C:\Program Files\Java".  See http://forum.java.sun.com/thread.jspa?messageID=4422238.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Identify or create a path with one or more space characters.
2. Add a JAR file to the directory.
3. Modify classpath to include JAR.
4. Use the standard file manager to obtain a JavaFileObject from JAR.
5. Call toUri() on file object.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Method should return a valid URI.
ACTUAL -
Exception is thrown.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.IllegalArgumentException
at java.net.URI.create(URI.java:853)
at com.sun.tools.javac.util.DefaultFileManager$ZipFileObject.toUri(DefaultFileManager.java:1338)
at Test.main(Test.java:28)
Caused by: java.net.URISyntaxException: Illegal character in path at index 15: jar:/C:/Program Files/Java/jdk1.6.0/lib/tools.jar!com/sun/jarsigner/ContentSignerParameters.class
at java.net.URI$Parser.fail(URI.java:3061)
at java.net.URI$Parser.checkChars(URI.java:3234)
at java.net.URI$Parser.parsePath(URI.java:3338)
at java.net.URI$Parser.parseHierpart(URI.java:3308)
at java.net.URI$Parser.parse(URI.java:3267)
at java.net.URI.<init>(URI.java:585)
at java.net.URI.create(URI.java:851)
... 2 more

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.io.IOException;
import java.util.Collections;
import java.util.Locale;
 
import javax.tools.Diagnostic;
import javax.tools.DiagnosticListener;
import javax.tools.JavaFileObject;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
 
public class Test {
  public static void main(String[] pArgs) throws IOException {
    for (
      JavaFileObject fileObj :
      ToolProvider.getSystemJavaCompilerTool().getStandardFileManager(
        new DiagnosticListener<JavaFileObject>() {
          public void report(Diagnostic<? extends JavaFileObject> pDiagnostic) {
            System.out.println(pDiagnostic.getMessage(Locale.getDefault()));
          }
        }
       ).list(
         StandardLocation.CLASS_PATH,
         "",
         Collections.<JavaFileObject.Kind>singleton(JavaFileObject.Kind.CLASS),
         true
       )
    ) {
      System.out.println(fileObj.toUri());
    }
  }
}

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

CUSTOMER SUBMITTED WORKAROUND :
Decompile tools.jar and examine toUri() method of FileObject implementation.  Replace spaces with "%20" prior to the URI.create call:

if (mFileObject instanceof DefaultFileManager.ZipFileObject) {
  final DefaultFileManager.ZipFileObject fileObj = (DefaultFileManager.ZipFileObject) mFileObject;

  String s = (new File(fileObj.getZipName())).toURI().getPath().replaceAll(" ", "%20");
  String s1 = fileObj.getZipEntryName();
  return URI.create((new StringBuilder()).append("jar:").append(s).append("!").append(s1).toString());
}

Comments
EVALUATION Yes. Use File.toURI for underlying URI.
08-09-2009