質問

If I'm trying to run a Restlet in the embedded Jetty with the JettyHelper with HTTPS. The Restlet is start with Jetty if I run the jar and listening on the Port 443. But on the first Request I'm getting a Bind Exception from Jetty but everything is working well:

INFO   | jvm 1    | 2013/08/05 07:35:43 | 2013-08-05 07:35:43.720:INFO:oejs.Server:jetty-7.6.5.v20120716
INFO   | jvm 1    | 2013/08/05 07:35:43 | 2013-08-05 07:35:43.813:INFO:oejs.AbstractConnector:Started SslSelectChannelConnector@0.0.0.0:443
INFO   | jvm 1    | 2013/08/05 07:35:43 | 2013-08-05 07:35:43.814:INFO:oejs.Server:jetty-7.6.5.v20120716
INFO   | jvm 1    | 2013/08/05 07:35:43 | 2013-08-05 07:35:43.820:INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:8182
INFO   | jvm 1    | 2013/08/05 07:36:35 | 2013-08-05 07:36:35.730:INFO:oejs.Server:jetty-7.6.5.v20120716
INFO   | jvm 1    | 2013/08/05 07:36:35 | 2013-08-05 07:36:35.733:WARN:oejuc.AbstractLifeCycle:FAILED SslSelectChannelConnector@0.0.0.0:443: java.net.BindException: Die Adresse wird bereits verwendet
INFO   | jvm 1    | 2013/08/05 07:36:35 | java.net.BindException: Die Adresse wird bereits verwendet
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at sun.nio.ch.Net.bind0(Native Method)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at sun.nio.ch.Net.bind(Net.java:444)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at sun.nio.ch.Net.bind(Net.java:436)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:214)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.server.nio.SelectChannelConnector.open(SelectChannelConnector.java:182)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.server.AbstractConnector.doStart(AbstractConnector.java:311)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.server.nio.SelectChannelConnector.doStart(SelectChannelConnector.java:260)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.server.ssl.SslSelectChannelConnector.doStart(SslSelectChannelConnector.java:626)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.server.Server.doStart(Server.java:281)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.restlet.ext.jetty.JettyServerHelper.start(JettyServerHelper.java:398)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.restlet.Server.start(Server.java:590)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.restlet.Restlet.handle(Restlet.java:315)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.restlet.Server.handle(Server.java:513)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.restlet.engine.ServerHelper.handle(ServerHelper.java:72)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.restlet.engine.adapter.HttpServerHelper.handle(HttpServerHelper.java:152)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.restlet.ext.jetty.JettyServerHelper$WrappedServer.handle(JettyServerHelper.java:170)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:452)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:884)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:938)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:630)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:230)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:77)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.io.nio.SslConnection.handle(SslConnection.java:191)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:622)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:46)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:603)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:538)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at java.lang.Thread.run(Thread.java:724)
INFO   | jvm 1    | 2013/08/05 07:36:35 | 2013-08-05 07:36:35.735:WARN:oejuc.AbstractLifeCycle:FAILED org.restlet.ext.jetty.JettyServerHelper$WrappedServer@60ce274e: java.net.BindException: Die Adresse wird bereits verwendet
INFO   | jvm 1    | 2013/08/05 07:36:35 | java.net.BindException: Die Adresse wird bereits verwendet
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at sun.nio.ch.Net.bind0(Native Method)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at sun.nio.ch.Net.bind(Net.java:444)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at sun.nio.ch.Net.bind(Net.java:436)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:214)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.server.nio.SelectChannelConnector.open(SelectChannelConnector.java:182)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.server.AbstractConnector.doStart(AbstractConnector.java:311)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.server.nio.SelectChannelConnector.doStart(SelectChannelConnector.java:260)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.server.ssl.SslSelectChannelConnector.doStart(SslSelectChannelConnector.java:626)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.server.Server.doStart(Server.java:281)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.restlet.ext.jetty.JettyServerHelper.start(JettyServerHelper.java:398)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.restlet.Server.start(Server.java:590)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.restlet.Restlet.handle(Restlet.java:315)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.restlet.Server.handle(Server.java:513)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.restlet.engine.ServerHelper.handle(ServerHelper.java:72)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.restlet.engine.adapter.HttpServerHelper.handle(HttpServerHelper.java:152)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.restlet.ext.jetty.JettyServerHelper$WrappedServer.handle(JettyServerHelper.java:170)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:452)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:884)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:938)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:630)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:230)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:77)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.io.nio.SslConnection.handle(SslConnection.java:191)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:622)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:46)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:603)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:538)
INFO   | jvm 1    | 2013/08/05 07:36:35 |   at java.lang.Thread.run(Thread.java:724)

Why is Jetty trying to start twice? And how can I get ride of this exception?

Source Code:

import java.security.KeyStore;

import org.restlet.Application;
import org.restlet.Component;
import org.restlet.Context;
import org.restlet.Restlet;
import org.restlet.Server;
import org.restlet.data.Parameter;
import org.restlet.data.Protocol;
import org.restlet.engine.Engine;
import org.restlet.ext.jetty.HttpServerHelper;
import org.restlet.ext.jetty.HttpsServerHelper;
import org.restlet.routing.Router;
import org.restlet.util.Series;

public class RestServer extends Application {


    private RestServer(Context context) {
        super(context);     
    }

    public static void main(String[] args) throws Exception {  

        Engine.setLogLevel(java.util.logging.Level.INFO);

        Component component = new Component();  

        component.getLogService().setLoggerName("net.asdf.WebComponent.www");

        Context context = component.getContext().createChildContext();
        component.getDefaultHost().attach(new RestServer(context));


        startHttpsServer(context, component, 443).start();
        startHttpServer(context, component, 8182).start(); 

    } 

    private static HttpServerHelper startHttpServer(Context context, Component component, Integer port) throws Exception {
        //create embedding http jetty server
        Server embedingHttpJettyServer=new Server(
                context,
                Protocol.HTTP,
                port,
                component
            );
        //construct and start JettyServerHelper
        HttpServerHelper jettyHttpServerHelper=new HttpServerHelper(embedingHttpJettyServer);
        return jettyHttpServerHelper;
    }

    private static HttpsServerHelper startHttpsServer(Context context, Component component, Integer port) throws Exception {
        //create embedding https jetty server
        final Server embedingHttpsJettyServer=new Server(
                context,
                Protocol.HTTPS,
                port, // 8183,
                component
            );

        Series<Parameter> parameters = embedingHttpsJettyServer.getContext().getParameters();
        // parameters.add("sslContextFactory", "org.restlet.ext.ssl.PkixSslContextFactory");
        // parameters.add("sslContextFactory", "org.eclipse.jetty.http.ssl.SslContextFactory");
        parameters.add("keystore", "jks/keystore.jks");
        parameters.add("keyStorePath", "jks/keystore.jks");
        parameters.add("keyStorePassword", "xxxxx");
        parameters.add("keyManagerPassword", "xxxx");
        parameters.add("keyPassword", "xxxx");
        parameters.add("password", "xxx");
        parameters.add("keyStoreType", KeyStore.getDefaultType());
        parameters.add("tracing", "true");
        parameters.add("truststore", "jks/keystore.jks"); 
        parameters.add("trustStorePath", "jks/keystore.jks"); 
        parameters.add("trustStorePassword", "xxxxx");
        parameters.add("trustPassword", "xxxxx"); 
        parameters.add("trustStoreType", KeyStore.getDefaultType()); 
        parameters.add("allowRenegotiate", "true");
        parameters.add("type", "1");
        //construct and start JettyServerHelper
        HttpsServerHelper jettyHttpsServerHelper = new HttpsServerHelper(embedingHttpsJettyServer);
        return jettyHttpsServerHelper;

    }


    /**
     * Creates a root Restlet that will receive all incoming calls.
     */
    @Override
    public Restlet createInboundRoot() {
        // Create a router Restlet that routes each call to a
        Context routerContext = getContext().createChildContext();
        Router router = new Router(routerContext);
        router.attachDefault(DefaultResource.class);
        return router;
    }
}
役に立ちましたか?

解決

I've updated the "main", "startHttpServer" and "startHttpsServer" methods in order to make the code work:

public static void main(String[] args) throws Exception {
    Engine.setLogLevel(java.util.logging.Level.INFO);
    Component component = new Component();
    component.getLogService().setLoggerName("net.asdf.WebComponent.www");
    component.getDefaultHost().attach(new TestPatrick());

    // Attach the server connectors descriptors to the component
    component.getServers().add(startHttpsServer(component, 443));
    component.getServers().add(startHttpServer(component, 8182));
    // Start the component, which will lead to start, at the end, the real connectors.
    component.start();
}

private static Server startHttpServer(Component component, Integer port) throws Exception {
    return new Server(Protocol.HTTP, port, component);
}

private static Server startHttpsServer(Component component, Integer port) throws Exception {
    // create embedding https jetty server
    Server server = new Server(new Context(), Protocol.HTTPS, port, component);

    Series<Parameter> parameters = server.getContext().getParameters();
    parameters.add("keystore", "jks/keystore.jks");
    parameters.add("keyStorePath", "jks/keystore.jks");
    parameters.add("keyStorePassword", "xxx");
    parameters.add("keyManagerPassword", "xxx");
    parameters.add("keyPassword", "xxx");
    parameters.add("password", "xxx");
    parameters.add("keyStoreType", KeyStore.getDefaultType());
    parameters.add("tracing", "true");
    parameters.add("truststore", "jks/keystore.jks");
    parameters.add("trustStorePath", "jks/keystore.jks");
    parameters.add("trustStorePassword", "xxx");
    parameters.add("trustPassword", "xxx");
    parameters.add("trustStoreType", KeyStore.getDefaultType());
    parameters.add("allowRenegotiate", "true");
    parameters.add("type", "1");

    return server;
}

Here are some explanations. The Component is a container for applications, it aims at providing some services to these applications. For example, it provides server connectors, that help applications to be reached via client requests using several protocols. The Restlet framework furnishes several implementations of server connectors; one is internal, the others are based on a specific framework such as Jetty. As we do not want your code to be dependent on a specific extension, the philosophy it to let the Component declare its required server connectors using the Server class, which acts as a descriptor. Then, the Engine discovers the implementations located in the classpath, and transparently creates the real server helpers.

I hope my explanations are clear. If not, please feel free to ask for more.

他のヒント

Your question: Why is Jetty trying to start twice? And how can I get ride of this exception?

Answering your question after four years make me feel like I am a Nut Job, but here we go. I am realy answering for the others.

The reason why the Jetty server get started twice (not quite correct) is that the Jetty helper detected that there wan't any server running so it start a new instance. The reason the helper does not know about the instance is because you called:

startHttpServer(context, component, 8182).start();  

The helper.start() method does not set the Restlet.start flag and this flag is being checked by the helper when it attempt to start the server. So YES, it is a bug in the HttpServerHelper.

So instead of calling:

startHttpsServer(context, component, 443).start();
startHttpServer(context, component, 8182).start();

you should change it to:

Server s1 = startHttpServer(context, component, 8182);  // startHttpServer should return Server instead of HttpServerHelper.  The method still instantiates HttpServerHelper
Server s2 = startHttpsServer(context, component, 443);
component.getServers().add(s1);
component.getServers().add(s2);
component.start();
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top