Question

There seem to be a number of questions on SO in this area, but I haven't been able to find one with exactly my scenario:

I have two projects in Eclipse: Core and Interface.

In the Core project I have 5 .jar files that contain useful classes and so on. Let's say that one of the jars is called DAO.

In the Interface project I have gone into the Build Path (via Right-Click > Build Path > Configure Build Path...) and gone to the Projects section, then added the Core project.

At first the Interface project still couldn't see the classes within the DAO.jar, which confused me, but I found that by going into the Core project's build path and checking the box next to DAO.jar (for export) the compiler stopped complaining and I was able to use classes from DAO.jar.

(Just to be specific, I'm making a Java webapp with Servlets and JSPs and so on, running on a local Tomcat server.)

I build the project, but when I navigate to a Servlet where the Get method involves a class from DAO.jar, I get a NoClassDefFoundError. Here's the stack trace:

java.lang.ClassNotFoundException: dao.DirectSqlVisitorImpl
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1702)
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1547)
    java.lang.ClassLoader.defineClass1(Native Method)
    java.lang.ClassLoader.defineClass(ClassLoader.java:792)
    java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2928)
    org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1174)
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1669)
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1547)
    interface.DonationsServletController.doGet(DonationsServletController.java:79)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

What I've gathered is that the JRE can't find the definition of the DirectSqlVisitorImpl class at runtime, even though the Eclipse error-checking lets it fly now that I've configured my Build Path in the (seemingly) correct fashion.

So what do I need to do to make sure that the jar gets pulled into the Interface project via the Core project?

As a note, I'd prefer not to do something like adding the jars directly to the Interface project, as the Core project could be used by other projects, and I'd like to have modifications to the Core project cascade to all dependent projects.

Thanks!

Was it helpful?

Solution 3

Although the other answers here may be useful in some respect, overall they are incomplete.

I did find a way to resolve my problem and get rid of this error, though it does not quite accomplish the cascading system that I had hoped for.

It seems that dsh was right in that my issue is the difference between the classpath used by eclipse as it compiles my code, and the classpath used at runtime by tomcat. Or more specifically, the DAO jar file exists within my project, but doesn't get deployed to the tomcat server.

To solve this, I went to my Project's Properties > Web Deployment Assembly > Add... > Archives from Workspace > Add...

I then selected the DAO jar and added it in. The project then built and ran fine, without the NoClassDefFoundError. So my problem was solved, essentially.

However, I'm not sure what would happen if I changed/updated the jar files in the Core project.

OTHER TIPS

Your issue is the difference between the classpath used by eclipse as it compiles your code, and the classpath used at runtime by tomcat. I have dealt with this in an OSGi-based desktop application, though I haven't, yet, learned how to package a JavaEE application as separate components. However, I can tell you that the path to the answer is to learn how to build the WAR and/or EAR files so that the libraries in one are exported by the bundle and the other can import them.

One solution may be to add the dependent jars to the tomcat lib folder. i.e /lib.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top