This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.
If a file or path contains a "+", the URL returned by URLMapper.findURL (or FileObject.getURL) is not mappable back to its original FileObject using URLMapper.findFileObject (it returns null instead). If I manually replace "+" with "%2B" inside the returned URL, URLMapper.findFileObject works again. I guess this is because "+" inside an URL is mapped to " " (space). Maybe other special characters are not working as well (~ ? & # ; : % = ...). Don't know. Can you resolve this problem before the next NetBeans Platform release, please? Thanks in advance.
Why not donate unit test and a fix?
Well, it's too hard for me to fix it. Sorry. I tracked the problem down to DefaultURLMapper.getURL (URLMapper.java) around line 427: // XXX clumsy; see ArchiveURLMapper for possible cleaner style String toReplace = "__EXCLAMATION_REPLACEMENT__";//NOI18N retURL = new URL( "jar:" + new File(f,toReplace + fo.getPath()).toURI().toString().replaceFirst("/"+toReplace,"!/") + ((fo.isFolder() && !fo.isRoot()) ? "/" : "") ); The reverse operation : URLMapper.findFileObject(URL) calls DefaultURLMapper.getFileObjects(URL), futher calls DefaultURLMapper.getFileObjectsForJarProtocol(URL) and makes use of private class JarUrlParser to decode the jar:file: input URL. JarUrlParser then uses entryName = URLDecoder.decode(spec.substring(separator, spec.length()),"UTF-8"); to decode the path inside Jar, but URLDecoder translates '+' into ' ' (space). URLMapper.findURL and URLMapper.findFileObject are not bijectives due to the fact that the latter makes use of URLDecoder but the former does not call URLEncoder to encode each part of the input path. Don't know how to fix it without breaking other parts of NetBeans. Best regards Eric.
Well, it seems too hard for me to fix it. Sorry. I tracked the problem down to DefaultURLMapper.getURL (URLMapper.java) around line 427: // XXX clumsy; see ArchiveURLMapper for possible cleaner style String toReplace = "__EXCLAMATION_REPLACEMENT__";//NOI18N retURL = new URL( "jar:" + new File(f,toReplace + fo.getPath()).toURI().toString().replaceFirst("/"+toReplace,"!/") + ((fo.isFolder() && !fo.isRoot()) ? "/" : "") ); The reverse operation : URLMapper.findFileObject(URL) calls DefaultURLMapper.getFileObjects(URL), futher calls DefaultURLMapper.getFileObjectsForJarProtocol(URL) and makes use of private class JarUrlParser to decode the jar:file: input URL. JarUrlParser then uses entryName = URLDecoder.decode(spec.substring(separator, spec.length()),"UTF-8"); to decode the path inside Jar, but URLDecoder translates '+' into ' ' (space). URLMapper.findURL and URLMapper.findFileObject are not bijectives due to the fact that the latter makes use of URLDecoder but the former does not call URLEncoder to encode each part of the input path. Don't know how to fix it without breaking other parts of NetBeans. Best regards Eric.
URLEncoder and URLDecoder should not be used for encoding URLs, despite the names; they are only useful for application/x-www-form-urlencoded in servlets. URI escaping looks superficially similar but differs in a number of details. Unfortunately there is no clear specification of how nontrivial characters in the embedded URL of a jar-protocol URL should be represented, so we basically have to make it up ourselves and hope that it is somehow compatible with various JRE code which handles this protocol.
(In reply to comment #2) > Well, it's too hard for me to fix it. Sorry. It is not that hard to write a unit test and it clearly demonstrates what is broken. See http://hg.netbeans.org/ergonomics/rev/080cbec96ed6 which shows, things sort of work. Closing as works for me.
Integrated into 'main-golden' Changeset: http://hg.netbeans.org/main-golden/rev/080cbec96ed6 User: Jaroslav Tulach <jtulach@netbeans.org> Log: #203223: Test to show URLMapper sort of works