0

I have a servlet, powered by Tomcat 8, which calls for a static method to perform JSON parsing with Jackson 2.9.6.

During the code execution:

JSONData parsedJSONData = PDFGenerator.parseJSONDocument(jsonDocument);

I get:

java.lang.ClassNotFoundException: com.fasterxml.jackson.core.JsonProcessingException

It's important to note, that servlet class and PDFGenerator class are located in different packages but with public access modifiers.

I tried to add dependencies to the root of the project via pom.xml:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.6</version>
</dependency>

but it doesn't help.

In my project I'm not using Maven, rather just added needed libraries via classpath.

What's strange is that such exception appears only when I try to call PDFGenerator.parseJSONDocument(jsonDocument) from a servlet, execution from a regular Java-class works smoothly.

What and where should I add in order to be able calling a static method with the JSON parser functionality based on a FasterXML/Jackson JSON library?

2
  • 1
    This sort of problem is usually caused by packaging issues with your code associated with the servlet engine classloader(s). How is your code packaged when installed into the servlet engine? Which servlet engine(s) are you using when you get the error? Commented Jul 4, 2018 at 8:19
  • @GregT., I'm using Tomcat 8 to run a servlets. Servlet class and PDFGenerator class are located in different packages but with public access modifiers. Commented Jul 4, 2018 at 8:30

1 Answer 1

1

This problem is almost certainly caused by classloaders within your servlet container (Tomcat 8.x) being unable to locate the library/JAR for Jackson. The way classes/libs are loaded within servlet containers is different than a standard classpath declaration from a standalone Java application. This is why you are seeing the error from the servlet engine but not during your direct execution of the class. Here is the general documentation on how Tomcat 8.x handles classloading:

https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

As a general rule, to help prevent such issues in the first place, its a good idea to deploy your servlets within a "webapp" container including all required libraries (the appropriate versions of required JAR's, etc.). Doing this isolates your servlets under a single classloader and automatically locates them in the correct hierarchy. See this portion of the linked documentation:

WebappX — A class loader is created for each web application that is deployed in a single Tomcat instance. All unpacked classes and resources in the /WEB-INF/classes directory of your web application, plus classes and resources in JAR files under the /WEB-INF/lib directory of your web application, are made visible to this web application, but not to other ones.

FYI, there are other ways to do this with enterprise-class web applications, but we're not talking about that here.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the link to the reference. The one-line solution is to copy all required JARs to the /WEB-INF/lib and restart Tomcat.
Yes, that will resolve the dependency. Just keep in mind that it's only a quick-fix. If you start running more servlets on the same Tomcat instance later, you could have dependency conflicts due to shared classloaders (unless you use a Webapp deployment).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.