Participate in the Code
If you are more interested in digging into what makes Jetty tick then this some information that you will need to arm yourself with. First we start with how to checkout and build Jetty, then on to our general coding standards followed by the actual patch contribution process.
Source Control
The Eclipse Jetty project is located at Github under the Eclipse Foundation parent project. There are a number of branches that are generally of interest.
Development |
Servlet 5.0 |
Java 11+ |
|
Development (default branch) |
Servlet 4.0 |
Java 11+ |
|
Maintenance |
Servlet 3.1 |
Java 8 |
|
Maintenance |
Servlet 3.0 |
Java 8 |
|
Historical |
Servlet 2.0 |
Java 7 |
|
Mythical |
Servlet 1.0 |
Java 6 |
If you are planning on working with a specific issue within Jetty it is important to target the correct branch for a pull request. Pull requests that are targeted at Maintenance Branches are typically merged forward into subsequent branches while historical branches are left alone merge wise. Depending on the nature of an issue a historical branch may have an issue cherrypicked forward, but maintenance releases are merged wholesale forward as a matter of project policy.
Secondary SCM
These are the URLs for Jetty-related code and metadata. These are not needed to use Jetty; these are primarily of use for developers who are working with the open source project within Eclipse.
- Build related artifacts that release separately, common assembly descriptors, remote resources, etc.
Maven Build
Eclipse Jetty uses Apache Maven for managing the project metadata and controlling the build.
Building Jetty should simply be a matter of changing into the relevant directory and executing the following commands:
$ git clone https://github.com/jetty/jetty.project.git
$ cd jetty.project
$ mvn install
All relevant dependencies should be downloaded into your local repository automatically and the build should proceed normally.
Jetty has a great many test cases that run through the course of its build. Many of these tests spin up embedded instances of Jetty itself and it is not uncommon to see hundreds or more instances of Jetty start and stop during tests. Periodically we find some test cases to be more time dependent than they should be and this results in intermittent test failures. You can help track these down by opening an Issue.
Coding Standards
Jetty uses number of conventions for its source code. The developers of Jetty use a variety of tooling and editors when developing Jetty so standards and conventions are important!
Intelli-J
The suggested configuration for Intelli-J when working with Jetty is available here: Intelli-J Codestyle
Eclipse
The Eclipse format configuration can be found here: Eclipse Java Formatting
There are also some templates available for Eclipse here: Eclipse Code Templates
Code Conventions
The following is an example of the Java formatting and naming styles to apply to Jetty:
import some.exact.ClassName; // GOOD
import some.wildcard.package.*; // BAD!
package org.always.have.a.package;
/* --------------------------------------------------------- */
/** Always have some javadoc
*/
class MyClassName
{
// indent by 4 spaces.
// use spaced to indent
// The code must format OK with default tabsize of 8.
private static final int ALL_CAPS_FOR_PUBLIC_CONSTANTS=1;
// Field prefixed with __ for static of _ for normal fields.
// This convention is no longer mandatory, but any given
// class should either consistently use this style or not.
private static String __staticField;
private Object _privateField;
// use getters and setters rather than public fields.
public void setPrivateField(Object privateField)
{
_privateField=privateField;
}
public Object getPrivateField()
{
return _privateField;
}
public void doSomething()
throws SomeException
{
Object local_variable = _privateField;
if (local_variable==null)
{
// do Something
}
}
}
While Eclipse Jetty is an open source project it is also a member of the Eclipse Foundation which carries along some additional responsibilities. Intellectual Property is a hallmark concern of the Eclipse Foundation so you are encouraged to understand what that entails before diving in. As much as we would like to accept a tremendous pull request, without the proper chain of events being completed our hands are tied. That being said, the steps are not particularly onerous and we are happy to work with you to get them accomplished.
Logging Conventions
When deciding when and what to log, bear in mind a few things:
-
never use
LOG.debug
without a precedingif (LOG.isDebugEnabled())
-
we don’t want to pollute the log with very long stacktraces unless necessary
-
we don’t want to routinely produce logging events in response to data sent by a user
-
we should not call more than one LOG method for a single event: otherwise log messages may be interleaved and more confusing
-
we should never LOG.warn and then throw that exception, as that will result in double handling
-
we should seldom LOG.debug and then throw as that will make debug verbose and add little information
-
when interacting with a request, or information received from a client:
-
no logging unless
isDebugEnabled
, in which case you output atDEBUG
level eg:
-
catch (Throwable t) { if (LOG.isDebugEnabled()) LOG.debug("Something happened {} {} {}",x, y, z, t); }
-
when calling into application code that throws an exception:
-
use
INFO
level, and useisDebugEnabled
to cut down on the size of the logging of stack traces:
-
catch (Throwable t) { if (LOG.isDebugEnabled()) LOG.info("Something happened {} {} {}", x, y, z, t); else LOG.info("Something happened {} {} {} {}", x, y, z, t.toString()); }
-
when exceptions happen in jetty code:
-
mostly use
WARN
orERROR
level -
if the exception is not entirely unexpected, can happen relatively frequently, or can potentially have a very long stack trace and you don’t want to clutter up the log, you can use
isDebugEnabled
to cut down on the size of the logging of the stacktrace:
-
catch (Throwable t) { if (LOG.isDebugEnabled()) LOG.warn("Something happened {} {} {}", x, y, z, t); else LOG.warn("Something happened {} {} {} {}", x, y, z, t.toString()); }
Be aware that LOG.warn("Something happened", t)
is the same asLOG.warn("Something happened {}", t)
, at least for the default jetty logging. In both cases, the full stacktrace is output. If you only want the log message, you need to doLOG.warn("Something happened {}", t.toString())
.