Google AppEngineは初めてです。過去3日間、プロジェクトでエラーが発生しました。
Google AppEngineプロジェクトでJPA2.0をセットアップしました。クライアントはAndroidアプリケーションです。エンティティを挿入しようとすると、Google AppEngineログに次の警告/エラーが表示されます。また、エンティティを挿入できません。
CLASSPATHにpersistence.xmlファイルを配置しました。また、プロジェクトのJPA構成で「注釈付きクラスを自動的に検出する」オプションを使用しています。ここに関連するコードを入力するのを忘れた場合はお知らせください。
ログ:
com.google.api.server.spi.SystemService invokeServiceMethod: Could not initialize class com.sample.EMF
java.lang.NoClassDefFoundError: Could not initialize class com.sample.EMF
at com.sample.GroupEndpoint.getEntityManager(GroupEndpoint.java:159)
at com.sample.GroupEndpoint.insertGroup(GroupEndpoint.java:96)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:45)
at com.google.api.server.spi.SystemService.invokeServiceMethod(SystemService.java:359)
at com.google.api.server.spi.SystemServiceServlet.execute(SystemServiceServlet.java:127)
at com.google.api.server.spi.SystemServiceServlet.doPost(SystemServiceServlet.java:85)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:437)
at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:444)
at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:188)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:308)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:300)
at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:441)
at java.lang.Thread.run(Thread.java:724)
私のエンティティクラス:
package com.sample;
import javax.persistence.Basic;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import com.google.appengine.api.datastore.Key;
@Entity
public class Group {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Key key;
private String name;
@Basic
@ManyToOne
private User owner;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User getOwner() {
return owner;
}
public void setOwner(User owner) {
this.owner = owner;
}
public Key getKey() {
return key;
}
}
私のエンドポイントクラス:パッケージcom.sample; インポートjava.util.List;
import javax.annotation.Nullable;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.Query;
import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.config.ApiNamespace;
import com.google.api.server.spi.response.CollectionResponse;
import com.google.appengine.api.datastore.Cursor;
import com.google.appengine.datanucleus.query.JPACursorHelper;
@Api(name = "groupendpoint", namespace = @ApiNamespace(ownerDomain = "sample.com", ownerName = "sample.com", packagePath = ""))
public class GroupEndpoint {
/**
* This method lists all the entities inserted in datastore.
* It uses HTTP GET method and paging support.
*
* @return A CollectionResponse class containing the list of all entities
* persisted and a cursor to the next page.
*/
@SuppressWarnings({ "unchecked", "unused" })
@ApiMethod(name = "listGroup")
public CollectionResponse<Group> listGroup(
@Nullable @Named("cursor") String cursorString,
@Nullable @Named("limit") Integer limit) {
EntityManager mgr = null;
Cursor cursor = null;
List<Group> execute = null;
try {
mgr = getEntityManager();
Query query = mgr.createQuery("select from Group as Group");
if (cursorString != null && cursorString != "") {
cursor = Cursor.fromWebSafeString(cursorString);
query.setHint(JPACursorHelper.CURSOR_HINT, cursor);
}
if (limit != null) {
query.setFirstResult(0);
query.setMaxResults(limit);
}
execute = (List<Group>) query.getResultList();
cursor = JPACursorHelper.getCursor(execute);
if (cursor != null)
cursorString = cursor.toWebSafeString();
// Tight loop for fetching all entities from datastore and accomodate
// for lazy fetch.
for (Group obj : execute)
;
} finally {
mgr.close();
}
return CollectionResponse.<Group> builder().setItems(execute)
.setNextPageToken(cursorString).build();
}
/**
* This method gets the entity having primary key id. It uses HTTP GET method.
*
* @param id the primary key of the java bean.
* @return The entity with primary key id.
*/
@ApiMethod(name = "getGroup")
public Group getGroup(@Named("id") Long id) {
EntityManager mgr = getEntityManager();
Group group = null;
try {
group = mgr.find(Group.class, id);
} finally {
mgr.close();
}
return group;
}
/**
* This inserts a new entity into App Engine datastore. If the entity already
* exists in the datastore, an exception is thrown.
* It uses HTTP POST method.
*
* @param group the entity to be inserted.
* @return The inserted entity.
*/
@ApiMethod(name = "insertGroup")
public Group insertGroup(Group group) {
EntityManager mgr = getEntityManager();
try {
mgr.persist(group);
} finally {
mgr.close();
}
return group;
}
/**
* This method is used for updating an existing entity. If the entity does not
* exist in the datastore, an exception is thrown.
* It uses HTTP PUT method.
*
* @param group the entity to be updated.
* @return The updated entity.
*/
@ApiMethod(name = "updateGroup")
public Group updateGroup(Group group) {
EntityManager mgr = getEntityManager();
try {
if (!containsGroup(group)) {
throw new EntityNotFoundException("Object does not exist");
}
mgr.persist(group);
} finally {
mgr.close();
}
return group;
}
/**
* This method removes the entity with primary key id.
* It uses HTTP DELETE method.
*
* @param id the primary key of the entity to be deleted.
*/
@ApiMethod(name = "removeGroup")
public void removeGroup(@Named("id") Long id) {
EntityManager mgr = getEntityManager();
try {
Group group = mgr.find(Group.class, id);
mgr.remove(group);
} finally {
mgr.close();
}
}
private boolean containsGroup(Group group) {
EntityManager mgr = getEntityManager();
boolean contains = true;
try {
Group item = mgr.find(Group.class, group.getKey());
if (item == null) {
contains = false;
}
} finally {
mgr.close();
}
return contains;
}
private static EntityManager getEntityManager() {
return EMF.get().createEntityManager();
}
}
EMFクラス:パッケージcom.sample; インポートjavax.persistence.EntityManagerFactory; インポートjavax.persistence.Persistence;
public final class EMF {
private static EntityManagerFactory emfInstance;
private EMF() {
}
public static EntityManagerFactory get() {
if(emfInstance == null) {
emfInstance = Persistence
.createEntityManagerFactory("transactions-optional");
}
return emfInstance;
}
}
永続性.xmlファイル:
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
<persistence-unit name="transactions-optional">
<provider>org.datanucleus.api.jpa.PersistenceProviderImpl</provider>
<properties>
<property name="datanucleus.NontransactionalRead" value="true"/>
<property name="datanucleus.NontransactionalWrite" value="true"/>
<property name="datanucleus.ConnectionURL" value="appengine"/>
<property name="datanucleus.singletonEMFForName" value="true"/>
</properties>
</persistence-unit>
</persistence>
更新:エンドポイントとpersistence.xml、EMFはプラグインによって生成されました。しかし、JPAを設定すると、これらのエラーが発生し、これを解決する方法がわかりません。
私はついに問題を解決しました。私がしたことをあなたに知らせるためだけに...
特に:persistence.xmlとその場所。また、注釈付きエンティティの自動トレースを信頼していなかったため、persistence.xmlを次のように変換しました。
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="transactions-optional">
<provider>org.datanucleus.api.jpa.PersistenceProviderImpl</provider>
<class>com.sample.DeviceInfo</class>
<class>com.sample.Group</class>
<class>com.sample.User</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="datanucleus.NontransactionalRead" value="true" />
<property name="datanucleus.NontransactionalWrite" value="true" />
<property name="datanucleus.ConnectionURL" value="appengine" />
<property name="datanucleus.singletonEMFForName" value="true" />
<property name="javax.persistence.query.timeout" value="5000" />
<property name="datanucleus.datastoreWriteTimeout" value="10000" />
</properties>
</persistence-unit>
</persistence>
また、適切なフォルダを指すようにクラスパスを修正しました。
私を助けてくれたみんなに感謝します!
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加