| Summary: | Make loading of system resources more OSGi-friendly | ||
|---|---|---|---|
| Product: | [RT] Jetty | Reporter: | Benjamin Bentmann <bentmann> |
| Component: | server | Assignee: | Hugues Malphettes <hmalphettes> |
| Status: | CLOSED WONTFIX | QA Contact: | |
| Severity: | normal | ||
| Priority: | P3 | CC: | bentmann, gregw, janb, jetty-inbox |
| Version: | 7.3.0 | ||
| Target Milestone: | 7.2.x | ||
| Hardware: | All | ||
| OS: | All | ||
| Whiteboard: | |||
hughes, can you give me your considered opinion on this issue. I'm open to the suggestion of changing newSystemResource, but I wonder why you have not hit this problem with your OSGi work? I am probably missing the complete testcase: according to the stack trace the jetty server is started without using org.eclipse.jetty.osgi.boot We have solved this type of issues inside org.eclipse.jetty.osgi.boot Could you attach the jetty.xml file you use to configure your application and maybe some more pieces to be able to reproduce the issue? (In reply to comment #2) > according to the stack trace the > jetty server is started without using org.eclipse.jetty.osgi.boot This is correct. My plugin's manifest had Require-Bundle: org.eclipse.jetty.server, [other-jetty-bundles] and tried to fire up the server programmatically, much like as described in http://wiki.eclipse.org/Jetty/Tutorial/Embedding_Jetty but with Cargo's Jetty7xEmbeddedLocalContainer doing the actual calls to start the server. > We have solved this type of issues inside org.eclipse.jetty.osgi.boot Should this be mentioned in the above mentioned tutorial? > Could you attach the jetty.xml file you use to configure your application and > maybe some more pieces to be able to reproduce the issue? There is no jetty.xml and no local install of the server, it was all programmatically setup. I won't be able to provide a complete show case as I dropped the original approach to embed Jetty and start the server outside OSGi now. (In reply to comment #3) > (In reply to comment #2) > > according to the stack trace the > > jetty server is started without using org.eclipse.jetty.osgi.boot > > This is correct. My plugin's manifest had > Require-Bundle: org.eclipse.jetty.server, [other-jetty-bundles] > and tried to fire up the server programmatically, much like as described in > http://wiki.eclipse.org/Jetty/Tutorial/Embedding_Jetty but with Cargo's > Jetty7xEmbeddedLocalContainer doing the actual calls to start the server. > > > We have solved this type of issues inside org.eclipse.jetty.osgi.boot > > Should this be mentioned in the above mentioned tutorial? Thanks a lot for explaining the user-case. I must confess I had not read that tutorial before. That part of jetty is not ready for OSGi. There is some work related to this in bug #309250; to manage multiple instances of jetty in the same equinox and to be able to programatically create the jetty server. Reading the tutorial, we would need to make some APIs of org.eclipse.jetty.osgi.boot public to support the type of example above: in particular the setup of the WebAppContext is quite different in OSGi. > > > Could you attach the jetty.xml file you use to configure your application and > > maybe some more pieces to be able to reproduce the issue? > > There is no jetty.xml and no local install of the server, it was all > programmatically setup. I won't be able to provide a complete show case as I > dropped the original approach to embed Jetty and start the server outside OSGi > now. OK. We will prepare for the opportunity to support this in OSGi. The jetty-osgi API has changed significantly since this issue was raised. It is possible to use the classes in the jetty-osgi-boot jar to provide a classloader for the webapp that will allow it to resolve the webdefaults.xml file from the jetty-webapp jar. Look at the OSGIWebAppClassLoader, ServerInstanceWrapper, LibExtClassLoader and FakeURLClassLoader classes for how to construct the classloader for the webapp. Jan |
Background: I was trying to fire up an embedded Jetty 7.3.0 container via Cargo 1.0.6 within some Eclipse plugin. The required Jetty libs are brought into action by adding the Jetty p2 repo to the target platform and having my Eclipse plugin's manifest give the corresponding Require-Bundle header. Mostly using default settings for a web app, I ended up with the following exception while trying to deploy the webapp to the Jetty container: java.io.FileNotFoundException: D:\eclipse\3.7\org\eclipse\jetty\webapp\webdefault.xml (Das System kann den angegebenen Pfad nicht finden) at java.io.FileInputStream.open(Native Method) ~[na:1.5.0_22] at java.io.FileInputStream.<init>(FileInputStream.java:106) ~[na:1.5.0_22] at java.io.FileInputStream.<init>(FileInputStream.java:66) ~[na:1.5.0_22] at sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:70) ~[na:1.5.0_22] at sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:161) ~[na:1.5.0_22] at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:973) ~[na:1.5.0_22] at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(XMLVersionDetector.java:184) ~[na:1.5.0_22] at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:798) ~[na:1.5.0_22] at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:764) ~[na:1.5.0_22] at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:148) ~[na:1.5.0_22] at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1242) ~[na:1.5.0_22] at javax.xml.parsers.SAXParser.parse(SAXParser.java:375) ~[na:1.5.0_22] at org.eclipse.jetty.xml.XmlParser.parse(XmlParser.java:187) ~[na:na] at org.eclipse.jetty.xml.XmlParser.parse(XmlParser.java:203) ~[na:na] at org.eclipse.jetty.webapp.Descriptor.parse(Descriptor.java:60) ~[na:na] at org.eclipse.jetty.webapp.WebDescriptor.parse(WebDescriptor.java:142) ~[na:na] at org.eclipse.jetty.webapp.MetaData.setDefaults(MetaData.java:142) ~[na:na] at org.eclipse.jetty.webapp.WebXmlConfiguration.preConfigure(WebXmlConfiguration.java:46) ~[na:na] at org.eclipse.jetty.webapp.WebAppContext.preConfigure(WebAppContext.java:406) ~[na:na] at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:435) ~[na:na] at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55) [org.eclipse.jetty.util_7.3.0.v20110203.jar:7.3.0.v20110203] at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:226) [org.eclipse.jetty.server_7.3.0.v20110203.jar:7.3.0.v20110203] at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:164) [org.eclipse.jetty.server_7.3.0.v20110203.jar:7.3.0.v20110203] at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55) [org.eclipse.jetty.util_7.3.0.v20110203.jar:7.3.0.v20110203] at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:226) [org.eclipse.jetty.server_7.3.0.v20110203.jar:7.3.0.v20110203] at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55) [org.eclipse.jetty.util_7.3.0.v20110203.jar:7.3.0.v20110203] at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:95) [org.eclipse.jetty.server_7.3.0.v20110203.jar:7.3.0.v20110203] at org.eclipse.jetty.server.Server.doStart(Server.java:258) [org.eclipse.jetty.server_7.3.0.v20110203.jar:7.3.0.v20110203] at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55) [org.eclipse.jetty.util_7.3.0.v20110203.jar:7.3.0.v20110203] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.5.0_22] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~[na:1.5.0_22] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[na:1.5.0_22] at java.lang.reflect.Method.invoke(Method.java:592) ~[na:1.5.0_22] at org.codehaus.cargo.container.jetty.internal.JettyExecutorThread.run(JettyExecutorThread.java:69) [cargo-core-uberjar-1.0.6.jar:1.0.6] Another helpful/related stack trace from the container a few instructions before the exception: org.eclipse.jetty.util.resource.Resource.newSystemResource(java.lang.String) line: 212 org.eclipse.jetty.webapp.WebXmlConfiguration.preConfigure(org.eclipse.jetty.webapp.WebAppContext) line: 43 org.eclipse.jetty.webapp.WebAppContext.preConfigure() line: 406 org.eclipse.jetty.webapp.WebAppContext.doStart() line: 435 org.eclipse.jetty.webapp.WebAppContext(org.eclipse.jetty.util.component.AbstractLifeCycle).start() line: 55 org.eclipse.jetty.server.handler.ContextHandlerCollection(org.eclipse.jetty.server.handler.HandlerCollection).doStart() line: 226 org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart() line: 164 org.eclipse.jetty.server.handler.ContextHandlerCollection(org.eclipse.jetty.util.component.AbstractLifeCycle).start() line: 55 org.eclipse.jetty.server.handler.HandlerCollection.doStart() line: 226 org.eclipse.jetty.server.handler.HandlerCollection(org.eclipse.jetty.util.component.AbstractLifeCycle).start() line: 55 org.eclipse.jetty.server.Server(org.eclipse.jetty.server.handler.HandlerWrapper).doStart() line: 95 org.eclipse.jetty.server.Server.doStart() line: 258 org.eclipse.jetty.server.Server(org.eclipse.jetty.util.component.AbstractLifeCycle).start() line: 55 sun.reflect.NativeMethodAccessorImpl.invoke0(java.lang.reflect.Method, java.lang.Object, java.lang.Object[]) line: not available [native method] sun.reflect.NativeMethodAccessorImpl.invoke(java.lang.Object, java.lang.Object[]) line: 39 sun.reflect.DelegatingMethodAccessorImpl.invoke(java.lang.Object, java.lang.Object[]) line: 25 java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object...) line: 592 org.codehaus.cargo.container.jetty.internal.JettyExecutorThread.run() line: 69 What happens is that WebXmlConfiguration.preConfigure() calls Resource.newSystemResource("org/eclipse/jetty/webapp/webdefault.xml"). newSystemResource() queries the TCCL and next the loader of the Resource class for the resource. In my setting, the TCCL (which I can't control) effectively resolves to the bundle loader of org.eclipse.jetty.util (as per Eclipse's ContextFinder logic) which also is the loader of o.e.j.u.r.Resource. However, the resource in question is actually contained in the org.eclipse.jetty.webapp bundle whose contents is not visible to the org.eclipse.jetty.util loader. In a nutshell, the class loader of o.e.j.u.r.Resource does not see all of the Jetty classes/resources when using Jetty as OSGi bundles which can easily make loading of "system" resources fail. As a potential solution, I could think of extending Resource.newSystemResource() to additionally take a class loader as input which would be queried as well. So basically, WebXmlConfiguration.preConfigure() could call Resource.newSystemResource( ..., WebXmlConfiguration.class.getClassLoader() ), i.e. thereby providing access to the class loader which actually contains the system resource.