How to configure dependencies for DataNucleus AppEngine plugin v3?

In my project (Spring Framework + Google App Engine + DataNucleus + JPA) I get the following exception when starting the server:

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) 

Obviously, this exception is thrown during persistence.xml parsing. Spring is trying to call the MetaDataUtils#parsePersistenceFiles(PluginManager,String,NucleusContext,nucCtx) , but it is missing. This method is part of org.datanucleus:datanucleus-core . At first, I thought I had a missing or duplicate dependency somewhere. I performed

 gradle dependencies 

carefully scanned output and did not find anything suspicious: only one version of the dependency.
According to the documentation, MetaDataUtils has only one parsePersistenceFiles method:

 public static PersistenceFileMetaData[] parsePersistenceFiles( PluginManager pluginMgr, String persistenceFilename, boolean validate, ClassLoaderResolver clr); 

If you are observant, you probably noticed that it differs in arguments: there is an additional argument boolean validate . It is strange that there is no such method in any version of DataNucleus. Why is DataNucleus looking for a method that did not even exist? I can’t get it.

Dora
Please help DataNucleus and I will find the missing method!


UPDATE
As Neil Stockton said, because I am using inconsistent versions of datanucleus-core and datanucleus-api-jpa. But I do not know the correct combination of dependencies. And I'm starting to think that the DataNucleus App Engine Plugin 3.0 is currently not ready for use.


I want to use the DataNucleus App Engine Plugin 3.0 because of this problem (fixed in DataNucleus versions 3.2.6 and 3.3.3) and because I need JPA 2.1 functions (selection of entity groups / diagrams). The DataNucleus App Engine Plugin 3.0 module is compatible with the mentioned versions of DataNucleus, but unreleased . I checked the plugin from SVN, packed it and added it to my project as a jar (an identical jar is available for download if you want to repeat this setting yourself).

build.gradle:

 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" } 

Spring context:

 <?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> 

Storage unit

 <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:
If I put datanucleus-api-jpa of a different version on CLASSPATH, for example

 compile 'org.datanucleus:datanucleus-api-jpa:3.2.2' 

I get an exception during improvement:

 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) 

From the documentation:

The App Engine Java SDK includes version 2.x of the DataNucleus plugin for the App Engine. This plugin corresponds to version 3.0 of the DataNucleus Access Platform, which allows you to use App Engine storage through JPA 2.0.
JPA is a standard interface for interacting with relational databases, but the App Engine datastore is not a relational database. As a result, there are JPA features that App Engine simply cannot support.

+5
source share
1 answer

The simple fact is that you must use consistent versions of different cans. If you use Google "datanucleus-appengine" v3.0 (SVN), you MUST have a DataNucleus project "datanucleus-core", "datanucleus-api-jpa" v3.2.x (or 3.3.x of datanucleus-api-jpa ) and other versions. If you receive a message about

The Bundle plugin "org.datanucleus.api.jpa" is already registered.

then you have several versions of this plugin in CLASSPATH and you have to fix your CLASSPATH (just print out what is in CLASSPATH and it will tell you ... something like System.getProperty ("java.class.path") )

In your case you have

File: //appengine-sdk/appengine-java-sdk-1.9.19/lib/opt/tools/datanucleus/v2/datanucleus-api-jpa-3.1.3.jar

and

File: //caches/modules-2/files-2.1/org.datanucleus/datanucleus-api-jpa/3.2.2/c24c14634c39b5b9a59dcd379dbb6d93da97f3e7/datanucleus-api-jpa-3.2.2.jar

so get rid of the first

0
source

All Articles