The configuration file is jetty.xml, and doesn't require much. It lives under the ./etc directory of my project:
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure id="Server" class="org.mortbay.jetty.Server">
<Set name="ThreadPool">
<New class="org.mortbay.thread.QueuedThreadPool">
<!-- initial threads set to 10 -->
<Set name="minThreads">10</Set>
<!-- the thread pool will grow only up to 200 -->
<Set name="maxThreads">200</Set>
<!-- indicates that having 20 and below, the pool will be considered low on threads -->
<Set name="lowThreads">20</Set>
<!-- The number of queued jobs (or idle threads) needed before the thread pool is grown (or shrunk) -->
<Set name="SpawnOrShrinkAt">2</Set>
</New>
</Set>
<Call name="addConnector">
<Arg>
<New class="org.mortbay.jetty.nio.SelectChannelConnector">
<!-- the ip address or domain to bind -->
<Set name="host">
<SystemProperty name="jetty.host"/>
</Set>
<!-- the port to use/bind, defaults to 8080 if property not set -->
<Set name="port">
<SystemProperty name="jetty.port" default="8080"/>
</Set>
<!-- the time in milliseconds when a connection is considered idle -->
<Set name="maxIdleTime">300000</Set>
<!-- the number of acceptors (their job is to accept the connection and dispatch to thread pool) -->
<Set name="Acceptors">2</Set>
<!-- should the connection statistics be turned on? (Not advisable in production) -->
<Set name="statsOn">false</Set>
<!-- the confidential port -->
<Set name="confidentialPort">8443</Set>
<!-- indicates the minimum number of connections when the server is considered low on resources -->
<Set name="lowResourcesConnections">5000</Set>
<!-- when low on resources, this indicates the maximum time a connection must be idle to not be closed -->
<Set name="lowResourcesMaxIdleTime">5000</Set>
</New>
</Arg>
</Call>
<!-- Stops the server when ctrl+c is pressed (registers to Runtime.addShutdownHook) -->
<Set name="stopAtShutdown">true</Set>
<!-- send the server version in the response header? -->
<Set name="sendServerVersion">true</Set>
<!-- send the date header in the response header? -->
<Set name="sendDateHeader">true</Set>
<!-- allows requests(prior to shutdown) to finish gracefully -->
<Set name="gracefulShutdown">1000</Set>
</Configure>
This configuration file is referenced by the bootstrap class, using it to configure Jetty. This class also sets the context for the webapp, points to the top-level directory of the exploded WAR content, sets a webapp context and a default context as handlers for Jetty, and starts up the webserver:
public class MyJettyWebServer {
public static void main(String[] args) throws Exception {
Server jetty = new Server();
// configure Jetty by pointing to config file(s)
String[] configFiles = { "etc/jetty.xml" };
for (String configFile : configFiles) {
XmlConfiguration configuration = new XmlConfiguration(new File(configFile).toURI().toURL());
configuration.configure(jetty);
}
// set the context for the webapp
WebAppContext appContext = new WebAppContext();
appContext.setContextPath("/mycontext");
// point to the top-level directory of the exploded WAR content
File warPath = new File(System.getProperty("basedir"));
appContext.setWar(warPath.getAbsolutePath());
// set a webapp context and a default context as handlers for Jetty
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[]{ appContext, new DefaultHandler() });
jetty.setHandler(handlers);
// start up the webserver
jetty.start();
}
}
The pom specifies IceFaces 1.8.2, being careful to exclude the EL API jar wherever that's brought in transitively, as per http://www.icefaces.org/docs/v1_8_0/htmlguide/devguide/appendixA.html; and it specifies Jetty and Log4J artifacts. Note that JSP support is explicitly specified:
....
<!-- use JAR packaging for embedded Jetty -->
<packaging>jar</packaging>
....
<dependencies>
<dependency>
<dependency>
<groupId>org.icefaces</groupId>
<artifactId>icefaces</artifactId>
<version>1.8.2</version>
<exclusions>
<exclusion>
<groupId>javax.el</groupId>
<artifactId>el-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.icefaces</groupId>
<artifactId>icefaces-comps</artifactId>
<version>1.8.2</version>
</dependency>
<dependency>
<groupId>org.icefaces</groupId>
<artifactId>icefaces-facelets</artifactId>
<version>1.8.2</version>
<exclusions>
<exclusion>
<groupId>javax.el</groupId>
<artifactId>el-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>javax.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>1.2_12</version>
</dependency>
<dependency>
<groupId>javax.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>1.2_12</version>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
<version>6.1.21</version>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>6.1.21</version>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jsp-2.1-jetty</artifactId>
<version>6.1.21</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4jVersion}</version>
</dependency>
</dependencies>
</project>
The assembly-plugin descriptor has a few things worth mentioning. In the dependency sets, I lay down my dependencies in the standard webapp location, ./WEB-INF/lib:
<dependencySet>
<unpack>false</unpack>
<scope>runtime</scope>
<outputDirectory>war/WEB-INF/lib</outputDirectory>
</dependencySet>
I also specify several destinations for my dev-time files to deal with Jetty-related stuff:
<!--
Jetty deployment: configuration file location
-->
<fileSet>
<directory>etc</directory>
<outputDirectory>/usr/local/mywebapp/etc</outputDirectory>
<fileMode>0644</fileMode>
</fileSet>
<!--
Jetty deployment: webapp deployment location - hmmm, this one might not be needed...
-->
<fileSet>
<directory>webapps</directory>
<outputDirectory>/usr/local/mywebapp/webapps</outputDirectory>
<fileMode>0644</fileMode>
</fileSet>
<!--
Jetty deployment: production-time exploded warfile location
-->
<fileSet>
<directory>src/main/webapp</directory>
<outputDirectory>/usr/local/mywebapp/war</outputDirectory>
<fileMode>0644</fileMode>
</fileSet>
Finally, to start the program:
java -server -Dbasedir=/usr/local/mywebapp/war -cp /usr/local/mywebapp/war/WEB-INF/lib/* com.mybiz.MyJettyWebServer
Browse to localhost:8080 and your webapp should appear.
You'll notice I did not use the maven-jetty plugin (nor the jetty-maven plugin - yes, there are two different ones, each with different names, schemas and behaviors). The good news about the plugin is that it shields you from much of the configuration/deployment exercises you'll need; that's also the bad news. I needed to understand explicitly what dependencies, etc. I'd need for production, so I chose to do things manually. The good news around this is that I've done most of the heavy lifting to grease the skids for future embedded-Jetty exercises.
References
Jetty 6.x Wiki
Jetty 7x, 8.x Wiki

No comments:
Post a Comment