Marshaling / Demarshaling JSON with Java EE 7 / Glassfish 4.1 results in null object

I upgraded to Java EE 7 from Java EE 6 and some of my REST services have stopped working. By all accounts, it looks like this change happened when Jersey switched from Jackson to MOXy in Java EE 7.

My service looks like this:

@Stateless
@Path("access")
public class AccessFacadeREST extends AbstractFacade<Access> {
    @PersistenceContext(unitName = "AccessServerPU")
    private EntityManager em;

    public AccessFacadeREST() {
        super(Access.class);
    }

    @POST
    @Consumes({"application/xml", "application/json"})
    @Produces({"application/xml", "application/json"})
    public ObjectResponse create(@Context HttpServletRequest requestContext,
                                 @Context SecurityContext context,
                                 ObjectRequest<Access> req) {
        req.setHostname(requestContext.getRemoteAddr());
        return AccessValidation.create(em, req);
    }
}

      

Here req

is null and therefore generates a NullPointerException

when presented using JSON. It works great when presented XML. ObjectRequest

is a generic class that I use to wrap a request with an authentication content standard for several different types of requests.

I tested a similar service @GET

to return an instance ObjectRequest<Access>

filled with garbage data. It works well again when using XML, but returns null

(no exception) when I try to return JSON.

I found Java EE7 REST Server no longer returns List as JSON to understand the underlying problem, but didn't figure out how I can get this to work in my situation. My class ApplicationConfig

looks like this:

@javax.ws.rs.ApplicationPath("webresources")
public class ApplicationConfig extends Application {

    @Override
    public Set<Object> getSingletons() {
        Set<Object> set = new HashSet<>();
        log.info("Enabling custom Jackson JSON provider");
        set.add(new JacksonJsonProvider());
        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<>();
        addRestResourceClasses(resources);
        return resources;
    }

    private void addRestResourceClasses(Set<Class<?>> resources) {
        resources.add(AccessFacadeREST.class);
    }
}

      

I feel like I need to configure the ApplicationConfig class to use Jackson, but I can't see how to generalize the solutions I've found to cover my situation. So there are actually two questions:

  • Did I correctly characterize the underlying problem as a kind of flaw in MOXy?
  • How can I fix this using MOXy or Jackson (I don't have a preference as long as it works)?

Setting:

  • Netbeans 8.0.2
  • Glassfish 4.1
  • JDK 8 / JRE 8U25 (64 bit)

Edit in response to the question below ...

The project pom.xml

has the following entry:

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

      

+3


source to share


1 answer


You should solve this problem by disabling MOXy (register the class below in getClasses()

) and get rid of the singleton set.add(new JacksonJsonProvider());

. I use this for all my GF4 projects to get Jersey to use Jackson.



/**
 * Feature to disable Moxy and Enable Jackson processing
 */
private static class Jackson2Feature implements Feature {

    @Override
    public boolean configure(FeatureContext context) {
        final String disableMoxy = PropertiesHelper.getPropertyNameForRuntime(
                CommonProperties.MOXY_JSON_FEATURE_DISABLE,
                context.getConfiguration().getRuntimeType());
        context.property(disableMoxy, true);

        // add the default Jackson exception mappers and allow jaxb annotations
        context.register(JsonParseExceptionMapper.class);
        context.register(JacksonJaxbJsonProvider.class, MessageBodyReader.class, MessageBodyWriter.class);
        return true;
    }
}

      

+3


source







All Articles