JPA con Google Cloud SQL "NoClassDefFoundError: java.util.prefs.Preferences es una clase restringida"

Estoy usando JPA con GAE/Google Cloud SQL y configuré todo de acuerdo con los documentos de Google. Puedo navegar por mis Entidades JPA en Eclipse, y la aplicación funciona bien, excepto cuando intento hacer lo siguiente:

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

Dentro de EMF, hago:

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

... y eso es lo que causa los errores. ¿Es esta la forma correcta de adquirir EntityManagerFactory?

A continuación se muestra el rastreo. También pegué el contenido de persistence.xml debajo del rastreo, pero se generó automáticamente y creo que es correcto. No entiendo por qué se restringen las Preferencias, ya que utilicé la forma recomendada de Google para acceder a 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)

Y aquí está mi persistencia.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>

¡Gracias de antemano por cualquier ayuda!

preguntado el 12 de junio de 12 a las 18:06

1 Respuestas

Parece que tiene un conflicto con dos proveedores de jpa diferentes.

Debe eliminar eclipselink ya que el motor de aplicaciones de Google usa datanucleus. Compruebe las dependencias de su biblioteca.

Edit:

La solución correcta era cambiar com.google.cloud.sql.Driver a com.google.appengine.api.rdbms.AppEngineDriver en persistence.xml

Respondido el 13 de junio de 12 a las 10:06

Para aclarar: los paquetes org.eclipse.persistence.internal.jpa que se encuentran en su stacktrace no deben estar en su classpath. Si hubiera estado usando datanucleus, habría contenido org.datanucleus.api.jpa en su lugar. - jontro

Gracias, pero en su tutorial en aquí, Google sugiere usar como EclipseLink 2.3.x, y ni siquiera describe el proceso para usar JPA de DataNucleus con Cloud SQL, aunque debería ser posible. Creo que debe referirse a que Datanucleus es el único JPA disponible para Google Datastore (nosql). Independientemente, probé su sugerencia de eliminar EclipseLink para ver si DataNucleus libs se haría cargo automáticamente y obtuve el mismo error, aunque sin org.eclipse.persistence.internal.jpa en el rastreo. - elmor

Vaya, en la primera oración, quise decir "... Google sugiere usar EclipseLink 2.3.x..." - elmor

Lo siento, tienes razón. ¿Seguiste esta guía? developers.google.com/eclipse/docs/cloudsql-jpatools Si es así, ¿verificó que está ejecutando "App Engine SDK 1.6.4 o posterior"? - jontro

Sí, esa es la guía que he estado usando. Estoy usando 1.6.5. La documentación para esto realmente necesita ser mejorada. - elmor

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.