Re: JDTCompiler and locked jar files *again*
Dominik Drzewiecki wrote: I think I finally found it. And fixed it. JDTCompiler uses JasperLoader.getResourceAsStream() which is *not* overriden in JasperLoader and uses getResourceAsStream() derived from java.net.URLClassLoader (in fact from java.lang.ClassLoader). j.l.ClassLoader's getResourceAsStream() implementation does not setUseCaches(false), therefore causes locking. I suggest overriding getResourceAsStream in JasperLoader by adding the following (or similar) method: public InputStream getResourceAsStream(String name) { URL url = getResource(name); if (url != null) { try { URLConnection urlc = url.openConnection(); urlc.setUseCaches(false); return urlc.getInputStream(); } catch (IOException e) { return null; } } return null; } This actually *WORKS* for me. It's a hack though. JasperLoader shouldn't have the JARs in its repositories, so it is supposed to delegate. PS. I hope that I don't get cursed again. It's easy: don't be annoying, and avoid whining. For example, what's up with that bug ? http://issues.apache.org/bugzilla/show_bug.cgi?id=32746 Is it relevant or not ? Rmy - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: JDTCompiler and locked jar files *again*
Remy Maucherat [EMAIL PROTECTED] wrote: It's a hack though. JasperLoader shouldn't have the JARs in its repositories, so it is supposed to delegate. It *does* delegate to its parent classloader (which is WebappClassLoader) The only difference is that my solution sets useCaches to false on obtained URLConnection before opening an InputStream. There are no repositories related with JasperLoader. Look: in o.a.j.c.JDTCompiler there is such an invocation in findType(String) is = classLoader.getResourceAsStream(resourceName); classLoader is an instance of JasperLoader, which does not override j.n.URLClassLoader.getResourceAsStream(String) Since there is also no getResourceAsStream in its superclass j.n.URLClasLoader, ClassLoader's implementation getResourceAsStream(String) is used It (java.lang.ClassLoader) is implemented like this: public InputStream getResourceAsStream(String name) { URL url = getResource(name); try { return url != null ? url.openStream() : null; } catch (IOException e) { return null; } } Notice that openStream() is a short for getConnection().getInputStream(). As you can clearly see after applying my hack after an invocation of is = classLoader.getResourceAsStream(resourceName); is is assigned an InputStream opened on an *uncached* JarURLConnection. Te question arises - is there any benefit of having cached JarURLConnection?? I haven't checked that in the sources of jdk as java.net.JarURLConnection is abstract and implemented in sun.net.www.protocol.jar.JarURLConnection. PS. I hope that I don't get cursed again. It's easy: don't be annoying, and avoid whining. I try hard not to be annoying. And I'am not whining - I try to be helpfull. For example, what's up with that bug ? http://issues.apache.org/bugzilla/show_bug.cgi?id=32746 Is it relevant or not ? It is. It is an outcome of my investigation. Fixing it (closing the stream), however, does no good. But I'm pretty sure it is a good habit to cleanup. cheers, /dd - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: JDTCompiler and locked jar files *again*
Dominik Drzewiecki wrote: Remy Maucherat [EMAIL PROTECTED] wrote: It *does* delegate to its parent classloader (which is WebappClassLoader) The only difference is that my solution sets useCaches to false on obtained URLConnection before opening an InputStream. There are no repositories related with JasperLoader. Look: in o.a.j.c.JDTCompiler there is such an invocation in findType(String) is = classLoader.getResourceAsStream(resourceName); classLoader is an instance of JasperLoader, which does not override j.n.URLClassLoader.getResourceAsStream(String) Since there is also no getResourceAsStream in its superclass j.n.URLClasLoader, ClassLoader's implementation getResourceAsStream(String) is used It (java.lang.ClassLoader) is implemented like this: public InputStream getResourceAsStream(String name) { URL url = getResource(name); try { return url != null ? url.openStream() : null; } catch (IOException e) { return null; } } Notice that openStream() is a short for getConnection().getInputStream(). As you can clearly see after applying my hack after an invocation of is = classLoader.getResourceAsStream(resourceName); is is assigned an InputStream opened on an *uncached* JarURLConnection. There are other solutions: - modify findType to use getResource instead of getResourceAsStream - have JasperLoader.getResourceAsSteam (and possibly getResource as well) do nothing and delegate to parent.getResourceAsStream (and getResource) I think I like the second one. I didn't quite realize how this was working with the dependecies. The use of getResource would prevent caching (although the JAR wouldn't need to be found again), while using the parent's getResourceAsStream should speed up compilation a little (since the binary content of the class is only loaded once). Te question arises - is there any benefit of having cached JarURLConnection?? Well, it locks your files, therefore hinting that you should be using Linux or something. Seriously, I don't know the answer to that, but I imagine it could have consequences (the amount of accesses is not insignificant if there are lots of depedencies). I haven't checked that in the sources of jdk as java.net.JarURLConnection is abstract and implemented in sun.net.www.protocol.jar.JarURLConnection. Rmy - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: JDTCompiler and locked jar files *again*
Remy Maucherat [EMAIL PROTECTED] wrote: There are other solutions: - modify findType to use getResource instead of getResourceAsStream - have JasperLoader.getResourceAsSteam (and possibly getResource as well) do nothing and delegate to parent.getResourceAsStream (and getResource) I think I like the second one. So do I as that is exacly what my proposed hack does. There is no need to provide JasperLoader.getResource(String) as the inherited from java.lang.ClassLoader getResource(String) is cool, it already delegates to parent first if there is one. Here it is, as implemented in java.lang.ClassLoader: public URL getResource(String name) { URL url; if (parent != null) { url = parent.getResource(name); } else { url = getBootstrapResource(name); } if (url == null) { url = findResource(name); } return url; } So it is enough to provide only JasperLoader.getResourceAsStream(String) which in turn invokes getResource(String) to obtain URL to requested resource. As there is no implementation of such method provided in JasperLoader, the implementation of ClassLoader is used (which delegates to parent). I hope I made myself clear (I realize that a patch is worth thousand words ;) It's not that hacky after all, is it? cheers, /dd - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: JDTCompiler and locked jar files *again*
Dominik Drzewiecki wrote: Remy Maucherat [EMAIL PROTECTED] wrote: So do I as that is exacly what my proposed hack does. The WCL doesn't do the same thing when you call getResource or getResourceAsStream. Using getResource is less efficient. That's the idea. There is no need to provide JasperLoader.getResource(String) as the inherited from java.lang.ClassLoader getResource(String) is cool, it already delegates to parent first if there is one. Here it is, as implemented in java.lang.ClassLoader: public URL getResource(String name) { URL url; if (parent != null) { url = parent.getResource(name); } else { url = getBootstrapResource(name); } if (url == null) { url = findResource(name); } return url; } So it is enough to provide only JasperLoader.getResourceAsStream(String) which in turn invokes getResource(String) to obtain URL to requested resource. As there is no implementation of such method provided in JasperLoader, the implementation of ClassLoader is used (which delegates to parent). I hope I made myself clear (I realize that a patch is worth thousand words ;) What I plan to commit is add: public InputStream getResourceAsStream(String name) { return parent.getResourceAsStream(name); } and possibly, since we never need to search the internal repositories: public URL getResource(String name) { return parent.getResource(name); } It's not that hacky after all, is it? It might make getResourceAsStream more expensive, that's the problem. (and stop posting your messages multiple times) Rmy - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: JDTCompiler and locked jar files *again*
Remy Maucherat wrote: (and stop posting your messages multiple times) It must have been my webmail agent or mail server or both. Sorry. /dd - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]