DataNucleus enchancer 无法实例化 org.datanucleus.api.jdo.JDOAdapter

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

我的代码符合要求,但是当我尝试 运行 DataNucleus 增强器时,我无法完成 post 编译步骤。我想我丢失了一个 jar 文件,但是是哪个??我已经包含了错误和 pom.xml

我从 google 页复制说明:

<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.
    [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>

我的项目构建正确,能够生成元类和 运行 字节码增强器。但它是 SBT,不是 Maven。

有兴趣的可以看看 http://github.com/frgomes/poc-scala-datanucleus

我遇到了同样的问题,通过比较https://cloud.google.com/appengine/docs/java/datastore/jdo/overview-dn2 and http://www.datanucleus.org/products/accessplatform_3_2/jdo/maven.html

解决了

Google 的 pom.xml 片段中可能有一个简单的拼写错误。正如您在 DataNucleus 页面上看到的那样,maven 插件将自动使用最新的可用 datanucleus 核心。要防止这种使用:

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

而且增强器会起作用!所以区别在于 Google 使用了 <artifactId>datanucleus-api-jdo</artifactId> 这对我来说不是必需的,当然它不会覆盖应该使用的 datanucleus-core 版本的选择。另请注意,从 3.2.0-m2 开始,插件已从 maven-datanucleus-plugin 重命名为 datanucleus-maven-plugin。所以我也改成使用官方的3.2.0-release。 此外,Google 描述了如何使用在 appengine-java-sdk-1.9.21/lib/opt/user/datanucleus/v2 中找到的 JAR 副本,它们是:

  • 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.jarjta-1.1.jar

但是由于我没有使用 ant,而是使用 maven,所以我只需要将此依赖项添加到 pom.xml 就可以将 JDO 与 DataNucleus 一起使用 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>

顺便说一句:我在当前的 appengine-skeleton-archetype 提供的 pom.xml 中发现了另一个错误。 Maven 目标 "appengine update" 失败,因为 appengine-maven-plugin 试图上传我的应用程序,版本设置为 1.9.21。这显然是使用的 GAE SDK 的版本,而不是我的应用程序的版本。它失败了,因为它违反了 GAE 允许的版本 ID 格式。解决方法是通过添加行 <version>${app.version}</version> 来正确设置插件配置中的版本,如下所示:

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

玩得开心!