Home > Uncategorized > Extending the Grizzly HTTP Runtime part V: Programatically configuring Servlet and GrizzlyAdapter

Extending the Grizzly HTTP Runtime part V: Programatically configuring Servlet and GrizzlyAdapter

A lot of applications/framework (like Jersey, Hudson, DWR, etc.) out there just consist of a single Servlet which dispatch requests to its appropriate internal components. In such case, a full blown Servlet Container might not be needed….but a tiny 800k Grizzly might be!


Like I’ve described in previous post on the topic (I,II,II,IV), it is extremely simple to build an HTTP extension/WebServer using Grizzly:

  1 GrizzlyWebServer ws = new GrizzlyWebServer(80);
  2 GrizzlyAdapter adapter = new GrizzlyAdapter() {
  3     @Override               
  4         public void service(GrizzlyRequest req, GrizzlyResponse res) {
  5             String uri = req.getRequestURI();                   
  6             File file = new File("/var/www",uri);                               
  7             long length = file.length();                                                        
  9             if (file.exists()){                                                                                 
 10                 FileInputStream fis = null;                                                                                             
 11                 try{
 12                     fis = new FileInputStream(file);                                                                                           
 13                     FileOutputBuffer fob = (FileOutputBuffer)res.getOutputBuffer();
 14                     long nWrite = 0;                                                                                                           
 15                     while (nWrite < length) {
 16                         nWrite += fob.sendFile(fis.getChannel(), nWrite, length - nWrite);                                                     
 17                     }                                        
 18                 } catch (IOException ex){                                                                                                      
 19                     res.setStatus(404);                                              
 20                     res.setDetailMessage("Not Found");                                                                                         
 21                 } finally {                                                                                  
 22                     try{                                                                                                                       
 23                         fis.close();                                                                                                         
 24                     } catch (IOException ex){};
 25                 }                                                                                                                              
 26             } else {                                                                                                                           
 27                 res.setStatus(404);
 28                 res.setDetailMessage("Not Found");                                                                                             
 29             }                                                                                                                    
 30         }
 31 };                                                                                                                                             
 32 ws.addGrizzlyAdapter(adapter, new String[]{"/"});   

In 30 lines you just wrote a simple file server. But what about Servlet? Let’s take a very difficult application and try to launch it with Grizzly: Hudson. Let’s programmatically configure Hudson, similar to what we did for our simple file server. First, let’s create a simple wrapper.

  1 GrizzlyWebServer ws = new GrizzlyWebServer(80);
  2 ServletAdapter adapter = new ServletAdapter();
  3 adapter.setRootFolder("/tmp/hudson");
  4 adapter.setHandleStaticResources(true);
  6 adapter.setContextPath("/hudson");      
  8 Servlet servlet = (Servlet)ClassLoaderUtil.load("org.kohsuke.stapler.Stapler");
  9 adapter.setServletInstance(servlet);                    
 11 Filter filter = (Filter)ClassLoaderUtil.load("hudson.security.HudsonFilter"); 
 12 adapter.addFilter(filter, "authentication-filter", null);               
 14 adapter.addInitParameter("default-encoding", "UTF-8");                          
 16 filter = (Filter)ClassLoaderUtil.load("hudson.util.PluginServletFilter");               
 17 adapter.addFilter(filter, "plugins-filter", null);
 19 adapter.addServletListener("hudson.WebAppMain");
 21 adapter.setProperty("load-on-startup","1");                                                             
 23 ws.addGrizzlyAdapter(adapter, new String[]{"/hudson"});        

As you can see, this is quite simple. First, we create an instance of ServletAdapter (line 2), then configure the appropriate Servlet, Filter, and deployment information (line 8 to 21), taken from Hudson’s web.xml. Note line 23 where we finally add the Adapter to GrizzlyWebServer: just pass the ServletAdapter and a mapping (context) used to map requests. That’s it. You can download the result here and lunch Hudson on top of Grizzly by just doing:

java -jar grizzly-hudson-1.9.3.jar -p 8080 -a hudson.war

OK but this is cool as a demo, but doesn't add anything special to Hudson. Let's extends it by adding a chat functionality so we can blame each other when someone breaks the build. Let first add another Adapter that support the Bayeux protocol so we can chat using Comet

 24 ws.addGrizzlyAdapter(new CometdAdapter(), new String[]{"/cometd"});

So now we can package our 24 lines of code, and have a very small Hudson server with chat capability. Requests to /hudson goes to Hudson, /cometd goes to our Bayeux/Cometd chat application. Nothing fancy here as you can already do that using GlassFish. But quite simple to do it programmatically!. Another way to add Bayeux support could have been:

 24 ServletAdapter adapter2 = new ServletAdapter();
 25 adapter2.setRootFolder("/tmp/hudson");
 26 adapter2.setHandleStaticResources(true);
 28 adapter2.setContextPath("/cometd");
 30 Servlet servlet = (Servlet)ClassLoaderUtil.load("com.sun.grizzly.cometd.servlet.CometdServlet");
 31 adapter2.setServletInstance(servlet);
 33 ws.addGrizzlyAdapter(adapter2, new String[]{"/cometd"});

A little more complicated, but just to demonstrate how to programmatically deploy more than one Servlet.

Want to try it? download the grizzly-webserver.jar and uses your favorite IDE to build powerful HTTP based applications. Need help: ping us on users@grizzly.dev.java.net, or Tweet us on Twitter.

_uacct = "UA-3111670-1";


Categories: Uncategorized
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s