9

my first post on SO and expecting good stuff in return :-)

I have developed a small java restful services app and integrated with Swagger. I have @Controller -> @Service -> @Repository architecture. I have deployed on Glassfish (4.1.1), when I use Chrome's 'Advanced Rest Client', I am able to perfectly send and receive rest calls (GET/POST etc), but when I use Swagger, it throws the following exception 'after Controller returns the correct response'.

I have been struggling with this by changing the maven entry versions, changing the moxy jar, delting felix as suggested in some forums etc, none seem to help.

Here are more details ...

Exception:

  StandardWrapperValve[com.xxx.config.ApplicationConfig]: Servlet.service() for servlet com.xxx.config.ApplicationConfig threw exception
java.lang.ClassNotFoundException: com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector not found by com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider [130]
    at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1532)
    at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:75)
    at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1955)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)

Code:

@Controller
@Path("/document")
@Api(value = "/document", description = "Document Controller ")
public class DocumentController {

    @Inject
    DocumentService documentService;

    @GET
    @Path("/{id}")
    @Produces(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "Get Document.", notes = "Get Document Call")
    @ApiResponses(value = { @ApiResponse(code = 200, message = "OK"),
            @ApiResponse(code = 500, message = "Something wrong in Server") })
    public DtoDocument getDocument(@PathParam("id") Integer docId) {
        Document doc = documentService.getDocument(docId);
        DtoDocument dto = toDto(doc);
        return dto;
    }
}

@Service
@Transactional
public class DocumentService {

    @Inject
    DocumentRepository repository;

    public Document getDocument(Integer id) {
        return repository.getDocumentById(id);
    }

}

@Repository
public class DocumentRepository {

    public static final String COLLECTION_NAME = "document";

    @Inject
    private MongoTemplate mongoTemplate;

    public Document getDocumentById(Integer Id) {
        Document doc = getMongoTemplate().findOne(Query.query(Criteria.where("id").is(Id)), Document.class, COLLECTION_NAME);
        return doc;
    }

}

@ApplicationPath("/rest")
public class ApplicationConfig extends Application {

    @Override
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public Set<Class<?>> getClasses() {
        Set<Class<?>> resources = new java.util.HashSet();

        resources.add(com.wordnik.swagger.jaxrs.listing.ApiListingResource.class);
        resources.add(com.wordnik.swagger.jaxrs.listing.ApiDeclarationProvider.class);
        resources.add(com.wordnik.swagger.jaxrs.listing.ApiListingResourceJSON.class);
        resources.add(com.wordnik.swagger.jaxrs.listing.ResourceListingProvider.class);

        addRestResourceClasses(resources);

        return resources;
    }

    private void addRestResourceClasses(Set<Class<?>> resources) {
        // Custom resources in the project (all restful services)
        resources.add(com.xxx.web.rest.DocumentController.class);
    }

}

beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
    bean-discovery-mode="all">
</beans>

swagger entry in the pom.xml

<dependency>
            <groupId>com.wordnik</groupId>
            <artifactId>swagger-jersey-jaxrs_2.10</artifactId>
            <version>1.3.13</version>
            <exclusions>
                <exclusion>
                    <groupId>com.sun.jersey.contribs</groupId>
                    <artifactId>jersey-spring</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.sun.jersey</groupId>
                    <artifactId>jersey-client</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.sun.jersey</groupId>
                    <artifactId>jersey-server</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.sun.jersey</groupId>
                    <artifactId>jersey-core</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.sun.jersey</groupId>
                    <artifactId>jersey-servlet</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.sun.jersey</groupId>
                    <artifactId>jersey-multipart</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.codehaus.jackson</groupId>
                    <artifactId>jackson-mapper-asl</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.google.guava</groupId>
                    <artifactId>guava</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.fasterxml.jackson.module</groupId>
                    <artifactId>jackson-module-jaxb-annotations</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

Appreciate if anyone can tell me what exactly is the issue ... its been a frustrating week & am stuck with this, not making any progress.

rtnyc
  • 145
  • 1
  • 2
  • 10

5 Answers5

8

The stack trace mentions: java.lang.ClassNotFoundException: com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector not found by com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider

and you are excluding the JAXB annotation module:

<exclusion>
   <groupId>com.fasterxml.jackson.module</groupId>
   <artifactId>jackson-module-jaxb-annotations</artifactId>
</exclusion>

The exclusion means a dependency is not resolved, and therefore you'll get the ClassNotFoundException

beny23
  • 34,390
  • 5
  • 82
  • 85
  • I have actually tried not excluding & adding the jackson-module-jaxb-annotations-2.7.1.jar under glassfish/modules dir. Both didnot work. – rtnyc Feb 21 '16 at 17:10
  • for me, biggest question is : Why would the same work for another rest client and not with Swagger, that makes me think Swagger has its own route, my be somehow by-passing the glassfish classpath .. chance ? I mean it may have its own jackson-module-jaxb-annotations which is still overriding the glassfish jar file ... – rtnyc Feb 21 '16 at 17:31
5

Add 2 Dependency - it worked for me

   <dependency>
        <groupId>com.fasterxml.jackson.module</groupId>
        <artifactId>jackson-module-jaxb-annotations</artifactId>
        <version>2.10.1</version>
    </dependency>


    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <exclusions>
            <exclusion>
                <groupId>com.fasterxml.jackson.module</groupId>
                <artifactId>jackson-module-jaxb-annotations</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
4

This worked for me:

Steps: 1-Stop domain

2-Remove content of this folder: Glassfish\glassfish\domains\DOMAIN_NAME\osgi-cache\felix

3-In this folder: C:\Glassfish\glassfish\modules Substitute jackson libraries by the 2.4.4 version:

jackson-module-jaxb-annotations-2.4.4

jackson-jaxrs-json-provider-2.4.4

jackson-jaxrs-base-2.4.4

jackson-databind-2.4.4

jackson-annotations-2.4.4

jackson-core-2.4.4

4-Start domain

I hope it helps :-)

Roberto Rodriguez
  • 3,179
  • 32
  • 31
2

I don't know if this applies to 4.1.1 as well, but Glassfish 4.1 was shipped with old Jackson version and that was the cause to the issue you bring above.

To solve it, you'd have to force Glassfish to load Jackson 2.4.5 at least which is the minimum requirement for swagger-core. Upgrading Jackson in GlassFish 4.1 covers this procedure.

Community
  • 1
  • 1
Ron
  • 14,160
  • 3
  • 52
  • 39
  • thanks for the comment .. however, I tried putting the jar files in the modules directory, clean up felix & bounce GF, but still issue remained same. I have even modified 'asadmin' to pass classpath with the latest jar files, it still is overriding the classpath with the older versions that Swagger uses internally. I tried like this ... – rtnyc Feb 23 '16 at 03:56
  • export RUNTIME_CLASSPATH="/Users/xxx/Software/glassfish4/glassfish/modules/jackson-module-jaxb-annotations-2.7.1.jar" export RUNTIME_CLASSPATH="$RUNTIME_CLASSPATH:/Users/xxx/Software/glassfish4/glassfish/modules/jackson-core-2.7.1.jar" export RUNTIME_CLASSPATH="$RUNTIME_CLASSPATH:$CLASSPATH" exec "$JAVA" -cp RUNTIME_CLASSPATH -jar "$AS_INSTALL_LIB/client/appserver-cli.jar" "$@" – rtnyc Feb 23 '16 at 03:58
  • I'm afraid I don't know how to force GF to pick up a version. Is there a way you can validate which version of Jackson is loaded? The error you're getting is a strong indication that it's the wrong version (an old one as Jackson is mostly backwards compatible). – Ron Feb 23 '16 at 04:02
  • Ron, infact it worked after changing the classpath as I mentioned above. – rtnyc Feb 24 '16 at 00:51
  • It applies to 4.1.1 also. I resolved it by replacing the shipped jar with org.eclipse.persistence.moxy-2.7.0.jar – Dexter Dec 17 '17 at 21:31
0

My application is with springframework and I also had this problem. I noticed that different versions of springframework and Jackson are incompatible with each other. The problem was solved by removing all Jackson dependencies from the pom file.

Shapur
  • 498
  • 7
  • 17