Use new version of Jackson JSON with Jersey

Guice Module:

import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
import com.google.inject.Singleton;
import com.sun.jersey.guice.JerseyServletModule;
import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
 
public final class JerseyModule extends JerseyServletModule
{
   @Override
   protected void configureServlets()
   {
      bind(JacksonJaxbJsonProvider.class).in(Singleton.class);
      filter("/*").through(GuiceContainer.class);
   }
}

And the Maven pom:

<dependency>
   <groupId>com.fasterxml.jackson.jaxrs</groupId>
   <artifactId>jackson-jaxrs-json-provider</artifactId>
   <version>2.0.5</version>
</dependency>

Jersey + Guice ExceptionMapper

import com.google.inject.Singleton;
 
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
 
@Provider
@Singleton
public class MyExceptionMapper implements ExceptionMapper<MyException>
{
   @Override
   public Response toResponse(final MyException exception)
   {
      return Response.status(Status.NOT_FOUND).entity(exception.getMessage()).build();
   }
}
import com.google.inject.AbstractModule;
 
public class MyModule extends AbstractModule
{
   @Override
   protected void configure()
   {
      bind(MyExceptionMapper.class);
   }
}

maven-enunciate-plugin java 7

It is possible to get the maven-enuniciate-plugin to work with Java 7. You might see an error like this:

[ERROR] Failed to execute goal org.codehaus.enunciate:maven-enunciate-plugin:1.24:docs (default) on project Pluto: Execution default of goal org.codehaus.enunciate:maven-enunciate-plugin:1.24:docs failed: A required class was missing while executing org.codehaus.enunciate:maven-enunciate-plugin:1.24:docs: com/sun/mirror/apt/AnnotationProcessorFactory

Looks like the tools.jar is not available in Java 7 by default. You need to add it as a dependency of the enunciate plugin. If you are using some other (non sun/oracle) JDK then the solution will be different, you may need to use maven profiles for each JDK you want to use.

You can add tools.jar as a dependency like this:

<plugin>
   <groupId>org.codehaus.enunciate</groupId>
   <artifactId>maven-enunciate-plugin</artifactId>
   <configuration>
      <configFile>src/main/doc/enunciate.xml</configFile>
   </configuration>
   <executions>
      <execution>
         <goals>
            <goal>docs</goal>
         </goals>
         <configuration>
            ...
         </configuration>
      </execution>
   </executions>
   <dependencies>
      <dependency>
         <groupId>com.sun</groupId>
         <artifactId>tools</artifactId>
         <version>${java.version}</version>
         <scope>system</scope>
         <systemPath>${java.home}/../lib/tools.jar</systemPath>
      </dependency>
   </dependencies>
</plugin>

You will now get a warning, which hopefully enunciate will fix sometime before java 8!

warning: The apt tool and its associated API are planned to be
removed in the next major JDK release.  These features have been
superseded by javac and the standardized annotation processing API,
javax.annotation.processing and javax.lang.model.  Users are
recommended to migrate to the annotation processing features of
javac; see the javac man page for more information.

Update Glassfish 3.0 to use Jersey 1.3

In order to update Glassfish 3.0 to use Jersey 1.3 we had to write over the Jersey files in the “modules” subfolder of the glassfish installation.

Here are some maven dependencies for the required files:

   <properties>
      <jersey.version>1.3</jersey.version>
      <jackson.version>1.5.6</jackson.version>
   </properties>
   <dependencies>
      <dependency>
         <groupId>com.sun.jersey</groupId>
         <artifactId>jersey-server</artifactId>
         <version>${jersey.version}</version>
      </dependency>
      <dependency>
         <groupId>com.sun.jersey</groupId>
         <artifactId>jersey-client</artifactId>
         <version>${jersey.version}</version>
      </dependency>
      <dependency>
         <groupId>com.sun.jersey</groupId>
         <artifactId>jersey-json</artifactId>
         <version>${jersey.version}</version>
      </dependency>
      <dependency>
         <groupId>com.sun.jersey.glassfish.v3.osgi</groupId>
         <artifactId>jersey-gf-server</artifactId>
         <version>${jersey.version}</version>
      </dependency>
     <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-xc</artifactId>
        <version>${jackson.version}</version>
     </dependency>
     <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-jaxrs</artifactId>
        <version>${jackson.version}</version>
     </dependency>
     <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-core-asl</artifactId>
        <version>${jackson.version}</version>
     </dependency>
     <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>${jackson.version}</version>
     </dependency> 
   </dependencies>

And here is a assembly plugin snippet which will rename the dependencies the way glassfish expects them to be named

   <dependencySets>
      <dependencySet>
         <outputFileNameMapping>${artifact.artifactId}.${artifact.extension}</outputFileNameMapping>
         <outputDirectory>modules</outputDirectory>
      </dependencySet>
   </dependencySets>

Serving static content and Jersey

If you want to serve static content from the same WAR as Jersey resources, it is possible to configure Jersey to run as a filter rather than a Servlet.

You can then define the property com.sun.jersey.config.property.WebPageContentRegex to exclude URLs matching the regular expression from being handled by Jersey. Instead request matching the pattern will fall through to the next filter and eventually the default Servlet, which can respond with your static content in the normal way.

   <filter>
      <filter-name>jerseyFilter</filter-name>
      <filter-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</filter-class>
      <init-param>
         <param-name>com.sun.jersey.config.property.WebPageContentRegex</param-name>
         <param-value>/static/.*</param-value>
      </init-param>
   </filter>
   <filter-mapping>
      <filter-name>jerseyFilter</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>