JPA с Google Cloud SQL NoClassDefFoundError: java.util.prefs.Preferences является ограниченным классом

Я использую JPA с GAE/Google Cloud SQL и настроил все в соответствии с документами Google. Я могу просматривать свои объекты JPA в Eclipse, и приложение работает нормально, за исключением случаев, когда я пытаюсь сделать:

EntityManager em = EMF.get().createEntityManager();

Внутри EMF я делаю:

private static final EntityManagerFactory emfInstance = Persistence.createEntityManagerFactory("MyApp");

... и это то, что вызывает ошибки. Это правильный способ приобрести EntityManagerFactory?

Ниже приведена трассировка. Я также вставил содержимое persistence.xml ниже трассировки, но он был сгенерирован автоматически, и я думаю, что это правильно. Я не понимаю, почему Preferences ограничены, поскольку я использовал рекомендуемый Google способ доступа к EntityManagerFactory.

java.lang.NoClassDefFoundError: java.util.prefs.Preferences is a restricted class. Please see the Google  App Engine developer's guide for more details.
    at com.google.appengine.tools.development.agent.runtime.Runtime.reject(Runtime.java:51)
    at com.google.cloud.sql.Driver.<clinit>(Driver.java:34)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:247)
    at org.eclipse.persistence.internal.security.PrivilegedAccessHelper.getClassForName(PrivilegedAccessHelper.java:119)
    at org.eclipse.persistence.sessions.DefaultConnector.loadDriverClass(DefaultConnector.java:253)
    at org.eclipse.persistence.sessions.DefaultConnector.connect(DefaultConnector.java:85)
    at org.eclipse.persistence.sessions.DatasourceLogin.connectToDatasource(DatasourceLogin.java:162)
    at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:584)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:206)
    at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:488)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.getDatabaseSession(EntityManagerFactoryDelegate.java:188)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.createEntityManagerImpl(EntityManagerFactoryDelegate.java:277)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:294)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:272)
    at org.pathways.myapp.rest.impl.GetProgramNameByID.<init>(GetProgramNameByID.java:16)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at com.google.appengine.tools.development.agent.runtime.Runtime.newInstance_(Runtime.java:126)
    at com.google.appengine.tools.development.agent.runtime.Runtime.newInstance(Runtime.java:134)
    at com.sun.jersey.server.spi.component.ResourceComponentConstructor._construct(ResourceComponentConstructor.java:191)
    at com.sun.jersey.server.spi.component.ResourceComponentConstructor.construct(ResourceComponentConstructor.java:179)
    at com.sun.jersey.server.impl.resource.PerRequestFactory$PerRequest._getInstance(PerRequestFactory.java:182)
    at com.sun.jersey.server.impl.resource.PerRequestFactory$AbstractPerRequest.getInstance(PerRequestFactory.java:144)
    at com.sun.jersey.server.impl.application.WebApplicationContext.getResource(WebApplicationContext.java:238)
    at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:83)
    at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
    at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1483)
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1414)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1363)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1353)
    at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:414)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:708)
    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 com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:35)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:60)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:122)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.tools.development.BackendServersFilter.doFilter(BackendServersFilter.java:97)
    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 com.google.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:78)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:369)
    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.HttpParser.parseNext(HttpParser.java:547)
    at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
    at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)

А вот мой файл persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" 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_2_0.xsd">
    <persistence-unit name="MyApp" transaction-type="RESOURCE_LOCAL">
        <class>org.myapp.shared.ProfileInfo</class>
        <properties>
            <property name="javax.persistence.jdbc.driver" value="com.google.cloud.sql.Driver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:google:rdbms://mydomain.net:myapp:mydbinstance/mydb"/>
            <property name="javax.persistence.jdbc.user" value=""/>
            <property name="javax.persistence.jdbc.password" value=""/>
        </properties>
    </persistence-unit>
</persistence>

Заранее благодарю за любую помощь!


person elmor    schedule 12.06.2012    source источник


Ответы (1)


Похоже, у вас конфликт с двумя разными провайдерами jpa.

Вы должны удалить eclipselink, поскольку движок приложения Google использует datanucleus. Проверьте зависимости вашей библиотеки.

Редактировать:

Правильным решением было изменить com.google.cloud.sql.Driver на com.google.appengine.api.rdbms.AppEngineDriver в файле persistence.xml.

person jontro    schedule 12.06.2012
comment
Чтобы уточнить: пакеты org.eclipse.persistence.internal.jpa, найденные в вашей трассировке стека, не должны находиться в вашем пути к классам. Если бы он использовал datanucleus, вместо этого он содержал бы org.datanucleus.api.jpa. - person jontro; 13.06.2012
comment
Спасибо, но в своем руководстве по ссылка Google предлагает использовать, например, EclipseLink 2.3. .x и даже не описывает процесс использования JPA DataNucleus с Cloud SQL, хотя это должно быть возможно. Я думаю, вы должны иметь в виду, что Datanucleus является единственным JPA, доступным для хранилища данных Google (nosql). Несмотря на это, я попробовал ваше предложение удалить EclipseLink, чтобы увидеть, будут ли библиотеки DataNucleus работать автоматически, и я получил ту же ошибку, хотя и без org.eclipse.persistence.internal.jpa в трассировке. - person elmor; 13.06.2012
comment
ой, в первом предложении я имел в виду... Google предлагает использовать EclipseLink 2.3.x... - person elmor; 13.06.2012
comment
Извините, вы правы. Вы следовали этому руководству? developers.google.com/eclipse/docs/cloudsql-jpatools Если да, Вы убедились, что используете App Engine SDK 1.6.4 или более позднюю версию? - person jontro; 13.06.2012
comment
Да, это руководство, которым я пользовался. Я использую 1.6.5. Документация для этого действительно нуждается в улучшении. - person elmor; 13.06.2012
comment
Попробуйте изменить com.google.cloud.sql.Driver на com.google.appengine.api.rdbms.AppEngineDriver, это то, что они используют на developers.google.com/cloud-sql/docs/developers_guide_java - person jontro; 13.06.2012
comment
Это помогло, и я заставил его работать. На самом деле я только что создал новый проект, он также сгенерировал ту же строку. JPA начал работать! Теперь мне нужно вернуться и исправить исходный проект. :) - person elmor; 13.06.2012
comment
Я дал вам принятое решение, так как ваши комментарии содержат решение. - person elmor; 13.06.2012