Reputation: 2769
I have been searching for a solution for this issue for multiple hours today and many hours yesterday so I decided to address it here, although it seems a stupid issue.
Situation: I have a Google AppEngine project setup in Eclipse Java EE. It's there for multiple weeks everything runs fine, I can deploy to App Engine and test in Eclipse without probs.
Now I need to add JAR packages for f.e. JSON support and Google Visualization API. I tried JSON a week ago and because it failed, I just downloaded the source files and added them to my own source. But now with the Visualizations thing, it are too much source files so I need the JARs working.
What I did:
What happened: All went fine, I could import the classes and create subclasses from them without having errors. So it's clear that Eclipse recognized the classes' existence and Eclipse had them imported successfully.
Then I tried to build it (Debug Mode) and got following error (the one I got with JSON too):
Nov 27, 2011 11:57:48 AM com.google.apphosting.utils.jetty.JettyLogger warn
WARNING: failed chartDataServlet: java.lang.NoClassDefFoundError: com/google/visualization/datasource/DataSourceServlet
Nov 27, 2011 11:57:48 AM com.google.apphosting.utils.jetty.JettyLogger warn
WARNING: failed com.google.appengine.tools.development.DevAppEngineWebAppContext@727db937{/,/Volumes/Data/eclipse_workspace/kulStats/war}: java.lang.NoClassDefFoundError: com/google/visualization/datasource/DataSourceServlet
Nov 27, 2011 11:57:48 AM com.google.apphosting.utils.jetty.JettyLogger warn
WARNING: failed JettyContainerService$ApiProxyHandler@409bad4f: java.lang.NoClassDefFoundError: com/google/visualization/datasource/DataSourceServlet
Nov 27, 2011 11:57:48 AM com.google.apphosting.utils.jetty.JettyLogger warn
WARNING: Error starting handlers
java.lang.NoClassDefFoundError: com/google/visualization/datasource/DataSourceServlet
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at com.google.appengine.tools.development.IsolatedAppClassLoader.loadClass(IsolatedAppClassLoader.java:176)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at org.mortbay.util.Loader.loadClass(Loader.java:91)
at org.mortbay.util.Loader.loadClass(Loader.java:71)
at org.mortbay.jetty.servlet.Holder.doStart(Holder.java:73)
at org.mortbay.jetty.servlet.ServletHolder.doStart(ServletHolder.java:242)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.mortbay.jetty.servlet.ServletHandler.initialize(ServletHandler.java:685)
at org.mortbay.jetty.servlet.Context.startContext(Context.java:140)
at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
at org.mortbay.jetty.Server.doStart(Server.java:224)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at com.google.appengine.tools.development.JettyContainerService.startContainer(JettyContainerService.java:191)
at com.google.appengine.tools.development.AbstractContainerService.startup(AbstractContainerService.java:239)
at com.google.appengine.tools.development.DevAppServerImpl.start(DevAppServerImpl.java:146)
at com.google.appengine.tools.development.DevAppServerMain$StartAction.apply(DevAppServerMain.java:164)
at com.google.appengine.tools.util.Parser$ParseResult.applyArgs(Parser.java:48)
at com.google.appengine.tools.development.DevAppServerMain.<init>(DevAppServerMain.java:113)
at com.google.appengine.tools.development.DevAppServerMain.main(DevAppServerMain.java:89)
Caused by: java.lang.ClassNotFoundException: com.google.visualization.datasource.DataSourceServlet
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at com.google.appengine.tools.development.IsolatedAppClassLoader.loadClass(IsolatedAppClassLoader.java:176)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
... 35 more
I don't know if the fact that it prints out the class with slashed instead of with dots is part of the issue: com/google/visualization/datasource/DataSourceServlet
.
In the second part he does use dots.
I looked for an issue a very long time, and heard things about classpath file. My .classpath file looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" output="test-classes" path="test"/>
<classpathentry kind="con" path="com.google.appengine.eclipse.core.GAE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="com.google.appengine.eclipse.core.GAE_CONTAINER/App Engine (1)"/>
<classpathentry kind="lib" path="war/WEB-INF/lib/chart-datasource/lib/commons-lang-2.4.jar"/>
<classpathentry kind="lib" path="war/WEB-INF/lib/chart-datasource/lib/commons-logging-1.1.1.jar"/>
<classpathentry kind="lib" path="war/WEB-INF/lib/chart-datasource/lib/opencsv-1.8.jar"/>
<classpathentry kind="lib" path="war/WEB-INF/lib/chart-datasource/visualization-datasource-1.1.1.jar"/>
<classpathentry kind="output" path="war/WEB-INF/classes"/>
</classpath>
Only the war/WEB-INF/classes
does not exist..
Ow, another thing: I found documents about App Engine specifically and they sometimes mentioned the war/WEB-INF/lib
folder, so I tried putting it there as well. Of course after deleting from build path and reading after the move. (It's that version of the classpath file I've pasted).
Does anyone have an idea how this can be solved? Summary: Eclipse recognizes the imported JARs, but build fails for some reason...
EDIT: solution I found the following:
Upvotes: 18
Views: 16186
Reputation: 258
Might be "a little" too late for this, but in eclipse you don't have to manually copy. Right-Click on project -> Build Path -> Configure Build Path... -> select Deployment Assembly (left). Add your jars here and they will be included when deploying.
Upvotes: 0
Reputation: 4249
Copy paste the .jar files to war/WEB-INF/lib and then go to Properties(of the project in Eclipse) --> Java Build Path --> Add JARs --> Select the related .jars from the current project. You should be all set!
Upvotes: 1
Reputation: 7830
You still need to add the jar files to the java build path to avoid compilation errors after adding the files to the war/WEB-INF/lib folder!
Upvotes: 2
Reputation: 39
this solution that:
Upvotes: 4
Reputation: 23171
You are on the right track. Since the app when deployed to appengine is packaged as a war (web application archive), library jars need to be in WEB-INF/lib. You should ensure your jars are there and then add those jars to your eclipse build path. Try doing a "clean" operation on the project and re-building it to ensure the libraries is in the package.
Upvotes: 21