问题
I am developing a straightforward maven-based JavaEE application in IntelliJ IDEA, and obviously I would like to use Wildfly 8 for both development and production. I simply need to expose some entities through some RESTful web services. Those entities have bidirectional relationships, which leads to a loop when they are going to be serialized into JSON.
Newer versions of Jackson are able to handle this kind of situation with a special annotation. To get that to work, I need to exclude Wildfly's built-in JSON serializer / jackson provider / whatever it is and use the newer version that comes bundled with my application. I have followed the instructions I have found on the web and came up with this jboss-deployment-structure.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
<deployment>
<exclusions>
<module name="org.codehaus.jackson.jackson-jaxrs" />
<module name="org.codehaus.jackson.jackson-core-asl" />
<module name="org.codehaus.jackson.jackson-mapper-asl" />
<module name="org.codehaus.jackson.jackson-xc" />
</exclusions>
</deployment>
</jboss-deployment-structure>
The problem is, it doesn't work. Even when I set my pom.xml to something like this:
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.3.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.3.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson2-provider</artifactId>
<version>3.0.6.Final</version>
<scope>provided</scope>
</dependency>
</dependencies>
which clearly indicates that nothing should come bundled with my application, I still get this StackOverflowError (caused by the infinite loop) which roots in org.codehaus.jackson package. This is turn means that built-in version of Jackson is still in the works and is not excluded. How can I fix this?
Thanks in advance.
UPDATES
I changed the title because I guess the problem is even bigger. Either I am doing something terribly wrong or there is a serious problem with Wildfly.
I have created a pom.xml with all the jackson 2 libraries (com.fasterxml.jackson*) with a "compile" scope. The libraries are included in the WEB-INF/lib folder. I wrote a @Provider according to Jackson JAX-RS FAQ and I can verify that it is actually read by the JAX-RS implementation (RestEasy), simply because the deployment fails if I do not include jackson libraries in WEB-INF/lib with a ClassNotFoundException. However, I am still getting infinite recursion errors with org.codehaus.X (Jackson 1).
I don't care how, I just need a solution to fix this infinite recursion in Wildfly.
回答1:
The solution is to create a class which implement MessageBodyWriter<Object>
using Jackson's ObjectMapper
:
@Provider
@Produces("application/json")
public class JacksonMapper implements MessageBodyWriter<Object> {
@Override
public boolean isWriteable(Class<?> aClass, Type type, Annotation[] annotations, MediaType mediaType) {
return true;
}
@Override
public long getSize(Object object, Class<?> aClass, Type type, Annotation[] annotations, MediaType mediaType) {
return 0;
}
@Override
public void writeTo(Object object, Class<?> aClass, Type type, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> stringObjectMultivaluedMap, OutputStream outputStream)
throws IOException, WebApplicationException {
outputStream.write(new ObjectMapper().writeValueAsBytes(object));
}
}
There's no need for any exclusion or Wildfly-specific descriptors.
It doesn't matter if you include the dependencies or not (compile
or provided
scopes both work fine) as Jackson 2 is included in Wildfly. However, for an unknown reason, it is near to impossible to deactivate Jackson 1.
This solution brings Jackson 2 into the works. Now you can easily avoid serialization loops using the @JsonIdentityInfo
annotation. More info here.
来源:https://stackoverflow.com/questions/21395380/json-serialization-loop-infinite-recursion-in-wildfly