TheChrisONeil
TheChrisONeil

Reputation: 405

DataNucleus enchancer cannot instantiate org.datanucleus.api.jdo.JDOAdapter

My code complies but when I try to run the DataNucleus enhancer, I am unable to get the post compilation step to complete. I presume I am missing a jar file but which one?? I have included the error and the pom.xml

I copy the instructions from the google pages:

<plugin>
<groupId>org.datanucleus</groupId>
<artifactId>maven-datanucleus-plugin</artifactId>
<version>3.2.0-m1</version>
<configuration>
<api>JDO</api>
<props>${basedir}/datanucleus.properties</props>
<verbose>true</verbose>
<enhancerName>ASM</enhancerName>
</configuration>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>enhance</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-api-jdo</artifactId>
<version>3.1.3</version>
</dependency>
</dependencies>
</plugin>

And I get this error.

And I get this error.
    [ERROR] --------------------
    [ERROR]  Standard error from the DataNucleus tool +    org.datanucleus.enhancer.DataNucleusEnhancer :
    [ERROR] --------------------
    [ERROR] Exception in thread "main" Error : An error occurred trying to     instantiate an instance of the API adapter "org.datanucleus.api.jdo.JDOAdapter" (perhaps you dont have the requisite   datanucleus-api-XXX jar in the CLASSPATH, or the
     jar for the persistence spec you are using?) : {1}
org.datanucleus.exceptions.NucleusUserException: Error : An error occurred trying to instantiate an instance of the A
adapter "org.datanucleus.api.jdo.JDOAdapter" (perhaps you dont have the requisite datanucleus-api-XXX jar in the CLAS
TH, or the api jar for the persistence spec you are using?) : {1}
        at org.datanucleus.api.ApiAdapterFactory.getApiAdapter(ApiAdapterFactory.java:104)
        at org.datanucleus.AbstractNucleusContext.(AbstractNucleusContext.java:115)
        at org.datanucleus.enhancer.EnhancementNucleusContextImpl.(EnhancementNucleusContextImpl.java:48)
        at org.datanucleus.enhancer.EnhancementNucleusContextImpl.(EnhancementNucleusContextImpl.java:37)
        at org.datanucleus.enhancer.DataNucleusEnhancer.(DataNucleusEnhancer.java:161)
        at org.datanucleus.enhancer.CommandLineHelper.createDataNucleusEnhancer(CommandLineHelper.java:148)
        at org.datanucleus.enhancer.DataNucleusEnhancer.main(DataNucleusEnhancer.java:1108)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

	<modelVersion>4.0.0</modelVersion>
	<packaging>war</packaging>
	<version>1.0-SNAPSHOT</version>

	<groupId>com.thechrisoneil.mygroupstogo</groupId>
	<artifactId>mygroupstogo</artifactId>

	<properties>
		<appengine.app.version>1</appengine.app.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<prerequisites>
		<maven>3.1.0</maven>
	</prerequisites>

	<dependencies>
		<!-- Compile/runtime dependencies, as defined by Google default maven project -->
		<!-- https://cloud.google.com/appengine/docs/java/tools/maven -->
		<dependency>
			<groupId>com.google.appengine</groupId>
			<artifactId>appengine-api-1.0-sdk</artifactId>
			<version>1.9.18</version>
		</dependency>
		<dependency>
			<groupId>com.google.appengine</groupId>
			<artifactId>appengine-endpoints</artifactId>
			<version>1.9.18</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.inject</groupId>
			<artifactId>javax.inject</artifactId>
			<version>1</version>
		</dependency>
		<dependency>
			<groupId>javax.jdo</groupId>
			<artifactId>jdo-api</artifactId>
			<version>3.1.3</version>
		</dependency>
		<!-- Dependencies added for datastorage persistents -->
		<!-- Datanucleaus (http://www.datanucleus.org/products/datanucleus/jdo/maven.html) -->
		<dependency>
			<groupId>com.google.appengine.orm</groupId>
			<artifactId>datanucleus-appengine</artifactId>
			<version>2.1.2</version>
		</dependency>
        <dependency>
            <groupId>org.datanucleus</groupId>
            <artifactId>datanucleus-core</artifactId>
            <version>3.1.3</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.datanucleus</groupId>
            <artifactId>datanucleus-api-jdo</artifactId>
            <version>3.1.3</version>
        </dependency>      
       

		<!-- Test Dependencies -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.11</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.mockito</groupId>
			<artifactId>mockito-all</artifactId>
			<version>1.9.5</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>com.google.appengine</groupId>
			<artifactId>appengine-testing</artifactId>
			<version>1.9.18</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>com.google.appengine</groupId>
			<artifactId>appengine-api-stubs</artifactId>
			<version>1.9.18</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>javax.jdo</groupId>
			<artifactId>jdo-api</artifactId>
			<version>3.0.1</version>
		</dependency>
	</dependencies>

	<build>
		<!-- for hot reload of the web application -->
		<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
		<plugins>
			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>versions-maven-plugin</artifactId>
				<version>2.1</version>
				<executions>
					<execution>
						<phase>compile</phase>
						<goals>
							<goal>display-dependency-updates</goal>
							<goal>display-plugin-updates</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<version>3.1</version>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.4</version>
				<configuration>
					<webXml>${project.build.directory}/generated-sources/appengine-endpoints/WEB-INF/web.xml</webXml>
					<webResources>
						<resource>
							<!-- this is relative to the pom.xml directory -->
							<directory>${project.build.directory}/generated-sources/appengine-endpoints</directory>
							<!-- the list has a default value of ** -->
							<includes>
								<include>WEB-INF/*.discovery</include>
								<include>WEB-INF/*.api</include>
							</includes>
						</resource>
						<!--Development of groupstogo front end is imported to deployment server -->
						<resource>
							<directory>C:/software/angularjs/my-gtg/app</directory>
							<filtering>true</filtering>
							<includes>
								<include>**/*.js</include>
								<include>**/*.html</include>
								<include>**/*.png</include>
								<include>**/*.css</include>
							</includes>
							<targetPath>app</targetPath>
						</resource>
						
					</webResources>
				</configuration>
			</plugin>
			<plugin>
				<groupId>com.google.appengine</groupId>
				<artifactId>appengine-maven-plugin</artifactId>
				<version>1.9.18</version>
				<configuration>
					<enableJarClasses>false</enableJarClasses>
					<!-- Comment in the below snippet to bind to all IPs instead of just 
						localhost -->
					<!-- address>0.0.0.0</address> <port>8080</port -->
					<!-- Comment in the below snippet to enable local debugging with a remove 
						debugger like those included with Eclipse or IntelliJ -->
					<!-- jvmFlags> <jvmFlag>-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n</jvmFlag> 
						</jvmFlags -->
				</configuration>
				<executions>
					<execution>
						<goals>
							<goal>endpoints_get_discovery_doc</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
			<plugin>
                <groupId>org.datanucleus</groupId>
                <artifactId>maven-datanucleus-plugin</artifactId>
                <version>3.2.0-m1</version>
                <configuration>
                    <api>JDO</api>
                    <props>${basedir}/datanucleus.properties</props>
                    <verbose>true</verbose>
                    <enhancerName>ASM</enhancerName>
                </configuration>
                <executions>
                    <execution>
                        <phase>process-classes</phase>
                        <goals>
                            <goal>enhance</goal>
                        </goals>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>org.datanucleus</groupId>
                        <artifactId>datanucleus-api-jdo</artifactId>
                        <version>3.1.3</version>
                    </dependency>
                </dependencies>
            </plugin>
		</plugins>
	</build>

</project>

Upvotes: 3

Views: 1617

Answers (2)

Bytemaster
Bytemaster

Reputation: 56

I had the same problem and was able to solve it by comparing https://cloud.google.com/appengine/docs/java/datastore/jdo/overview-dn2 and http://www.datanucleus.org/products/accessplatform_3_2/jdo/maven.html

There might be a simple typo in Google's pom.xml snippet. As you can read on the DataNucleus page the maven plug-in will automatically use the latest available datanucleus core. To prevent this use:

<plugin>
    <groupId>org.datanucleus</groupId>
    <artifactId>datanucleus-maven-plugin</artifactId>
    <version>3.2.0-release</version>
    <configuration>
        <api>JDO</api>
        <props>${basedir}/datanucleus.properties</props>
        <verbose>true</verbose>
        <enhancerName>ASM</enhancerName>
    </configuration>
    <executions>
        <execution>
            <phase>process-classes</phase>
            <goals>
                <goal>enhance</goal>
            </goals>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>org.datanucleus</groupId>
            <artifactId>datanucleus-core</artifactId>
            <version>3.1.3</version>
        </dependency>                    
    </dependencies>
</plugin>

And the enhancer will work! So the difference is that Google used <artifactId>datanucleus-api-jdo</artifactId> which wasn't necessary for me and of course it did not override the choice of the datanucleus-core version that should be used. Please also note that the plugin was renamed from maven-datanucleus-plugin to datanucleus-maven-plugin starting with 3.2.0-m2. So I also changed this to use the official 3.2.0-release. Furthermore Google describes to use copies of the JARs found in appengine-java-sdk-1.9.21/lib/opt/user/datanucleus/v2 which are:

  • asm-4.0.jar
  • datanucleus-api-jdo-3.1.3.jar
  • datanucleus-api-jpa-3.1.3.jar
  • datanucleus-appengine-2.1.2.jar
  • datanucleus-core-3.1.3.jar
  • geronimo-jpa_2.0_spec-1.0.jar
  • jdo-api-3.0.1.jar jta-1.1.jar

But since I'm not using ant but maven I simply had to add this dependencies to pom.xml to be able to use JDO with DataNucleus with the versions explicitly supported by Google:

<dependency>
    <groupId>javax.jdo</groupId>
    <artifactId>jdo-api</artifactId>
    <version>3.0.1</version>
</dependency>
<dependency>
    <groupId>org.datanucleus</groupId>
    <artifactId>datanucleus-core</artifactId>
    <version>3.1.3</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>org.datanucleus</groupId>
    <artifactId>datanucleus-api-jdo</artifactId>
    <version>3.1.3</version>
</dependency>
<dependency>
    <groupId>com.google.appengine.orm</groupId>
    <artifactId>datanucleus-appengine</artifactId>
    <version>2.1.2</version>
</dependency>

BTW: I spotted another bug in the pom.xml as provided by the current appengine-skeleton-archetype. The maven goal "appengine update" failed because the appengine-maven-plugin tried to upload my application with version set to 1.9.21. This is obviously the version of the used GAE SDK and not the version of my app. And it fails because it violates the allowed format for version ids as allowed by GAE. The fix was to correctly set the version in the plugin configuration by adding the line <version>${app.version}</version> like this:

<plugin>
    <groupId>com.google.appengine</groupId>
    <artifactId>appengine-maven-plugin</artifactId>
    <version>${appengine.version}</version>
    <configuration>
        <enableJarClasses>false</enableJarClasses>
        <!-- Comment in the below snippet to bind to all IPs instead of just localhost -->
        <!-- address>0.0.0.0</address>
        <port>8080</port -->
        <!-- Comment in the below snippet to enable local debugging with a remote debugger
        like those included with Eclipse or IntelliJ -->
        <!-- jvmFlags>
          <jvmFlag>-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n</jvmFlag>
        </jvmFlags -->
        <version>${app.version}</version>
    </configuration>
</plugin>

Have fun!

Upvotes: 4

Richard Gomes
Richard Gomes

Reputation: 6094

I have my project building properly, being able to generate metaclasses and run the bytecode enhancer. But it's SBT, not Maven.

In case you are interested, please have a look at http://github.com/frgomes/poc-scala-datanucleus

Upvotes: 0

Related Questions