Search code examples
javajettyosgirestlet

Configure Restlet to use Jetty Connector (Not Simple Connector) in OSGi


I wanted to use the jetty connector that is provided as an extension in the restlet jar file. I added the following jar to the class path of my Restlet application bundle.

org.restlet.ext.jetty.jar

I add the Http or HTTPS server to the component like below.

  private Component m_Component = new Component();


  private void addHTTPServer() throws Exception
  {
    m_Component.getServers().add( Protocol.HTTP, 8484 );

  }



  private void addHTTPsServer() throws Exception
  {
    File keystore = new File( m_KeyStoreFile );
    Server server = m_Component.getServers().add( Protocol.HTTPS, 8484 ); 

    Series<Parameter> parameters = server.getContext().getParameters();
    parameters.add( "keystorePath", keystore.toPath().toString() );
    parameters.add( "keystorePassword", "Localstorepass" );
    parameters.add( "keystoreType", "JKS" );
    parameters.add( "keyPassword", "Localkeypass" );
  }

Here is the output when the server is started.

Dec 08, 2015 11:44:59 AM org.restlet.engine.connector.NetServerHelper start

INFO: Starting the internal [HTTPS/1.1] server on port 8484

Dec 08, 2015 11:44:59 AM org.restlet.Application start

INFO: Starting de.hsag.services.restlet.application.RestletApplication application

Is there an option to configure it to directly use Jetty as a Server Connector?

Update:

As it was mentioned in the answer below making sure that I initialise the component after the org.restlet.ext.jetty.jar bundle is activated did the trick. So I made my restlet activator class implement BundleListener interface and start the component when the BundleEvent shows me that the jetty extension jar is activated.

  @Override
  public void bundleChanged( BundleEvent event )
  {
    if( event.getBundle().getSymbolicName().equalsIgnoreCase( "org.restlet.ext.jetty" ) ) {
      if( event.getBundle().getState() == Bundle.ACTIVE ) {
          private Component m_Component = new Component();
          m_Component.getServers().add( Protocol.HTTP, 8484 );
          ...
      }
    }
  }

In addition I added the following jar files for jetty.

javax.servlet.jar

org.eclipse.jetty.http.jar

org.eclipse.jetty.io.jar

org.eclipse.jetty.server.jar

org.eclipse.jetty.util.jar

Now I can see that jetty is selected automatically:

> Dec 11, 2015 12:36:23 AM org.restlet.ext.jetty.JettyServerHelper start
> INFO: Starting the Jetty [HTTPS/1.1] server on port 8484

Solution

  • In fact, when putting a Restlet extension jar within the application classpath, the Restlet engine will automatically register the elements (like servers) it contains. That's the case for the Jetty extension but also for other extensions.

    Restlet will get the first available connector available for a particular protocol.

    You can have a look at registered connectors using this code:

    List<ConnectorHelper<Server>> servers
            = Engine.getInstance().getRegisteredServers();
    for (ConnectorHelper<Server> server : servers) {
        system.out.println(server);
    }
    

    In my case, I added the jetty extension JAR file and I have the following output:

    org.restlet.ext.jetty.HttpServerHelper@12c042ba
    org.restlet.ext.jetty.HttpsServerHelper@c5ccaf4
    org.restlet.engine.local.RiapServerHelper@20105f83
    org.restlet.engine.connector.HttpServerHelper@12eea1e7
    org.restlet.engine.connector.HttpsServerHelper@70c74e66
    

    As you can see, the jetty-based server is in first position. So Jetty is used when starting the component:

    2015-12-08 14:15:55.102:INFO::main: Logging initialized @178ms
    Starting the Jetty [HTTP/1.1] server on port 8182
    2015-12-08 14:15:55.163:INFO:oejs.Server:main: jetty-9.2.6.v20141205
    2015-12-08 14:15:55.198:INFO:oejs.ServerConnector:main: Started ServerConnector@79a8885f{HTTP/1.1}{0.0.0.0:8182}
    2015-12-08 14:15:55.198:INFO:oejs.Server:main: Started @276ms
    

    In your case, it seems that the internal HTTP server is used. You configured the right way your servers so it seems to be a server helper registration problem...

    As you use OSGi, it could be a problem of starting levels. I mean the jetty extension bundle isn't started when the restlet bundle starts. You could leverage the framework event to start your component. That way, you would be sure that every bundle is started so every restlet extensions as well...

    Hope it helps you, Thierry