Showing posts with label Jetty. Show all posts
Showing posts with label Jetty. Show all posts

Thursday, October 15, 2009

JAX-WS inside Jetty

Jetty is a nice and easy to use Web Server (see previous post), but it can it handle an open standards, heavy weight JAX-WS Web Service ?
With a bit of luck and glue code, it can.
So first we need a Service Provider Implementation (SPI) from Jetty: J2se6HttpServerSPI
This will make the JAX-WS endpoint use the Jetty server instead its default Sun HttpServer.
To plugin different SPI's you would define this new service in a META-INF/services file, but you can also set a system property, as described here. You can even do this in code which reduces the number of files you need to worry about when refactoring.
So here's an example of a Jetty Server handling a JAX-WS endpoint in combination with a File system directory.
      Server jettyServer = new Server(port);
     HandlerCollection handlerCollection = new HandlerCollection();
     jettyServer.setHandler(handlerCollection);
    
     /** 1) Publish WebService (JettyHttpServerProvider) */ 
     String context = "/web/ws";
             
     // 1.1) register THIS Jetty server with the JettyHttpServerProvider
     new JettyHttpServerProvider().setServer(jettyServer);
      
     // 1.2) make sure JAX-WS endpoint.publish will use our new service provider: JettyHttpServerProvider
     System.setProperty("com.sun.net.httpserver.HttpServerProvider",
           "org.mortbay.jetty.j2se6.JettyHttpServerProvider");
      
     // 1.3) add an empty HandlerCollection to by setup by this provider
     handlerCollection.addHandler( new HandlerCollection() );
      
     // 1.4) use JAX-WS API to publish the endpoint (will use a JettyHttpServerProvider)
     Endpoint endpoint = Endpoint.create(replayServiceImpl);
     endpoint.publish("http://localhost:" + port + "/web/ws", replayServiceImpl);
    
     /** 2) Publish WebGUI (Jetty) */       
     String context = "/gui";

     // 2.1) configure File Resource Handler
     ResourceHandler fileResourceHandler=new ResourceHandler();
     fileResourceHandler.setWelcomeFiles(new String[]{"index.html"});
     fileResourceHandler.setResourceBase(guiPath); // start here
       
     // 2.2) configure 'gui' Context
     ContextHandler guiHandler = new ContextHandler();
     guiHandler.setContextPath(context);
     guiHandler.setResourceBase(".");
     guiHandler.setClassLoader(Thread.currentThread().getContextClassLoader());
     guiHandler.setHandler(fileResourceHandler);
      
     // 2.3) add this context handler
     handlerCollection.addHandler(guiHandler);
 
     /** 3) start JETTY server */
     jettyServer.start();
     jettyServer.join();

Embedding an HTTP daemon in Java

Apache Tomcat, the well-known WebServer is about 84MB after installation. Other contenders are even bigger. Does it have to be so complicated ? The following blog is about the search for a 'right size' HTTP daemon embedable in Java.
Now, what's a Web Server anyway ?
To my mind, its just a piece of software that opens a socket (port 8080) where you send requests to (as defined by the HTTP protocol) and it returns data, in most cases something from the file system (HTML pages and such). This doesn't sound too complicated. In fact, there are examples on the net of HTTP daemons that only take 10 lines of source code (compare the C++ obfuscation contest).
But besides this little niche, there is also NanoHTTPD which already handles some of the ugliness of HTTP. So in order to serve up a system directory, which could contain fairly complicated AJAX/Javascript/JSP files, you don't need more than this single file of Java source code.
If serving a file directory is all you need, go back to the previous chapter.
Unfortunately, things are not that easy ... sometimes you also need to publish a WebService or a Servlet or an already packaged Web application (a war file). Then you need something slightly bigger. The best thing I could find in this category is Jetty. It gives up a nice stand-alone WebServer with all kinds of configuration choices and extension points, but most importantly, it is very easy to embed. By using three jar files (less then 1 MB in total) and writing very little code you again have a complete HTTP daemon. Oh, and also, Jetty is already used inside Eclipse and GWT.