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.

Bug 129772

Summary: Wrong protocol (nbjcl) for jar file url
Product: platform Reporter: mgoe <mgoe>
Component: Module SystemAssignee: Jesse Glick <jglick>
Status: RESOLVED FIXED    
Severity: blocker CC: antuano, mmirilovic, pnejedly, sreimers, sri
Priority: P1    
Version: 6.x   
Hardware: PC   
OS: Linux   
Issue Type: DEFECT Exception Reporter:
Bug Depends on: 134424    
Bug Blocks:    
Attachments: Module suite project showing the issue.
Simple patch to use jar URLs for certain JARs only
Patch using option #1: produces jar-protocol URLs, handling NB's own with the special cache, delegating others
Issues after making changes
Issues after making changes

Description mgoe 2008-03-11 13:54:07 UTC
When using:

URL url = getClass().getResource("/org/yourorghere/module1/JarURLTestAction.class");

in a module suite project with Netbeans 6.1beta the url contains:

nbjcl:file:/home/mgoe/NetBeansProjects/suite9/build/cluster/modules/org-yourorghere-module1.jar!/org/yourorghere/module1/JarURLTestAction.class

This URL cannot be used by third party libraries because the protocol nbjcl is unknown.
The same code worked fine in NB 6.0. So this is a regression which has to be fixed as soon as possible.

Best regards,
Martin Goettlicher
Comment 1 mgoe 2008-03-11 13:55:46 UTC
Created attachment 58149 [details]
Module suite project showing the issue.
Comment 2 mgoe 2008-03-11 13:57:55 UTC
In order to reproduce the problem please use the module suite project attached and select File->JarFileURL Test and 
have a look at the output.
Comment 3 Jesse Glick 2008-03-17 23:05:00 UTC
The new protocol implements an improved module cache and loading system. URL seems to work for me:

System.out.println(url.openConnection().getContentLength()); => 2275

If you want a jar-protocol URL for some other purpose, you can use e.g.

System.out.println(new URL(FileUtil.getArchiveRoot(getClass().getProtectionDomain().getCodeSource().getLocation()),
"org/yourorghere/module1/JarURLTestAction.class"));

or simply s/^nbjcl/jar/ what getClass() provides.
Comment 4 mgoe 2008-03-18 09:40:18 UTC
It's no so easy. There are a lot of third party libraries out there which use getClass().getResource() to read 
resource files etc. All these libraries will no longer work because they don't do the magic jglick described. That 
means you cannot use third party libraries any more. I find it very annoying that netbeans reinvents the wheel in 
every place. Coding practices which were valid long before netbeans was invented don't no longer work from one 
netbeans version to the other. You cannot break interfaces specified in the jdk.

From the URL class javadoc:

"Protocol handlers for the following protocols are guaranteed to exist on the search path :- 
     http, https, ftp, file, and jar"

So there is no guarantee for a nbjcl protocol handler. And therefore this protocol is useless since no third party 
library will ever support it. Please fix this regression from netbeans 6.0 and make getClass().getResource() return a 
jar file URL again.

Best regards,
Martin Goettlicher
Comment 5 Jesse Glick 2008-03-18 16:02:35 UTC
You only need to do something special if you specifically want a jar-protocol URL. The nbjcl-protocol URL can be opened
and used as it is.

The Java platform does not specify what kind of URL will be returned for Class.getResource. That is entirely dependent
on the ClassLoader implementation. The enumeration of "supported" protocols means simply that an application which does
not register any URL stream handlers of its own will automatically be able to create and open URLs using those
protocols. The NB platform defines a new handler and uses it.

If there is a concrete problem which can be observed due to this change, i.e. a minimal module or suite working as
expected in 6.0 and not in 6.1, then please attach for inspection.
Comment 6 mgoe 2008-03-18 17:01:35 UTC
Code such as (see also code example in javadoc of class JarURLConnection):

URL url = getClass.getResource("Some Resource");
JarURLConnection jarConnection = (JarURLConnection)url.openConnection();

will no longer work since the object returned by url.openConnection() cannot be cast to a JarURLConnection.

From the javadoc of URL.openConnection():

"Returns a URLConnection object that represents a connection to the remote object referred to by the URL. 
A new connection is opened every time by calling the openConnection method of the protocol handler for this URL. 
If for the URL's protocol (such as HTTP or JAR), there exists a public, specialized URLConnection subclass belonging 
to one of the following packages or one of their subpackages: java.lang, java.io, java.util, java.net, the connection 
returned will be of that subclass. For example, for HTTP an HttpURLConnection will be returned, and for JAR a 
JarURLConnection will be returned."
Comment 7 Petr Nejedly 2008-03-18 17:28:40 UTC
The question still remains why would you (or the library) cast specifically to the JarURLConnection?
Why isn't URLConnection good enough for you [*]?

If your classes were laid out plain in a folder (very legal and JDK-well-handled case), you'll see the same problem,
casting FileURLConnection to JarURLConnection, for examle.

*) Well, I can imagine a construct trying to find its own class to locate the jar and reference relatively-positioned
files from installation. But even in this case, the NetBeans way is to use InstalledFilesLocator, and the common (JDK)
way is to follow the path of getClass().getProtectionDomain().getCodeSource().getLocation(), which will work OK even
under NetBeans.
Comment 8 Jesse Glick 2008-03-18 17:42:18 UTC
Right, I am still looking for a concrete example of a library which inherently requires a jar-protocol URL. And does
this library still work e.g. from a (JDK 6+) Java Web Start app where the URLs will be http-protocol? Or with an
unpacked dir of classes where the URLs will be file-protocol, as Petr mentioned? Or in ClassWorlds which has its own
specialized loading scheme?
Comment 9 mgoe 2008-03-19 10:29:44 UTC
Sorry for not responding promptly. pnejedly had the correct assumption. Each of our modules can have its own icons 
(which are svg files embedded in the jar file of the module). Inspired by the code example in the javadoc of the class 
JarURLConnection I used JarURLConnection.getJarFileURL() to get the URL of my svg file because the transcoder of the 
batik toolkit allows to transcode a svg file from an URL/URI. This was what failed because the batik transcoder didn't 
know how to handle the nbjcl protocol. I now have implemented a solution which uses an InputStream for the transcoder 
input so I no longer need the URL. What annoyed me was the fact that code which was running for years with netbeans 
5.0, 5.5, 5.5.1 and 6.0 stopped working after I switched to netbeans 6.1beta (which I thought was just an update 
release fixing some bugs). The accompanying documentation also didn't mention this change.
Comment 10 Jesse Glick 2008-03-19 16:04:02 UTC
Good point, I noted the change in Modules API: #f2c147247cc2

If we find a reasonably straightforward way to use jar protocol for module resources, we would do that. It was
considered but seemed rather more complicated, as we would need to replace the JRE's protocol handler, delegating to it
for JARs which are not in fact modules.
Comment 11 Lukas Hasik 2008-03-20 11:14:43 UTC
*** Issue 130618 has been marked as a duplicate of this issue. ***
Comment 12 sri 2008-03-31 20:21:42 UTC
any updates on nbjcl issue. i am stuck on this for a while and cannot seem to progress. any quick fix would really help.

thanks
sri
Caused by: java.io.FileNotFoundException: nbjcl:file:/C:/Temp2/MySuite/build/cluster/modules/moduleA.jar!/
        at org.netbeans.JarClassLoader$ResURLConnection.connect(JarClassLoader.java:844)
        at org.netbeans.JarClassLoader$ResURLConnection.getInputStream(JarClassLoader.java:869)
        at java.net.URL.openStream(URL.java:1009)
        at org.apache.openjpa.lib.util.J2DoPrivHelper$39.run(J2DoPrivHelper.java:825)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.apache.openjpa.lib.meta.URLMetaDataIterator.getInputStream(URLMetaDataIterator.java:67)
        at org.apache.openjpa.lib.meta.ClassArgParser.parseTypeNames(ClassArgParser.java:243)
Comment 13 Jesse Glick 2008-04-02 17:51:36 UTC
*** Issue 130618 has been marked as a duplicate of this issue. ***
Comment 14 Jesse Glick 2008-04-02 17:53:40 UTC
No changes planned for 6.1. sri: I am not sure what your stack trace means, but if you can find a minimal self-contained
test case demonstrating the problem, please file a separate bug report for evaluation.
Comment 15 Jesse Glick 2008-04-04 22:25:25 UTC
I can propose some untested patches. Probably too late for 6.1, TBD.
Comment 16 Jesse Glick 2008-04-04 22:26:39 UTC
Created attachment 59712 [details]
Simple patch to use jar URLs for certain JARs only
Comment 17 sreimers 2008-04-04 22:32:54 UTC
Looks good for me. I will try it out and keep you posted. Thanks for your effort.
Comment 18 Jesse Glick 2008-04-05 00:45:12 UTC
Created attachment 59717 [details]
Patch using option #1: produces jar-protocol URLs, handling NB's own with the special cache, delegating others
Comment 19 sri 2008-04-12 17:39:37 UTC
How and where to find these updates. I tried to pull sources last night using hg pull -u and also did hg update. But I
cudn't find these changes. I would greatly appreciate if I can pull these changes. I have 'main' as cloned repo.
I tried to manually merge these changes but cudn't make NB start. 

thanks
sri
Comment 20 Jesse Glick 2008-04-14 15:20:35 UTC
The potential fixes are available as patches only, for purposes of evaluation and discussion; they are not in the repo.
Comment 21 sri 2008-04-14 16:35:46 UTC
jesse,
thanks for the update. i mean to say these changes must be somewhere in the system not necessarily the main repo( if i
can atleast browse to these changed files). i want to have the these files wherever they are located so that i can test
these changes. is this possible?
thanks
sri
Comment 22 Jesse Glick 2008-04-15 02:19:30 UTC
Again: the changes are not in any repository. They are available as patches only.
Comment 23 sri 2008-04-16 05:52:26 UTC
Created attachment 60247 [details]
Issues after making changes
Comment 24 sri 2008-04-16 06:01:56 UTC
Created attachment 60248 [details]
Issues after making changes
Comment 25 sri 2008-04-16 06:07:41 UTC
i've tested again today and found the following issues. earlier i forgot to change the META-INF/services value for
startup. the changes have solve the issue. im able to get what i  want. thanks to all the folks who invested so much
time. i really appreciate your help. 
however, i do get some errors during startup ( 1 and 2) and while trying to build the project for the first time ( 3
thru 6) in the attachments.
it might be possible that i might be missing something. please correct me.

thanks and thanks once again
sri
Comment 26 Jesse Glick 2008-04-25 19:06:54 UTC
*** Issue 127268 has been marked as a duplicate of this issue. ***
Comment 27 Jesse Glick 2008-04-25 20:23:05 UTC
x
Comment 28 Jesse Glick 2008-04-25 20:24:14 UTC
I have a fix that seems to work, using option #1: go back to using "jar" protocol rather than "nbjcl", but with a
special protocol handler which loads NB module resources from the binary cache. It is slightly different from the patch
I last attached; I found I needed to override parseURL in the handler, to deal with javawebstart and websvc.* modules
which use url="/..../something" in their layers (a questionable practice but probably should be permitted). I did not
find any problems with Java SE library definitions such as sri seemed to be having. Review would be appreciated of
course. #7ccf89a50f5f in core-main. Could potentially be backported to a 6.1 update release, though it is a somewhat
dangerous fix so I don't really recommend it; better to let it mature in dev builds.
Comment 29 Jesse Glick 2008-04-28 16:12:32 UTC
Additional #fbc63451ecd9 in core-main just fixes JarClassLoaderTest.
Comment 30 Jesse Glick 2008-05-12 22:02:24 UTC
Additional fix for issue #134424 in 7d33b9d2ed38.
Comment 31 Jesse Glick 2008-05-14 14:57:20 UTC
#3391c5e1cc92 removes the notice of incompatibility from API changes for 6.5, so it should only appear in 6.1 Javadoc.
Comment 32 Quality Engineering 2008-05-20 05:13:37 UTC
Integrated into 'main-golden', available in NB_Trunk_Production #206 build
Changeset: http://hg.netbeans.org/main/rev/3391c5e1cc92
User: Jesse Glick <jglick@netbeans.org>
Log: Removing notice of incompatibility for issue #129772 (nbjcl protocol) since we are back to jar protocol.
Comment 33 Quality Engineering 2008-12-23 14:32:33 UTC
This issue had *2 votes* before move to platform component