Nel mio progetto (Spring Framework + Google App Engine + DataNucleus + APP) ottengo la seguente eccezione sul avvio del server:Come configurare le dipendenze per il plug-in DataEnucleus AppEngine v3?
WARNING: Nestedin org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method failed;
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in ServletContext resource [/WEB-INF/spring/db.xml]: Invocation of init method failed;
nested exception is java.lang.NoSuchMethodError: org.datanucleus.metadata.MetaDataUtils.parsePersistenceFiles(Lorg/datanucleus/plugin/PluginManager;Ljava/lang/String;ZLorg/datanucleus/NucleusContext;)[Lorg/datanucleus/metadata/PersistenceFileMetaData;:
java.lang.NoSuchMethodError: org.datanucleus.metadata.MetaDataUtils.parsePersistenceFiles(Lorg/datanucleus/plugin/PluginManager;Ljava/lang/String;ZLorg/datanucleus/NucleusContext;)[Lorg/datanucleus/metadata/PersistenceFileMetaData;
at org.datanucleus.api.jpa.JPAEntityManagerFactory.<init>(JPAEntityManagerFactory.java:342)
at org.datanucleus.api.jpa.PersistenceProviderImpl.createEntityManagerFactory(PersistenceProviderImpl.java:91)
Ovviamente questa eccezione viene gettato durante persistence.xml
analisi. Spring tenta di richiamare il metodo MetaDataUtils#parsePersistenceFiles(PluginManager,String,NucleusContext,nucCtx)
, ma è assente. Questo metodo è una parte di org.datanucleus:datanucleus-core
. All'inizio pensavo di avere una dipendenza mancante o duplicata da qualche parte. Ho eseguito
gradle dependencies
output accuratamente scansionato e non ho trovato nulla di sospetto: solo una singola versione della dipendenza.
Secondo la documentazione MetaDataUtils
ha un solo metodo parsePersistenceFiles
:
public static PersistenceFileMetaData[] parsePersistenceFiles(
PluginManager pluginMgr, String persistenceFilename, boolean validate, ClassLoaderResolver clr);
Se si è attenti, probabilmente avete notato che si differenzia per argomenti: c'è un boolean validate
argomento extra. La cosa strana è che non esiste un tale metodo in nessuna versione di DataNucleus. Perché DataNucleus sta cercando il metodo che non è nemmeno esistito? Non riesco a capirlo.
Si prega di aiutare DataNucleus e me trovare il metodo mancante!
UPDATE
Come Neil Stockton rilevare è perché sto utilizzando le versioni incoerenti di DataNucleus-core e DataNucleus-api-JPA. Ma non conosco la giusta combinazione di dipendenze. E sto iniziando a pensare, che DataNucleus App Engine Plugin 3.0 non è attualmente pronto per l'uso.
voglio usare DataNucleus App Engine Plugin 3.0 a causa di this issue (fisso nelle versioni DataNucleus 3.2.6 e 3.3.3) e perché ho bisogno di JPA 2.1 caratteristiche (prendere gruppi/grafici entità). Il Plugin App Engine 3.0 DataNucleus è compatible con le versioni menzionate di DataNucleus, ma inedito. Ho controllato il plug-in da SVN, l'ho impacchettato e aggiunto al mio progetto come jar (un jar identico è disponibile per download, se vuoi ripetere questa configurazione da solo).
build.Gradle: contesto
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'appengine'
dependencies {
// App Engine
compile fileTree(dir: 'libs', include: ['*.jar']) // There is datanucleus-appengine-3.0.0-20140128.jar in libs
appengineSdk 'com.google.appengine:appengine-java-sdk:1.9.19'
compile 'com.google.appengine:appengine-api-1.0-sdk:1.9.19'
// persistence
// App Engine and DataNucleus compatibility:
// https://code.google.com/p/datanucleus-appengine/wiki/Compatibility
compile 'org.eclipse.persistence:javax.persistence:2.1.0'
runtime 'org.datanucleus:datanucleus-core:3.2.15'
compile 'org.datanucleus:datanucleus-api-jpa:3.1.3'
compile 'javax.jdo:jdo-api:3.1'
compile 'org.datanucleus:datanucleus-jodatime:3.2.1'
// Spring Framework
compile("org.springframework:spring-webmvc:4.1.6.RELEASE")
compile ("org.springframework.data:spring-data-jpa:1.8.0.RELEASE")
providedCompile 'javax.annotation:javax.annotation-api:1.2'
compile 'com.google.code.gson:gson:2.3.1'
providedCompile 'org.projectlombok:lombok:1.16.+'
}
appengine {
downloadSdk = true
httpAddress = "0.0.0.0"
}
Primavera:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"
default-autowire="byName">
<jpa:repositories base-package="<my.package.name>.repositories" />
<!-- The simplest and the most limited form of JPA deployment -->
<!-- For details see http://docs.spring.io/spring/docs/current/spring-framework-reference/html/orm.html#orm-jpa -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="transactions-optional" />
</bean>
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
unità Persistenza
<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.appengine.datastoreEnableXGTransactions" value="true" />
</properties>
</persistence-unit>
UPDATE:
Se metto DataNucleus-api-JPA di un'altra versione sul CLASSPATH , ad esempio
compile 'org.datanucleus:datanucleus-api-jpa:3.2.2'
ottengo un'eccezione durante miglioramento:
java.lang.RuntimeException: Unexpected exception
at com.google.appengine.tools.enhancer.Enhancer.execute(Enhancer.java:76)
at com.google.appengine.tools.enhancer.Enhance.<init>(Enhance.java:71)
... 1 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
... 5 more
Caused by: org.datanucleus.exceptions.NucleusException:
Plugin (Bundle) "org.datanucleus.api.jpa" is already registered.
Ensure you dont have multiple JAR versions of the same plugin in the classpath.
The URL "file:/<GRADLE_HOME>/appengine-sdk/appengine-java-sdk-1.9.19/lib/opt/tools/datanucleus/v2/datanucleus-api-jpa-3.1.3.jar" is already registered,
and you are trying to register an identical plugin located at URL "file:/<GRADLE_HOME>/caches/modules-2/files-2.1/org.datanucleus/datanucleus-api-jpa/3.2.2/c24c14634c39b5b9a59dcd379dbb6d93da97f3e7/datanucleus-api-jpa-3.2.2.jar."
at org.datanucleus.plugin.NonManagedPluginRegistry.registerBundle(NonManagedPluginRegistry.java:541)
at org.datanucleus.plugin.NonManagedPluginRegistry.registerBundle(NonManagedPluginRegistry.java:395)
Da documentazione:
L'App Engine Java SDK include la versione 2.x del plugin DataNucleus per App Engine. Questo plugin corrisponde alla versione 3.0 della piattaforma di accesso DataNucleus, che consente di utilizzare il Datastore App Engine tramite JPA 2.0.
JPA presenta un'interfaccia standard per l'interazione con i database relazionali, ma il datastore App Engine non è un database relazionale. Di conseguenza, ci sono funzionalità di JPA che App Engine non è in grado di supportare.
utilizzando le versioni incoerenti di DataNucleus-core e DataNucleus-api-JPA. Spring non sta effettuando quella chiamata come mostra la traccia stack, chiamata da org.datanucleus.api.jpa.XXX –