Simple tips in running Jetty on Linux

This is mainly just a short article to get me back in the habit of posting regularly. Recently, I’ve been working a bit with fine tuning Jetty, a light weight and configurable AppServer from Codehaus sponsored by Eclipse. Jetty gets production support from MortBay Consulting, who handle the heavy lifting for Codehaus. MortBay is also the developer of Jetty that was merged first with Webtide and finally with Intalio. Webtide, provides the training programs Mortbay founded with Jetty, and Intalio offers complete open source Cloud computing systems for businesses employing these tools. That’s about the end of my nod section.

Basic setup of Jetty is fairly simple. You unzip it into a folder, and then modify the JettyRoot/etc/jetty.xml file. You don’t need much here, and in fact jetty has a bunch of maven plugins and other companion tools from along the way, including integration with Cargo that let you deploy on the fly, but for my first tests, figuring out what the Jetty.xml file would do was kind of the first step.

David Yu was kind enough to give a full sample config file and then a walk through of it here.
My only issue with it, was that this was stand alone, self-documented configuration, and I rarely have something that works straight out of the box. To that end, I’m going to cite David’s file here and show my modifications.

I was dealing with a local server to start but planned on putting some beefy, database intensive apps, employing hibernate on here. To that end, I wanted to up the thread count. David’s first section lists them. Thread count pooling is one of those things I did primarily on the Java machine setup. Here, you just edit these lines here.

<Set name=”minThreads”>50</Set>
<Set name=”maxThreads”>500</Set>
Next you add the connector


<Call name=“addConnector”>
<Arg>
<New class=“org.mortbay.jetty.nio.SelectChannelConnector”>
<Set name=“host”><SystemProperty name=“jetty.host” /></Set>
<Set name=“port”><SystemProperty name=“jetty.port” default=“8080”/></Set>
<Set name=“maxIdleTime”>300000</Set>
<Set name=“Acceptors”>2</Set>
<Set name=“statsOn”>false</Set>
<Set name=“confidentialPort”>8443</Set>
<Set name=“lowResourcesConnections”>20000</Set>
<Set name=“lowResourcesMaxIdleTime”>5000</Set>
</New>
</Arg>
</Call>

As you can see, Wu has setup the typical Developer machine running on port 8080.  Tomcat defaults to the same port on initial setup, in part to avoid conflict with the web server like Apache that usually defaults to port 80.    But for this app, we’re going to let Jetty serve as the web server and the app server.

<Set name=“port”>80</Set>

Let’s remove the System call to the application command line that would have checked for a variable at runtime to change our jetty port, and just explicitly call the port we want as 80.

I’m also going to give this machine several IP addresses and later use the web app itself to determine some work, so I’m going to set the IP address to 0.0.0.0 so it will accept traffic from all IP’s on the box.

Change the host to this

<Set name=“host”>0.0.0.0</Set>

I plan on having a real SSL certificate on this machine, and want to use the default SSL port of 443 for my confidential port. There are two changes I need to make here.

First, I change this line to set my default port,

<Set name=“confidentialPort”>443</Set>

and then beneath the block I spelled out above, I need to add another listener.  So after “</Call>”

I add

<Call name=”addConnector”>
<Arg>
<New class=”org.mortbay.jetty.security.SslSocketConnector”>
<Set name=”Port”>443</Set>
<Set name=”maxIdleTime”>30000</Set>
<Set name=”keystore”><SystemProperty name=”jetty.home” default=”.” />/etc/keystore</Set>
<Set name=”password”>OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
<Set name=”keyPassword”>OBF:1u2u1wml1z7s1z7a1wnl1u2g</Set>
<Set name=”truststore”><SystemProperty name=”jetty.home” default=”.” />/etc/keystore</Set>
<Set name=”trustPassword”>OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
</New>
</Arg>
</Call>

I could set this up now and show you my passwords for my Secure cert, but let’s discuss what the next steps are instead so I can explain myself a little better.

That first section I did added an adapter that listens on port 80 of all IP’s the machine listens to.  The second section I added adds a listener that listens to port 443 and uses a keystore that actually comes standard with the mortbay version of Jetty.  If you have any problems on startup, with this mortbay connector, all you need to do is replace it with the Eclipse based jetty connector of the same name.  That was an interesting step in the documentation.  Many of the older versions of Jetty actually have two different major builds.  One that has eclipse objects and one with mortbay objects.  Check which one you’re using and configure accordingly.

Anyway, what the first Adapter did also was to declare that confidential communication received on port 80 should be redirected to port 443.  This ties into the Java web.xml page.

A good example of the security constraint configuration for web.xml can be found at IBM’s docs here.  Basically, you can add string matching constraints to services, types of requests or any other major communication flow of your application and direct them to either the CONFIDENTIAL port, or to the default port (port 80 for us) with the directive NONE.  You can litterally have dozens of these for your app, but for me, I just wanted to make certain that people coming to my loginServlet hit port 443 every time and on all requests.

Snippet for Web.xml

<security-constraint id=”basicloginauth”>
<url-pattern>/loginServlet*</url-pattern>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</security-constraint>

I’ll go ahead and tell you, the rest of Wu’s file, while filled with useful stuff about contexts, can now be left alone.
Next step, we need to change the context file.
goto your JettyRoot/contexts folder and delete everything in it.

Really, rm -f *.xml at the very least.  This stuff contains links to a bunch of test stuff, you’ll throw away later anyway, and only mucks things up for how simple we’re going to make it.

Now I want to make a simple context file that unwraps my superapp.war file from the webapps directory and serves it up after the root of my web address.

Make a file in the contexts folder called superapp.xml

and paste this into it

<?xml version=”1.0″  encoding=”ISO-8859-1″?>
<!DOCTYPE Configure PUBLIC “-//Mort Bay Consulting//DTD Configure//EN” “http://jetty.mortbay.org/configure.dtd”>
<Configure class=”org.mortbay.jetty.webapp.WebAppContext”>
<Set name=”contextPath”>/</Set>
<Set name=”war”><SystemProperty name=”jetty.home” default=”.”/>/webapps/superapp.war</Set>
</Configure>

Now, rename any old webapp you have lying around superapp.war, drop it into the folder and let’s see if we can’t get it running.

I already had Java running on my linux server, so my real concern here is getting this start.jar jetty gave me to load up the web server.

Here’s the command to run

java -jar start.jar etc/jetty.xml

and voila, point your web browser to localhost and look at your deployed webapp served there. If you have a loginServlet like I do in my app, point the host at localhost/loginServlet
Hey, looky there, we’re redirected to port 443 and we get a request to accept an unsigned cert. Well. That was a fairly short update, if any interest is shown, I’ll show you how to add a signed cert to the store and get Java to use the store.

Leave a Reply