| Summary: | Bundles do not fully express their dependencies | ||
|---|---|---|---|
| Product: | [RT] Jetty | Reporter: | Rüdiger Herrmann <ruediger.herrmann> |
| Component: | osgi | Assignee: | Hugues Malphettes <hmalphettes> |
| Status: | CLOSED INVALID | QA Contact: | |
| Severity: | normal | ||
| Priority: | P3 | CC: | jetty-inbox, ruediger.herrmann |
| Version: | unspecified | ||
| Target Milestone: | --- | ||
| Hardware: | All | ||
| OS: | All | ||
| Whiteboard: | |||
|
Description
Rüdiger Herrmann
Hi Rudiger, Here are the extra 4 import-package that you have identified: jetty.security jetty.servlet jetty.webapp jetty.xml However org.eclipse.jetty.server does not depend on those packages. We can't depend on those without introducing cyclic dependencies: at the moment I am convinced that we must not add those import. The bundle inside which you are creating the Server object programatically is in charge of setting up the jettty server with a classloader where packages needed for this particular configuratio are available. When you create the Server object, you will need to set the context classloader to the classloader of the bundle that has access to each one of those packages. This is the approach taken by the org.eclispe.jetty.osgi.boot I don't mind guiding you but I would prefer if you could define what API you are expecting. I can add it to jetty rather than have everyone re-invent how to configure jetty in OSGi. As an alternative you could use the eclipse aggregate: http://repo1.maven.org/maven2/org/eclipse/jetty/aggregate/jetty-all-server/7.4.0.v20110414/ All the jars are put together and there is no classloading issues. Note that there are many other challenges to run jetty in an OSGi environment nicely; in aprticular webapps and web-bundles. If you let us know what you want to do I can help you. Hi Hugues, thanks for your detailed reply. (In reply to comment #1) > Hi Rudiger, > Here are the extra 4 import-package that you have identified: > jetty.security > jetty.servlet > jetty.webapp > jetty.xml > > However org.eclipse.jetty.server does not depend on those packages. > We can't depend on those without introducing cyclic dependencies: at the moment > I am convinced that we must not add those import. Why would you break up something into bundles if they cannot function on their own anyway? If these packages are coupled in such a way, did you consider putting them into one single bundle? > > The bundle inside which you are creating the Server object programatically is in > charge of setting up the jettty server with a classloader where packages needed > for this particular configuratio are available. > When you create the Server object, you will need to set the context classloader > to the classloader of the bundle that has access to each one of those packages. I think, my initial description wasn't precise enough, sorry for that. There was no ClassNotFoundException, instead there were NoClassDefFoundError like the one below: java.lang.NoClassDefFoundError: org/eclipse/jetty/http/HttpBuffers The error occurs during server start, application classes aren't involved yet from what I can tell. What is wrong here is that there are no compiler errors (unresolved dependencies). Before running the thing everything looks good. At runtime though, NoClassDefFoundErrors occur because the dependencies among Jetty bundles aren't fully expressed in the MANIFESTs. If you whish so I can set up a small project to demonstrate what I mean. > > This is the approach taken by the org.eclispe.jetty.osgi.boot > I don't mind guiding you but I would prefer if you could define what API you are > expecting. I can add it to jetty rather than have everyone re-invent how to > configure jetty in OSGi. > > As an alternative you could use the eclipse aggregate: > http://repo1.maven.org/maven2/org/eclipse/jetty/aggregate/jetty-all-server/7.4.0.v20110414/ > All the jars are put together and there is no classloading issues. > > Note that there are many other challenges to run jetty in an OSGi environment > nicely; in aprticular webapps and web-bundles. > If you let us know what you want to do I can help you. Currently I am only consuming bundles to have the comfort of PDE taking care of the class path. At runtime, no SGOi is involved, the application (JUnit tests) runs as a plain Java application. The background is that I am using Jetty to set up a cluster failover scenario that can be controlled via unit tests. With the help of some utility classes (Fixture), I can start two or more embedded jetty servers, have them form a cluster with the help of a JDBCSessionManager that is backed by an also embedded databse. With this utilities, it is very comfortable to write unit tests that issue a couple of requests (simulating a session failover) and later examine the state of the migrated session. All this is done in an effort to enable RAP:"http://eclipse.org/rap" for transparent session failover (see bug 341761 if you are interesed in the gory details). (In reply to comment #2) > Hi Hugues, > thanks for your detailed reply. > ... > > > > However org.eclipse.jetty.server does not depend on those packages. > > We can't depend on those without introducing cyclic dependencies: at the moment > > I am convinced that we must not add those import. > Why would you break up something into bundles if they cannot function on their > own anyway? If these packages are coupled in such a way, did you consider > putting them into one single bundle? > Well honestly I did not come up with this break-up :) I came in after the fact and developped a way to make jetty execute cleanly in OSGi. At the moment many of the jetty APIs cannot be called in OSGi without further precautions. For sure jetty.server does not depend on jetty.security. A smaller distribution of jetty would certainly work without jaspi support. For sure jetty.server does not depend on the jetty.xml. Another example would be why org.eclipse.jetty.server does not import the jetty.webapps and jetty.servlets packages: anyone who works with webapps would assume that it does. In the case of RAP those dependnecies are not needed: you only need jetty.servlet and the equinox httpservice. We could have chosen to add a lot of optional imports or even a Dynamic-ImportPackage: org.eclipse.jetty.* Instead we are using th same technique than in J2EE: set the current context classloader during the configuration of the server in order to enable the class resolutions. We could go one step further and use OSGi services to wire things together rather than the context classloader. But at the moment org.eclipse.jetty.server does not depend on osgi at all. > > > > The bundle inside which you are creating the Server object programatically is in > > charge of setting up the jettty server with a classloader where packages needed > > for this particular configuratio are available. > > When you create the Server object, you will need to set the context classloader > > to the classloader of the bundle that has access to each one of those packages. > I think, my initial description wasn't precise enough, sorry for that. There > was no ClassNotFoundException, instead there were NoClassDefFoundError like the > one below: > java.lang.NoClassDefFoundError: org/eclipse/jetty/http/HttpBuffers > The error occurs during server start, application classes aren't involved yet > from what I can tell. What is wrong here is that there are no compiler errors > (unresolved dependencies). Before running the thing everything looks good. At > runtime though, NoClassDefFoundErrors occur because the dependencies among > Jetty bundles aren't fully expressed in the MANIFESTs. > If you whish so I can set up a small project to demonstrate what I mean. > > > > > This is the approach taken by the org.eclispe.jetty.osgi.boot > > I don't mind guiding you but I would prefer if you could define what API you are > > expecting. I can add it to jetty rather than have everyone re-invent how to > > configure jetty in OSGi. > > > > As an alternative you could use the eclipse aggregate: > > http://repo1.maven.org/maven2/org/eclipse/jetty/aggregate/jetty-all-server/7.4.0.v20110414/ > > All the jars are put together and there is no classloading issues. > > > > Note that there are many other challenges to run jetty in an OSGi environment > > nicely; in particular webapps and web-bundles. > > If you let us know what you want to do I can help you. > Currently I am only consuming bundles to have the comfort of PDE taking care of > the class path. At runtime, no OSGi is involved, the application (JUnit tests) > runs as a plain Java application. > > The background is that I am using Jetty to set up a cluster failover scenario > that can be controlled via unit tests. With the help of some utility classes > (Fixture), I can start two or more embedded jetty servers, have them form a > cluster with the help of a JDBCSessionManager that is backed by an also > embedded databse. With this utilities, it is very comfortable to write unit > tests that issue a couple of requests (simulating a session failover) and later > examine the state of the migrated session. > All this is done in an effort to enable RAP:"http://eclipse.org/rap" for > transparent session failover (see bug 341761 if you are interesed in the gory > details). OK thanks for the explanation. So if I understood correctly you are setting up some jetty servers during the testunits that will start the servletbridge. You want to be able to start those jetty servers both from OSGi during development and from J2EE during automated testing. I am quite convinced that the bundle from which you create and start the jetty servers must do all the jetty imports or even a Dynamic-ImportPackage: org.eclipse.jetty.* Then use the same type of code than what we do in org.eclipse.jetty.osgi.boot: http://download.eclipse.org/jetty/7.4.1.v20110513/xref/org/eclipse/jetty/osgi/boot/internal/serverfactory/ServerInstanceWrapper.html#146 Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()) This code won't hurt in j2ee and it will make it work in OSGi. If we can share your projects and your target platform, I would be happy to try it out. Please reopen if needed. |