Starting Jetty from Restlet in OSGi
I'm using Restlet in OSGi (equinox). I keep encountering a java.io.IOException: The thread blocked at the cyclic barrier has timed out.
exception with the default HTTP server and so am trying to use Jetty instead. From reading various forums and articles, it seems that the correct way to use Jetty is to simply add the appropriate JARs to the classpath and Restlet does the hard work. This doesn't appear to be working :(
My bundle activator's start
method looks as follows:
public void start(BundleContext bundleContext) throws Exception {
List<ConnectorHelper<Server>> servers = Engine.getInstance().getRegisteredServers();
System.out.println("Server connectors - "+servers.size());
for (ConnectorHelper<Server> connectorHelper : servers) {
System.out.println("connector = "+connectorHelper.getClass());
}
component = new Component();
component.getServers().add(Protocol.HTTP, 8182);
final Application app = new MyApplication();
component.getDefaultHost().attachDefault(app);
component.start();
}
Running this prints:
Server connectors - 2
connector = class org.restlet.engine.local.RiapServerHelper
connector = class org.restlet.engine.connector.HttpServerHelper
So it hasn't detected Jetty, which makes me think that the org.restlet.ext.jetty plugin isn't on the classpath. However, within the same method I'm able to access the Jetty helper classes. I've tried programmatically starting Jetty:
Server server = new Server(Protocol.HTTP, 8184, new MyApplication());
JettyServerHelper jetty = new HttpServerHelper(server);
jetty.start();
Which shows that Jetty is on the classpath, and starts Jetty fine, but when I make a request to http://localhost:8184, I get the following exception:
2015-01-28 13:44:57.182:INFO:oejs.Server:jetty-8.1.14.v20131031
2015-01-28 13:44:57.217:INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:8184
Jan 28, 2015 1:45:13 PM org.restlet.Restlet handle
WARNING: Unable to start the Restlet
java.net.BindException: Address already in use
at sun.nio.ch.Net.bind0(Native Method)
at sun.nio.ch.Net.bind(Net.java:444)
at sun.nio.ch.Net.bind(Net.java:436)
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:214)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:67)
at org.restlet.engine.connector.ServerConnectionHelper.createServerSocketChannel(ServerConnectionHelper.java:158)
at org.restlet.engine.connector.ServerConnectionHelper.start(ServerConnectionHelper.java:320)
at org.restlet.Server.start(Server.java:590)
at org.restlet.Restlet.handle(Restlet.java:315)
at org.restlet.Server.handle(Server.java:513)
at org.restlet.engine.ServerHelper.handle(ServerHelper.java:72)
at org.restlet.engine.adapter.HttpServerHelper.handle(HttpServerHelper.java:152)
at org.restlet.ext.jetty.JettyServerHelper$WrappedServer.handle(JettyServerHelper.java:170)
at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:494)
at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:971)
at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:1033)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:644)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)
at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:667)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
at java.lang.Thread.run(Thread.java:744)
Does anyone know what I've configured incorrectly?
Many thanks, Jim
Edit: Included list of running bundles:
id State Bundle
0 ACTIVE org.eclipse.osgi_3.9.1.v20140110-1610
Fragments=156, 157
2 ACTIVE org.eclipse.equinox.common_3.6.200.v20130402-1505
40 RESOLVED org.eclipse.core.runtime.compatibility.registry_3.5.200.v20130514-1256
Master=118
53 ACTIVE org.eclipse.core.runtime.compatibility.auth_3.2.300.v20120523-2004
65 ACTIVE javax.inject_1.0.0.v20091030
95 ACTIVE org.eclipse.core.jobs_3.5.300.v20130429-1813
97 ACTIVE org.eclipse.equinox.app_1.3.100.v20130327-1442
101 ACTIVE org.eclipse.equinox.preferences_3.5.100.v20130422-1538
118 ACTIVE org.eclipse.equinox.registry_3.5.301.v20130717-1549
Fragments=40
119 ACTIVE org.eclipse.osgi.services_3.3.100.v20130513-1956
124 ACTIVE org.eclipse.core.runtime_3.9.100.v20131218-1515
126 ACTIVE javax.xml_1.3.4.v201005080400
127 ACTIVE javax.servlet_3.0.0.v201112011016
130 ACTIVE org.eclipse.core.contenttype_3.4.200.v20130326-1255
134 ACTIVE javax.annotation_1.1.0.v201209060031
156 RESOLVED org.eclipse.equinox.weaving.hook_1.0.200.v20130327-1442
Master=0
157 RESOLVED org.eclipse.equinox.transforms.hook_1.0.401.v20130327-1442
Master=0
160 ACTIVE org.restlet.ext.ssl_2.1.4.v20130907-1635
161 ACTIVE org.restlet.ext.jetty_2.1.4.v20130907-1635
162 ACTIVE jsslutils_1.0.5
163 ACTIVE org.restlet_1.0.0
165 ACTIVE org.restlet.ext.servlet_2.1.4.v20130907-1635
166 ACTIVE org.eclipse.equinox.console_1.0.100.v20130429-0953
167 ACTIVE org.apache.felix.gogo.runtime_0.10.0.v201209301036
169 ACTIVE org.apache.felix.gogo.shell_0.10.0.v201212101605
170 ACTIVE org.eclipse.jetty.http_8.1.14.v20131031
171 ACTIVE org.eclipse.jetty.continuation_8.1.14.v20131031
172 ACTIVE org.eclipse.jetty.servlet_8.1.14.v20131031
173 ACTIVE org.eclipse.jetty.util_8.1.14.v20131031
174 ACTIVE org.eclipse.jetty.security_8.1.14.v20131031
175 ACTIVE org.eclipse.jetty.io_8.1.14.v20131031
176 ACTIVE org.eclipse.jetty.server_8.1.14.v20131031
180 ACTIVE osgi.restlet.jetty.test_1.0.0.qualifier
My bundle is osgi.restlet.jetty.test
Things are a bit tricky regarding connector detection when using Restlet within an OSGi environment. In fact, you need to be sure that you start your Restlet server once the jetty connector was registered against Restlet engine. I see two approaches for that:
Use the start level of your OSGi container to ensure that the bundle that starts the Restlet engine is started after the Restlet bundles ( org.restlet.ext.jetty
and org.restlet
.
Use an OSGi framework event to start the Restlet engine when all bundles are started. A sample of this approach is described below:
public class ServerActivator implements BundleActivator {
public void start(BundleContext bundleContext) throws Exception {
this.context.addFrameworkListener(new FrameworkListener() {
public void frameworkEvent(FrameworkEvent event) {
if (event.getType() == FrameworkEvent.STARTED) {
Component component = new Component();
Server server = new Server(Protocol.HTTP, 8080);
server.setName("Sample Server");
server.setNext(new SampleApplication());
component.getServers().add(server);
component.start();
}
}
});
}
}
Hope it helps. Thierry
链接地址: http://www.djcxy.com/p/74742.html