search close

Installing the Java Module as a Jetty Handler

access_time Updated Dec 5, 2022

Requirements

  • Jetty 9.2 or higher

Supported Application Types

For Jetty specific implementations, we support a HandlerWrapper-based install on Jetty 9.2 or higher.

We also provide a lower-level agent RPC communication API if you are interested in writing an implementation for another Java platform. If you are interested in writing an implementation for another Java platform, please reach out to our support team.

Agent Configuration

Like other Signal Sciences modules, the Jetty Handler supports both Unix domain sockets and TCP sockets for communication with the Signal Sciences Agent. By default, the agent uses Unix domain sockets with the address set to unix:/var/run/sigsci.sock. It is possible to override this or specify a TCP socket instead by configuring the rpc-address parameter in the Agent.

Additionally, ensure the agent is configured to use the default RPC version: rpc-version=0. This can be done by verifying the parameter rpc-version is not specified in the agent configuration or if it is specified, ensure that is specified with a value of 0. Below is an example Agent configuration that overrides the default Unix domain socket value:

accesskeyid = "YOUR AGENT ACCESSKEYID"
secretaccesskey = "YOUR AGENT SECRETACCESSKEY"
rpc-address = "127.0.0.1:9999"

Download

Download the Signal Sciences Java module manually or access it with Maven.

Download manually

  1. Download the Java module archive from https://dl.signalsciences.net/sigsci-module-java/sigsci-module-java_latest.tar.gz.

  2. Extract sigsci-module-java_latest.tar.gz.

  3. Deploy the jars using one of the following options:

    • Copy sigsci-module-java-{version}-shaded.jar (an uber jar with all the dependencies bundled) to your application’s classpath (e.g., %CATALINA_HOME%\webbapps\<APP_FOLDER>\WEB-INF\lib).
    • Copy sigsci-module-java-{version}.jar and its dependencies in the lib folder to your application’s classpath (e.g., %CATALINA_HOME%\webbapps\<APP_FOLDER>\WEB-INF\lib). If you already have any of the dependency jar files in your application classpath folder (i.e., for Tomcat in the WEB-INF\lib) then it is not necessary to copy them, even if the version numbers are different. The logging jars are optional based on how slf4j is configured.

Access with Maven

For Java projects using Maven for build or deployment, the Signal Sciences Java modules can be installed by adding the following to the project pom.xml:

<repositories>
    <repository>
        <id>sigsci-stable</id>
        <url>https://packages.signalsciences.net/release/maven2</url>
    </repository>
</repositories>

<dependency>
  <groupId>com.signalsciences</groupId>
  <artifactId>sigsci-module-java</artifactId>
  <version>1.1.3</version>
</dependency>

Install

The installation of the Jetty module varies slightly depending upon whether you deployed Jetty as an embedded or stand alone application.

If you are embedding Jetty within your web application, follow the instructions for “Embedded Jetty”.

Alternatively, if you are deploying your web application to a Jetty instance, follow the instructions for “Standalone Jetty”.

Embedded Jetty

The Signal Sciences Jetty module is currently implemented as a Handler. Edit your application to wrap your existing Handlers with the Signal Sciences Handler.

A typical Jetty based application will add all of the Handlers to a HandlerList, similar to this:

Server server = new Server(InetSocketAddress.createUnresolved("0.0.0.0", 8800));
ServletContextHandler context = new ServletContextHandler();
ServletHolder defHolder = new ServletHolder("default", DefaultServlet.class);
HandlerList handlers = new HandlerList();

// Servlet: /
defHolder.setInitParameter("pathInfoOnly", "true");
defHolder.setInitParameter("dirAllowed", "true");
defHolder.setInitParameter("acceptRanges", "true");
context.addServlet(defHolder, "/*");
context.addServlet(defHolder, "/");

// Existing App Handlers
handlers.addHandler(context);
handlers.addHandler(new DefaultHandler());

// Add the existing handlers as the server handler
server.setHandler(handlers);

try {
server.start();
server.join();
} catch (Exception e) {
e.printStackTrace();
} finally {
server.stop();
}

Add the Signal Sciences Handler around your primary handler. For example:

Server server = new Server(InetSocketAddress.createUnresolved("0.0.0.0", 8800));
ServletContextHandler context = new ServletContextHandler();
ServletHolder defHolder = new ServletHolder("default", DefaultServlet.class);
HandlerList handlers = new HandlerList();

// Servlet: /
defHolder.setInitParameter("pathInfoOnly", "true");
defHolder.setInitParameter("dirAllowed", "true");
defHolder.setInitParameter("acceptRanges", "true");
context.addServlet(defHolder, "/*");
context.addServlet(defHolder, "/");

// Existing App Handlers
handlers.addHandler(context);
handlers.addHandler(new DefaultHandler());

// REMOVED: This is replaced by wrapping with the sigsci handler below
//server.setHandler(handlers);

//////////////////////////////////////////////////////////////////////////
// BEGIN ADDITION: Signal Sciences Handler
// Need to also add these imports for SignalSciencesHandler and Timeout:
//   import com.signalsciences.jetty.SignalSciencesHandler;
//   import com.signalsciences.rpc.util.Timeout;
//////////////////////////////////////////////////////////////////////////
// 1. Create a new SignalSciencesHandler
SignalSciencesHandler sigsciHandler = new SignalSciencesHandler();
// 2. Specify the URI of the sigsci-agent rpc-address (Unix)
sigsciHandler.getSigSciConfig().setRpcServerURI(URI.create("unix:/var/run/sigsci.sock"));
// 3. Specify a timeout
sigsciHandler.getSigSciConfig().setRpcTimeout(new Timeout(300, TimeUnit.MILLISECONDS));
// 4. Set rpcVersion to 0
sigsciHandler.getSigSciConfig().setRpcVersion(0);
// 5. Wrap the other handlers
sigsciHandler.setHandler(handlers);
// 6. Set the SignalSciencesHandler (wrapper) as the server handler
server.setHandler(sigsciHandler);
//////////////////////////////////////////////////////////////////////////
// END ADDITION
//////////////////////////////////////////////////////////////////////////

try {
server.start();
server.join();
} catch (Exception e) {
e.printStackTrace();
} finally {
server.stop();
}

Standalone Jetty

The Signal Sciences Jetty module is currently implemented as a Handler. To use this, you will need to follow the steps below to update your server configuration.

Update Jetty Server Configuration File

In a default Jetty installation, the server configuration file can be found under {jetty.base}/etc/jetty.xml. You will need to update the configuration file to wrap the existing Handlers with the Signal Sciences Handler. Modify the stanza in the file that specifies the handler collection to include the Signal Sciences Handler. Below is an example using the out of the box jetty.xml file:

<Set name="handler">
  <New id="Wrapper" class="com.signalsciences.jetty.SignalSciencesHandler">
    <Call name="setRpcServerURI">
      <Arg>
        <New class="java.net.URI">
          <Arg>unix:/var/run/sigsci.sock</Arg>
         </New>
      </Arg>
     </Call>
     <Call name="setRpcTimeout">
       <Arg>
         <New class="com.signalsciences.rpc.util.Timeout">
           <Arg type="long">300</Arg>
             <Arg>
               <Get class="java.util.concurrent.TimeUnit" name="MILLISECONDS"/>
             </Arg>
         </New>
       </Arg>
     </Call>
     <Set name="handler">
       <New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
         <Set name="handlers">
           <Array type="org.eclipse.jetty.server.Handler">
             <Item>
               <New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
             </Item>
             <Item>
               <New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
             </Item>
           </Array>
         </Set>
       </New>
     </Set>
  </New>
</Set>

Deploy Signal Sciences Library to the Server ClassPath

There are two options for deploying the jars:

  • Copy sigsci-module-java-{version}-shaded.jar (an uber jar with all the dependencies bundled) to your server classpath.
  • Copy sigsci-module-java-{version}.jar and its dependencies in the lib folder to your server classpath.

Although optional, we recommended adding this library to {jetty.base}/lib/ext, as Jetty automatically loads libraries in this path to the server classpath.

Simple Example Server

For a more complete example, see the sigsci-jetty-simple-example JAR files included in the distribution. This consists of the binaries, source, and javadoc for a simple working example. The binary JAR is executable and can be run with commands similar to the following. These commands will start the simple server and point it at an agent running on TCP port 5000 on the local host, which require an agent started with rpc-address = "127.0.0.1:5000":

$ java -jar examples/sigsci-jetty-simple-example-{version}.jar
tcp://127.0.0.1:5000
00:00:00.384 [main] INFO  c.s.example.SimpleExampleServer - WebRoot is jar:file:/x/sigsci-jetty-simple-example-0.1.3.jar!/webroot/
00:00:00.403 [main] INFO  c.s.example.SimpleExampleServer - Signal Sciences WAF: enabled
00:00:00.501 [main] INFO  c.s.example.SimpleExampleServer - Signal Sciences Simple Example Server started (http://0.0.0.0:8800/)
00:00:00.986 [qtp123456789-12] INFO  c.s.example.RequestLogger - "GET /test/ HTTP/1.1" 302

This example test server will respond with a simple HTML page on the root directory. It can also be used to do basic tests using the /test/ context. In this test context the following parameters are interpreted:

  • response_time: Time in milliseconds to delay the response - to test timeouts.
  • response_code: The HTTP response code to return in the response.
  • size: The size of the response body in bytes.

For example:

$ curl -D- "http://127.0.0.1:8800/test/?response_code=302&response_time=10&size=86"
HTTP/1.1 302 Found
Date: Sat, 01 Sep 2016 00:00:00 GMT
Location: /
Content-Length: 86
Server: Jetty(9.2.z-SNAPSHOT)