Community
Participate
Working Groups
Currently it seems not possible to use Jetty in OSGi when session failover is enabled. We have Jetty embedded and configured to use JDBCSessionIdManager and JDBCSessionManager. In the case of a fail-over, when a session is deserialized, a ClassNotFoundException occurs. As far as we understand, this is caused by the ClassLoadingInputStream that uses Class.forName with contextClassLoader to load classes. Though in therory it would be possible to set a contextClassLoader, we don't see a place where to actually set an OSGi-aware class loader. Under the above assunptions, we suggest to allow to set a custom class loader on the servlet context, that is used whenever a session that belongs to the context is deserialized. Application code (or framework code in our case) could call: servletContext.setAttribute( "org.eclipse.jetty.serialization.classLoader", new CustomClassLoader() ); when the context is initialized (note: the attribute name is just a suggestion). The ClassLoadingObjectInputStream would then use the above set CustomClassLoader to load classs during deserialization.
Hi there, Jan tells me that the classloading uses this piece of java code: return Class.forName(cl.getName(), false, Thread.currentThread().getContextClassLoader()); Where the thread's context classloader is the webapp's classloader. It should behave as expected. Could you share the stack trace and a way for us to reproduce the issue?
Hi Ruediger, Can you paste the full stack trace? Also, is this jetty-7 or jetty-8? Which release number? This is a bit surprising to me, as I understood that our OSGi code will provide a special, osgi-aware classloader to each webapp that is deployed. Thus, when the Session is being re-inflated over on a new node, the context classloader should already be set to this this special osgi-aware classloader, and thus able to resolve the class reference. Perhaps seeing the stack trace will make this clearer to me. thanks Jan
(In reply to comment #2) > Also, is this jetty-7 or jetty-8? Which release number? I am working with Jetty 8.0.2.SNAPSHOT from ~ 2011-10-14. > This is a bit surprising to me, as I understood that our OSGi code will provide > a special, osgi-aware classloader to each webapp that is deployed. Thus, when > the Session is being re-inflated over on a new node, the context classloader > should already be set to this this special osgi-aware classloader, and thus > able to resolve the class reference. Perhaps seeing the stack trace will make > this clearer to me. I am sorry that I didn't realize that there is an OSGi integration for Jetty. I though the jetty.osgi.* just contained the HttpService. So my situation has changed: I am now going along the Jetty/OSGi doc [1] and try to register an instance of class Server as an OSGi service and then a ContextHandler. When the Server is registered, I get an IllegalStateException: ERROR: No ContextHandlerCollection or OSGiAppProvider configured. I am unsure whether I really need both, a ContextHandlerCollection *and* an OSGiAppProvider. The code reads like 'yes I need both', the exception message says rather 'either or'. Please note, I don't want to deploy a WAR or such. I want to programmatically start a server, create a context, register a servlet and then send some requests to that servlet. Please let me know if I should use another place (new bug, mailing list) to solve the changed issue. [1] http://wiki.eclipse.org/Jetty/Feature/Jetty_OSGi
Created attachment 205446 [details] Stacktrace Stacktrace of exception from comment #3
Hi Rüdiger, in order for a jetty server to be able to deploy web-apps it needs to be configured with an app provider. For OSGi web bundles it needs an OSGiAppProvider. Usually we use an xml file to configure a jetty server. For example here is such a config file for OSGi: http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree/jetty-osgi/jetty-osgi-boot/jettyhome/etc/jetty-osgi-default.xml In such a file, you can configure the session manager etc. Once such a jetty server is configured in this manner, the jetty.osgi.boot bundle will take care of listening for new web-bundles and have them plugged in the OSGiAppProvider (maybe that is where we could take care of the lazy activation of jetty.osgi.boot with one extra parameter on the OSGiAppProvider to decide to activate or not the bundle). If you are in the situation where you have a single jetty instance on your equinox and you are happy with a custom jetty.xml config file you could consider starting it in this manner: - choose if you want to have your jetty.xml inside a bundle or in a separate folder. - Setup the appropriate system property -Djetty.home.bundle=id.of.your.bundle inside it, have a /etc/jetty.xml file or if in a folder: -Djetty.home=path/to/jettyhome such that path/to/jettyhome/etc/jetty.xml exists. - activate jetty.osgi.boot In fact I stumbled on a blog that describes something eerily similar to your situation as far as I understand it: http://eclipsesource.com/blogs/2011/08/12/how-to-build-a-cluster-with-jetty-osgi/ Let me know.
(In reply to comment #5) > In fact I stumbled on a blog that describes something eerily similar to your > situation as far as I understand it: > http://eclipsesource.com/blogs/2011/08/12/how-to-build-a-cluster-with-jetty-osgi/ Hum I must be missing something you guys are already collaborating on github! Thanks for sharing with this blog post and the github project by the way. My understanding is that you would like to have the same project work on jetty-8? Let me know if I can help. Correct me if it is a different situation.
Hi Hugues, let me give you some context. Though the blog is from a colleague of mine, it is not directly related to the work I am doing. We have a JUnit test suite for integrations tests of RAP. These tests ensure e.g. that session failover works. With these tests we developed helper classes to start an embedded Jetty server, deploy a web app and after test code was executed stop and clean up the server. The server runs in the same VM as the tests. All setup is done programmatically, the web app that is deployed is not WAR'ed or anything. Instead of having a web.xml we set up the web app programmatically. See JettyEngine [1] and JettyController [2] in case you want more details. To test failover cluster scenarios, we can use the helper classes to create two or more server instances and have them form a cluster. So far there is no OSGi involved. Since RAP runs on OSGi, the next logical step was to enable failover clustering on RAP in OSGi. Therefore we need to extend helper classes. The goal is to do the same as before (start server, deploy web app, stop server) while running on OSGi. Our first approach was to just run the tests in OSGi. This brought us (via bug 358263) here, to the initial desription of the bug. But just then we noticed that Jetty comes with org.eclipse.jetty.osgi.boot to integrate into OSGi. Now we are seeking advice which path to follow. option a) leave aside the Jetty/OSGi integration This leads to the problem described here initially (and more problems down the path?) option b) use the Jetty/OSGi integration. We went this path up to the missing OSGiAppProvider (comment #3). We use the same helper classes from the non-OSGi tests to create and configure a Server. When registering this instance as a service, we hit the "no app provider" exception (comment #4). As far as I understand, the context file configures the server. The server instance that we register is already fully configured. Would it be worth trying to supply an OSGiAppProvider with an empty context file? After the server is registered successfully, the next step would be to register a ServletContextHandler as described here [3]. [1] http://dev.eclipse.org/viewcvs/viewvc.cgi/org.eclipse.rap/runtime.rwt.test/org.eclipse.rap.rwt.cluster.testfixture/src/org/eclipse/rap/rwt/cluster/testfixture/internal/jetty/JettyEngine.java?view=markup&root=RT_Project [2] http://dev.eclipse.org/viewcvs/viewvc.cgi/org.eclipse.rap/runtime.rwt.test/org.eclipse.rap.rwt.cluster.testfixture/src/org/eclipse/rap/rwt/cluster/testfixture/internal/jetty/JettyController.java?root=RT_Project&view=log [3] http://wiki.eclipse.org/Jetty/Feature/Jetty_OSGi#The_OSGi_service_.27org.eclipse.jetty.server.handler.ContextHandler.27
I forgot to mention that this issue is about Jetty 8.
For your reference, we think this issues is related to bug 361554. As opposed to programmatically embedding Jetty as desribed here, bug 361554 points out that also a ClassNotFoundException occurs when using Jetty/OSGi as a standalone server in a cluster.
Hi Rüdiger, I think since you opened bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=361554 this bug report is closeable. As you point out in the other bug, this bug report seems to discuss a number of different things, and there's nothing that I can clearly address as a bug. I will close this issue for now (leaving 361554 open), but please reopen with a clear statement of the problem if you feel there is something here for me to address. regards Jan