问题
I created a very simple Objectify/Endpoints class.
import static mypackage.OfyService.ofy;
import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.googlecode.objectify.Work;
@Api(name = "testapi", version = "1")
public class TestEndpoint {
@ApiMethod(name = "test.insert")
public TestEntity insert(final TestEntity test) {
test.setName("test");
return ofy().transact(new Work<TestEntity>() {
public TestEntity run() {
ofy().save().entities(test).now();
return test;
}
});
}
}
The TestEntity is trivial (getters & setters excluded for brevity):
@Entity
public class TestEntity {
@Id long id;
String name;
}
And I use the OfyService pattern from http://code.google.com/p/objectify-appengine/wiki/BestPractices#Use_Your_Own_Service
However, when I try to generate the Endpoints library, I get a ClassNotFoundException for Work. Full stacktrace follows:
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.google.gdt.eclipse.appengine.swarm.wizards.helpers.SwarmApiCreator.createSwarmApi(SwarmApiCreator.java:97)
at com.google.gdt.eclipse.appengine.swarm.wizards.helpers.SwarmServiceCreator.create(SwarmServiceCreator.java:196)
at com.google.gdt.eclipse.appengine.swarm.wizards.HandleGaeProjectChange.gaeProjectRebuilt(HandleGaeProjectChange.java:64)
at com.google.appengine.eclipse.core.properties.ui.GaeProjectChangeNotifier.build(GaeProjectChangeNotifier.java:77)
at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:728)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:199)
at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:239)
at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:292)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:295)
at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:351)
at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:374)
at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:143)
at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:241)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:53)
Caused by: java.lang.NoClassDefFoundError: com/googlecode/objectify/Work
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2427)
at java.lang.Class.getDeclaredMethods(Class.java:1791)
at com.google.api.server.spi.MethodHierarchyReader.addServiceMethods(MethodHierarchyReader.java:174)
at com.google.api.server.spi.MethodHierarchyReader.readMethodHierarchyIfNecessary(MethodHierarchyReader.java:44)
at com.google.api.server.spi.MethodHierarchyReader.getEndpointOverrides(MethodHierarchyReader.java:99)
at com.google.api.server.spi.config.annotationreader.ApiConfigAnnotationReader.readApiMethods(ApiConfigAnnotationReader.java:184)
at com.google.api.server.spi.config.annotationreader.ApiConfigAnnotationReader.readEndpoint(ApiConfigAnnotationReader.java:82)
at com.google.api.server.spi.tools.AnnotationApiConfigGenerator.generateForService(AnnotationApiConfigGenerator.java:242)
at com.google.api.server.spi.tools.AnnotationApiConfigGenerator.generateConfigObjects(AnnotationApiConfigGenerator.java:227)
at com.google.api.server.spi.tools.AnnotationApiConfigGenerator.generateConfig(AnnotationApiConfigGenerator.java:176)
... 20 more
Caused by: java.lang.ClassNotFoundException: com.googlecode.objectify.Work
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 java.lang.ClassLoader.loadClass(ClassLoader.java:247)
... 31 more
I don't have similar problems with other Objectify classes I include in Endpoint classes (eg Ref, etc), and I have Eclipse (4.2) project set up to include the Objectify 4.0b1 library.
I get exactly the same error if I change the Endpoints class to use VoidWork:
@Api(name = "testapi", version = "1")
public class TestEndpoint {
@ApiMethod(name = "test.insert")
public TestEntity insert(TestEntity test) {
final TestEntity newTest = new TestEntity();
newTest.setName(test.getName());
ofy().transact(new VoidWork() {
public void vrun() {
ofy().save().entities(newTest).now();
}
});
return newTest;
}
}
回答1:
You will have to include the objectify jar in the classpatch for endpoints. This is found in endpoints.sh (in linux, not sure of the windows equivalent). There is an entry in the script for classpath - just add the location of the objectify jar file.
回答2:
I added the Objectify jar through Build Path Libraries pointing at WEB-INF\lib
回答3:
Details can be found here for the maven setup. If you just want to get up and running fast, go [here](http://repo1.maven.org/maven2/com/googlecode/objectify/objectify/] and click on the latest version of Objectify (currently 4.0rc2/
), then download the objectify-*version*.jar
file.
In Eclipse: add the objectify.jar
as well as guava.jar to [Project]/war/WEB-INF/lib
. Right click on your project. Go to Properties -> Java Build Path -> Libraries. Click "Add Jars…", navigate to the aforementioned /lib
folder, click OK (do this once for each jar).
来源:https://stackoverflow.com/questions/14563680/google-cloud-endpoints-doesnt-know-about-the-work-class-from-objectify-4-transa