Escolar Documentos
Profissional Documentos
Cultura Documentos
1. Introduction
Jetty and Tomcat are often cast as direct competitors. This paper is short comparison of the technical and
non-technical aspects of these two open source servlet containers.
2. Technical Comparisons
2.0. Architecture
The view from 20,000 feet is that Tomcat and Jetty are rather similar, they are both java applications
servers offering implementations of the 2.5 servlet specification with optional extras giving many JEE
features.
However, on closer inspection, the architectures of the two servers differ greatly, mostly because each
project as historically had a different focus:
Tomcat is first and foremost an application server. Its default incarnation is as software installed onto a
system, into which one can install applications. Tomcat can be stripped down to be embedded or built up
the be an full JEE server, but both are difficult exercises. Jetty is first and foremost a set of software
components that offer HTTP and servlet services. Jetty can be invoked and installed as a stand alone
application server or it can be easily embedded in an application or framework as a HTTP component, as a
simple servlet engine, as a feature rich servlet engine or as part of a full JEE environment.
It is the flexible component based architecture of Jetty that allows it to be flexibly deployed and integrated in
a diverse range of instances:
In software frameworks and tools: OSGi Equinox, OSGi Felix, Spring, Plexus, Cocoon, Tapestry,
Maven, Continuum, Fisheye, Grails, JRuby, Xbean, etc.
In JEE application servers: Geronimo, Jboss, Sybase EAServer, JOnAS and Glassfish
Embedded in applications, products and services from IBM, HP, Cisco, BEA, Yahoo, Eclipse (see
http://docs.codehaus.org/display/JETTY/Jetty+Powered)
As the basis for enhanced services such a SIP (www.cipango.org), Ajax JMS (www.activemq.org),
Asynchronous SOA services (Apache Camel)
As the servlet specification continues to grow and add additional features (annotations, automatic web
services, etc.) the cost of a standard servlet server is increasing. While Jetty will always continue to support
the standard incarnation, its modular approach allows deployments to be targeted at precisely the set of
services required without the additional complexities, inefficiencies and security concerns of unused
features.
2.1. Performance
Both Jetty and Tomcat offer good request per second performance and for any non-trivial web application it
is highly unlikely that either will be the main bottleneck.
General benchmarks are difficult to provide and web load profiles are greatly influenced by the actual
application and there is no substitute for specific application benchmarking. However, some generalized
observations can be made:
Tomcat tends to have slightly better performance when there are few very busy connections. It has a
slight advantage in request latency, which is most apparent when many requests/responses are sent
over a few connections without any significant idle time.
Jetty tends to have better scalability when there are many connections with significant idle time, as
is the situation for most web sites. Jetty's small memory footprint and advance NIO usage allows a
larger number of users per unit of available memory. Also the smaller footprint means that less
memory and CPU cache is consumed by the servlet container and more cache is available to speed
the execution of non-trivial applications.
Jetty also has better performance with regards to serving static content, as Jetty is able to use
advance memory mapped file buffers combined with NIO gather writes to instruct the operating
system to send file content at maximum DMA speed without entering user memory space or the
JVM.
2.2. Features
Both Jetty and Tomcat implement the core standard servlet 2.5 specification. Both servers offer a range of
EE inspired features such as JNDI, JTA, JMS, Mail servers, etc. Tomcat has an easy migration path for full
EE towards Jboss and Geronimo. Jetty has an easy migration path for full EE towards Geronimo, JBoss,
JOnAS, Sybase EAServer and, to some extent, Glassfish.
In the last 18 months, there has been an increased focus on web-2.0 features, specifically Ajax Push and
Comet. Jetty has been a leader in supporting the web-2.0 use-case from within the servlet model and
Webtide has formalized the Jetty approach in a proposal to JSR315 for the Servlet 3.0 that is likely to be
accepted as the standard way to provide the asynchronous servlets that are needed by web-2.0. In
comparison, the Tomcat project was slow to accept the Web-2.0 use-case, but are now offering an async IO
API that does fulfill the requirement. However that approach is not from within the servlet model, so
standard frameworks (JSP, Struts, etc) and techniques cannot be used.
3. Non-Technical Comparisons
3.0. Market Share
Selecting the market leader is often used as an important selection criteria. While market share is often a
good indication of technical strength, there are often many non-technical and/or historical reasons that may
contribute to and devalue market share as a selection criteria -specially in a market heavy influenced by
standards.
More over, the dominant market share once held by Tomcat is in decline, while Jetty's market share has
been steadily increasing over the last 18 months to the point where it now has 80% of Tomcat's market
share as reported in the Netcraft server surveys:
The Netcraft (http://www.netcraft.com) report surveys only measure a fraction of installations as many
servers have had their identifies disabled or are hidden behind load balancers or other web servers such as
Apache. If installed base is to be considered, then Jetty's use in many frameworks and tools (e.g. in the
Eclipse IDE from 3.3 onwards) would give Jetty a regular usage basis in the millions.
Jetty pays close attention to the specification and faithfully implements it. The Jetty developers were also
very active on JSR-154 for servlets 2.5 and now on JSR-315 for servlets 3.0. Thus Jetty not only follows
the servlet specification, but is able to influence the ongoing enhancement of the specification and
to anticipate upcoming changes.
The project has switched from Commit and Review development to Review and Commit.
The upcoming move to Servlet 3.0 is going to require non-trivial enhancements to all servlet servers.
Having a unified harmonious, experienced and proven development team and process will be key to the
smooth transition to the new specification and the services and features that it will support.
4. Summary
The Tomcat project is a reasonable quality Java application server that has an established brand and large
user base. When used for it's prime role, Tomcat well fulfills the requirements. However it does lack the
flexibility as a software component and the capability as a project and community to adapt to
changing requirements and new innovative usage.
The Jetty project/team has an attitude and a history of being responsive to innovations and
changing requirements. This has resulted in a well architected software platform that has been
integrated and deployed in almost every environment and that is supported by a sizable, healthy
and growing community.
For more information about Jetty, please check out the official Jetty website at
http://jetty.mortbay.org/jetty/.
Initial Contributions
The initial code will be the current jetty trunk as located in svn at The Codehaus. A
bundle has already been delivered to begin the IP verification process.
Description
Jetty is an open-source, standards-based, full-featured web server implemented entirely
in Java. It is released under the Apache 2.0 license and is therefore free for commercial use
and distribution. Once established as an Eclipse project, it will be dual-licensed, maintaining
its Apache 2.0 license, and adding the Eclipse Public License. Beyond the license addition,
which would not require any changes from the current large number of users or consuming
open source projects or commercial products with use of Jetty, the move is seen as having
numerous benefits for the projects and community...
The transition would be a great time to clean up the project's packaging as it moves
to an org.eclipse name.
The project will be focused on providing components and less on providing a
bundled application server stack. This will allow great focus of development energies
and further bring out Jetty's embedding strengths.
The Eclipse IP policies will supplement Jetty's existing processes.
Jetty could discuss handling the maintenance and updating the OSGI HTTP service
for Equinox as a module. The project is also interested in being involved in an effort
to modernize the standard for OSGI HTTP service. At this time, the project does not
envision revising its internal structure to use OSGi, but to stay with POJO that can
be configured with IOC/DI frameworks, which will work well for OSGi.
The being a part of Eclipse's release trains would simplify spreading current versions
of Jetty for use in relevant projects within the Foundation that may be interested.
As history, Jetty was first created in 1995, and has benefited from input from a vast user
community and consistent and focused development by a stable core of lead developers.
There are many examples of Jetty in action on the Jetty Powered Page however, as Jetty
aims to be as unobtrusive as possible, countless websites and products are based around
Jetty, but Jetty is invisible!
Jetty can be used as:
a stand-alone traditional web server for static and dynamic content
a dynamic content server behind a dedicated HTTP server such as Apache using
mod_proxy or mod_jk
an embedded component within a java application
as a component to build an application server or Java EE server
This flexibility means that Jetty can be encountered in a number of different contexts:
http://docs.codehaus.org/display/JETTY/Newbie+Guide+to+Jetty
Starting up Jetty
Configuration file
Doctype (required)
Server (required)
Connectors (required)
Handlers (required)
ThreadPool (optional)
More
Examples
Starting up Jetty
jetty-runner.jar - fast and easy way to run your webapp, without needing to install and administer a jetty distro.
Run it using java
files
etc/jetty.xml is the default configuration file for Jetty. It demonstrates several basic functions, and can be used as
the basis for your own configuration. To immediately start up Jetty and begin looking around, go to $JETTY_HOME
and run this command:
http://localhost:8080/.
There are several additional options that can be set on the command line when using the supplied
Option
jetty.xml:
Value
name
jetty.home
directory which contains the etc, webapps, contexts folders. No trailing slash. Default value is the
directory from which you are running start.jar.
jetty.host
jetty.port
jetty.logs
directory which contains the request logs. No trailing slash. Default value is ${jetty.home}/logs
To use these, do
Overview
Configuration file
A server configuration file will look something like this:
Doctype (required)
All tags and elements declared inside
only tags and elements based from this data type file will be valid .
Connectors (required)
Implementations of the org.mortbay.jetty.Connector interface provide connectors for the HTTP protocol. It is here that
you set the ports that Jetty will listen on for incoming connections.
<Set name="connectors">
<Array type="org.mortbay.jetty.Connector">
<Item>
<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>
...
</New>
</Item>
</Array>
</Set>
Handlers (required)
Handlers
process
inbound
requests.
There
is
handler
which
services
web
applications
called
org.mortbay.jetty.webapp.WebAppContext. If you don't wish to use a full-blown application but just want to serve static
content and maybe some servlets, then you can use a ContextHandler and only configure those services you require.
The list of handlers that are defined for a Server is set by the following call:
<Set name="handlers">
<Array type="org.mortbay.jetty.Handler">
...
</Set>
ThreadPool (optional)
The ThreadPool class avoids the expense of thread creation by pooling threads for reuse after their run methods exit. If
the maximum pool size is reached, jobs wait for a free thread. By default there is no maximum pool size. Idle threads
timeout and terminate until the minimum number of threads are running. Configuring the ThreadPool is optional,
because the server falls back upon defaults. However, you may wish to customize the thread pool to better fit your
application. Example:
<Set name="ThreadPool">
<New class="org.mortbay.thread.QueuedThreadPool">
<Set name="minThreads">10</Set>
<Set name="maxThreads">200</Set>
<Set name="lowThreads">20</Set>
<Set name="SpawnOrShrinkAt">2</Set>
</New>
</Set>
More
For a more detailed explanation of the default settings, see the jetty.xml walkthrough. The Syntax Reference explains
the syntax for individual elements.
Examples
$JETTY_HOME/etc/myjetty.xml.
$JETTY_HOME/webapps folder:
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Set name="handler">
<New id="Handlers" class="org.mortbay.jetty.handler.HandlerCollection">
<Set name="handlers">
<Array type="org.mortbay.jetty.Handler">
<Item>
<New id="Contexts" class="org.mortbay.jetty.handler.ContextHandlerCollection"/>
</Item>
</Array>
</Set>
</New>
</Set>
<Call name="addLifeCycle">
<Arg>
<New class="org.mortbay.jetty.deployer.WebAppDeployer">
<Set name="contexts"><Ref id="Contexts"/></Set>
<Set name="webAppDir"><SystemProperty name="jetty.home" default="."/>/webapps</Set>
</New>
</Arg>
</Call>
</Configure>
<Set name="handler">
<New id="Handlers" class="org.mortbay.jetty.handler.HandlerCollection">
<Set name="handlers">
<Array type="org.mortbay.jetty.Handler">
<Item>
<New id="Contexts" class="org.mortbay.jetty.handler.ContextHandlerCollection"/>
</Item>
<Item>
<New id="DefaultHandler" class="org.mortbay.jetty.handler.DefaultHandler"/>
</Item>
</Array>
</Set>
</New>
</Set>
<Call name="addLifeCycle">
<Arg>
<New class="org.mortbay.jetty.deployer.WebAppDeployer">
<Set name="contexts"><Ref id="Contexts"/></Set>
<Set name="webAppDir"><SystemProperty name="jetty.home" default="."/>/webapps</Set>
<Set name="parentLoaderPriority">false</Set>
<Set name="extract">true</Set>
<Set name="allowDuplicates">false</Set>
<Set name="defaultsDescriptor"><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set>
</New>
</Arg>
</Call>
</Configure>
than
the
extra
configuration
settings,
the
biggest
change
is
the
addition
of
the
org.mortbay.jetty.handler.DefaultHandler, which deals with unhandled requests in the server. If you have no webapps
defined in the root context ("/"), visiting http://localhost:8080/ will 404, but will present a list of contexts that have been
deployed on the server. DefaultHandler also serves up a Jetty favicon.
For more details about configuring static deployment, see WebAppDeployer.
That sets up a ContextDeployer, which will scan the $JETTY_HOME/contexts folder every 5 seconds for changes to
the XML descriptors, and hot deploy as necessary. For more details, see ContextDeployer.
Note that ResourceHandler does not allow directory listing; if you visit a directory with no welcome files, you will get a
403 Forbidden error message. Try the exact path to the file.
If you just want a specific context to serve static content, while still serving dynamic web applications from other
contexts, configure your server to allow hot deployment (see previous example), then set up a context to serve up
Static Content.
<Ref id="RequestLog">
<Set name="requestLog">
<New id="RequestLogImpl" class="org.mortbay.jetty.NCSARequestLog">
<Set name="filename"><SystemProperty name="jetty.logs" default="./logs"/>/request.log</Set>
<Set name="append">false</Set>
</New>
</Set>
</Ref>
</Configure>
Similar to the one handler example, but defines multiple handlers. A handler can be configured either as soon as it is
declared, or further down using the Ref tag. There is no difference in effect between the two. That example serves up
static files in the logs directory under your current directory, and logs all requests since the server was last started to
request.log.
To see this in action, go to http://localhost:8080/request.log and refresh a few times (you may need to hard refresh, to
make sure you are not seeing a cached copy of the data).
For simplicity's sake, the logfile's name does not contain a date; see
does.
Either
HandlerCollection
or
HandlerList
can
be
used
when
setting
multiple
handlers.
(3)Jetty Documentation
http://docs.codehaus.org/display/JETTY/Jetty+Documentation
Jetty Documentation
Jetty Powered
About Jetty
Getting Started
Downloading Jetty
Supported JVMs
References
Jetty Architecture
Javadoc
xref
Walkthrough: jetty.xml
Jetty Security
Tutorials
Embedding Jetty
Porting to jetty6
Development
Contributing
SVN:
jetty-7 (developers svn+ssh)
jetty-7 accessories (developers https)
jetty-6 (developers https)
jetty-6 contrib (developers https)
hightide (developers https)
Codehaus CI
JIRA
Feature Guides
Asynchronous Servlets
Suspendable Requests
Continuations
AJAX / Comet
ActiveMQ
Maven Support
Ant Support
IDEA
Eclipse Workbench
run-jetty-run
Cargo
Mobile Computing
JME CDC
RedHat JBoss
Sybase EAServer
Web Frameworks
DWR
MyFaces
Jakarta Slide
Jetspeed2
ICEfaces
EJB
JBoss EJB3
Clustering Technologies
WADI
Infrastructure
JOTM
ActiveMQ
Java-monitor
OSGi
OSGi Tips
Jetty in JOnAS 5
Amazon EC2
Other
JIRA
How Tos
General
Debug Logging
General Configuration
Configuring Jetty
Temporary Directories
System Properties
Classloading
JSP Configuration
Customizing startup
GZIP Compression
Static Content
Rewrite Handler
Connectors
Configuring Connectors
Configuring SSL
Ssl Connector Guide
Configure SSL Cipher Suites
Virtual hosts
Thread Pools
Bounded ThreadPool
Security
Securing Jetty
Securing Passwords
Realms
JAAS Realms
Management
Request Logging
Collecting statistics
Graceful shutdown
JMX
Annotations
JNDI Services
Using JNDI
DataSource Examples
JSP
JSP Configuration
Sessions
Session Configuration
Persisting Sessions
Clustering
Optimizing
Other
Trouble shooting
Keep Generated
OutofMemory Errors
J2SE 6 Problems
General
Porting to jetty6