在 OSGi 中从 Restlet 启动 Jetty

Starting Jetty from Restlet in OSGi

我在 OSGi (equinox) 中使用 Restlet。我一直遇到默认 HTTP 服务器的 java.io.IOException: The thread blocked at the cyclic barrier has timed out. 异常,因此我尝试改用 Jetty。从阅读各种论坛和文章来看,使用 Jetty 的正确方法似乎是简单地将适当的 JAR 添加到类路径中,而 Restlet 会完成这项艰巨的工作。这似乎不起作用:(

我的包激活器的 start 方法如下所示:

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();
}

运行 这会打印:

Server connectors - 2
connector = class org.restlet.engine.local.RiapServerHelper
connector = class org.restlet.engine.connector.HttpServerHelper

所以它没有检测到 Jetty,这让我认为 org.restlet.ext.jetty 插件不在类路径中。但是,在相同的方法中,我能够访问 Jetty 助手 类。我尝试以编程方式启动 Jetty:

    Server server = new Server(Protocol.HTTP, 8184, new MyApplication());
    JettyServerHelper jetty = new HttpServerHelper(server); 
    jetty.start();

这表明 Jetty 在类路径上,并且可以正常启动 Jetty,但是当我向 http://localhost:8184 发出请求时,出现以下异常:

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.run(SelectChannelEndPoint.java:52)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
at org.eclipse.jetty.util.thread.QueuedThreadPool.run(QueuedThreadPool.java:543)
at java.lang.Thread.run(Thread.java:744)

有谁知道我配置有误吗?

非常感谢, 吉姆

编辑:运行 包的包含列表:

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

我的捆绑包是 osgi.restlet.jetty.test

在 OSGi 环境中使用 Restlet 时,关于连接器检测的事情有点棘手。事实上,您需要确保在 Jetty 连接器针对 Restlet 引擎注册后启动您的 Restlet 服务器。我看到了两种方法:

  • 使用您的 OSGi 容器的启动级别来确保启动 Restlet 引擎的包在 Restlet 包(org.restlet.ext.jettyorg.restlet.

  • 在所有包启动时使用 OSGi 框架事件启动 Restlet 引擎。下面描述了这种方法的示例:

    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();
                    }
                }
            });
        }
    }
    

希望对您有所帮助。 蒂埃里