5

The following example works in a Java EE6 (Glassfish3) project of mine but failed after I switched to Java EE7 (Glassfish4). The HTTP request returns "500 Internal Error" without any message in the Glassfish server log. The project was setup using NetBeans8 as Maven Web Project and has no special dependencies, beans.xml or other configuration.

@RequestScoped
@Path("generic")
public class GenericResource {

    @GET
    @Path("ping")
    @Produces(APPLICATION_JSON)
    public List<String> debugPing() {
        return Arrays.asList("pong");
    }

And then:

$ curl -v  http://localhost:8080/mavenproject2/webresources/generic/ping
> GET /mavenproject2/webresources/generic/ping HTTP/1.1
...
< HTTP/1.1 500 Internal Server Error

As as I understand, all REST handling is done by the Jackson reference implementation and that Jackson uses Jersey as underlaying JSON library. One of the two is supposed to have some kind of provider for all basic data types. Only custom made classes need a self written ObjectMapper. Are these concepts still correct?

lathspell
  • 3,040
  • 1
  • 30
  • 49
  • You have it backwards, but yes, the concepts should still be correct. Jersey is the reference implementation of JAX-RS, and Jackson is the JSON library. – Eric Stein Apr 01 '14 at 13:02

1 Answers1

4

It took me some hours but I finally solved this question myself. First fact is that the Glassfish4 JAX-RS implementation "Jersey" as switched its underlying JSON library from Jackson 1.x to Eclipselink MOXy. The latter seems not be able to convert Lists, Arrays and arbitrary POJOs to JSON out of the box. Therefore I tried to force JAX-RS to use Jackson 2.x and disable MOXy.

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

// This is Jackson 2.x, Jackson 1.x used org.codehaus.jackson!
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@ApplicationPath("rest")
public class RestConfig extends Application {

    private final static Logger log = LoggerFactory.getLogger(RestConfig.class);

    @Override
    public Set<Object> getSingletons() {
        Set<Object> set = new HashSet<>();
        log.info("Enabling custom Jackson JSON provider");
        set.add(new JacksonJsonProvider() /* optionally add .configure(SerializationFeature.INDENT_OUTPUT, true) */);
        return set;
    }

    @Override
    public Map<String, Object> getProperties() {
        Map<String, Object> map = new HashMap<>();
        log.info("Disabling MOXy JSON provider");
        map.put("jersey.config.disableMoxyJson.server", true);
        return map;
    }

    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> resources = new java.util.HashSet<>();
        // ... add your own REST enabled classes here ...
        return resources;
    }
}

My pom.xml contains:

    <dependency>
        <!-- REST (Jackson as JSON mapper) -->
        <groupId>com.fasterxml.jackson.jaxrs</groupId>
        <artifactId>jackson-jaxrs-json-provider</artifactId>
        <version>2.2.3</version>
    </dependency>
    <dependency>
        <!-- REST (Jackson LowerCaseWithUnderscoresStrategy etc.) -->
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.2.3</version>
    </dependency>

Hope this helps someone!

lathspell
  • 3,040
  • 1
  • 30
  • 49
  • The propery name in the above code fragment is wrong! To disable Moxy, set `jersey.config.server.disableMoxyJson` to `true` (*not* `jersey.config.disableMoxyJson.server`, this does not do anything!). In the above config, both Moxy and Jackson are enabled which means the Moxy will handle serialization for types it can serialize (most non-primitive types except for `Object`, `List`, `Map` and a few others) and Jackson will deal with everything Moxy cannot serialize. If the Moxy is disabled correctly, Jackson will handle *everything*, including classes that Moxy would otherwise handle. – Frans Mar 10 '17 at 08:15