在一个使用Maven和Google App Engine的项目中,出现了数据核心增强器的不兼容版本问题。

20

我在使用Datanucleus增强器时遇到了问题,这是用于Google App Engine项目的。如果我使用Datanucleus Eclipse插件,则一切都很好,但在我的Maven项目中,我会遇到奇怪的版本冲突错误。

我的POM文件中有以下Datanucleus引用:

<dependency>
    <groupId>org.datanucleus</groupId>
    <artifactId>datanucleus-core</artifactId>
    <version>1.1.0</version>
</dependency>

...

<plugin>
    <groupId>org.datanucleus</groupId>
    <artifactId>maven-datanucleus-plugin</artifactId>
    <version>1.1.0</version>
    <configuration>
        <mappingIncludes>**/*.class</mappingIncludes>
        <verbose>true</verbose>
        <enhancerName>ASM</enhancerName>
        <api>JDO</api>
    </configuration>
    <executions>
        <execution>
        <phase>compile</phase>
        <goals>
            <goal>enhance</goal>
        </goals>
        </execution>
    </executions>
</plugin>

编译项目时出现以下错误:

Exception in thread "main" Plugin (Bundle) "org.datanucleus" is already registered. 
Ensure you dont have multiple JAR versions of the same plugin in the classpath. The URL "file:/Users/drome/.m2/repository/org/datanucleus/datanucleus-core/1.1.0/**datanucleus-core-1.1.0.jar**" is already registered, and you are trying to register an identical plugin located at URL "file:/Users/drome/.m2/repository/org/datanucleus/datanucleus-core/1.1.3/**datanucleus-core-1.1.3.jar**."
org.datanucleus.exceptions.NucleusException: Plugin (Bundle) "org.datanucleus" is already registered. Ensure you dont have multiple JAR versions of the same plugin in the classpath. The URL "file:/Users/drome/.m2/repository/org/datanucleus/datanucleus-core/1.1.0/datanucleus-core-1.1.0.jar" is already registered, and you are trying to register an identical plugin located at URL "file:/Users/drome/.m2/repository/org/datanucleus/datanucleus-core/1.1.3/datanucleus-core-1.1.3.jar."
at org.datanucleus.plugin.NonManagedPluginRegistry.registerBundle(NonManagedPluginRegistry.java:437)
at org.datanucleus.plugin.NonManagedPluginRegistry.registerBundle(NonManagedPluginRegistry.java:343)
at org.datanucleus.plugin.NonManagedPluginRegistry.registerExtensions(NonManagedPluginRegistry.java:227
)
at org.datanucleus.plugin.NonManagedPluginRegistry.registerExtensionPoints(NonManagedPluginRegistry.jav
a:159)
at org.datanucleus.plugin.PluginManager.registerExtensionPoints(PluginManager.java:82)
at org.datanucleus.OMFContext.(OMFContext.java:164)
at org.datanucleus.enhancer.DataNucleusEnhancer.(DataNucleusEnhancer.java:171)
at org.datanucleus.enhancer.DataNucleusEnhancer.(DataNucleusEnhancer.java:149)
at org.datanucleus.enhancer.DataNucleusEnhancer.main(DataNucleusEnhancer.java:1157)

我不理解为什么datanucleus需要Maven下载datanucleus-core-1.1.3.jar,因为它没有在pom.xml中引用。

我也不明白为什么要注册datanucleus-core-1.1.3.jar...

有什么想法吗? 提前感谢...

6个回答

6

DN M2插件会拉取所需的最新版本DN jars以完成其工作(除了使用最新版本,没有其他合理的方法)。如果您想将“core”限制为不同的版本,则可以通过指定核心的插件依赖项或在应用程序中指定来实现。

<dependency>
    <groupId>org.datanucleus</groupId>
    <artifactId>datanucleus-core</artifactId>
    <version>1.1.0</version>
    <scope>runtime</scope> 
</dependency>

我认为排除同一构件的不同版本是不可能的。 group-a artifact-a 1.0 group-c excluded-artifact - ivo
1
DN M2插件只能做唯一合理的事情;使用最新版本。我看不到其他方法来拥有一个M2插件,而不必每次发布依赖jar的新版本时都要发布新版本,这就是引入M2版本范围的原因。其他人处理这个问题没有任何问题 http://groups.google.com/group/google-appengine-java/browse_thread/thread/aeaffa3f33e1e4e2/095300c75cd9da39?lnk=gst&q=maven-datanucleus#095300c75cd9da39 显然,谷歌更新他们的DN插件jar将意味着它是无关紧要的。 - DataNucleus
根据您提供的链接,将范围更改为“运行时”确实解决了问题。感谢您的支持 :-) - ivo
我尝试了这个方法,看起来是有效的。但是如果我运行mvn clean compile,我会得到错误信息Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project XXX: Fatal error compiling: java.lang.NoClassDefFoundError: org/datanucleus/util/AnnotationProcessorUtils: org.datanucleus.util.AnnotationProcessorUtils。有什么想法吗?我正在使用datanucleus-maven-plugin:3.3.0-release - Adrian Ber

5
很不幸,答案在评论中“隐藏”着:
<dependency>
    <groupId>org.datanucleus</groupId>
    <artifactId>datanucleus-core</artifactId>
    <version>1.1.0</version>
    <scope>runtime</scope>
</dependency>

这对我很有效!


2

我在测试maven gae插件原型时遇到了同样的问题。

我通过在我的gae运行时传递依赖项中添加排除来解决了这个问题。

<!-- Google App Engine meta-package -->
        <dependency>
            <groupId>net.kindleit</groupId>
            <artifactId>gae-runtime</artifactId>
            <version>${gae.version}</version>
            <type>pom</type>
            <exclusions>
                <exclusion>
                    <groupId>com.google.appengine.orm</groupId>
                    <artifactId>datanucleus-core</artifactId>
                </exclusion>

            </exclusions>
        </dependency>

然后将核心核心作为运行时依赖项添加

<dependency>
            <groupId>org.datanucleus</groupId>
            <artifactId>datanucleus-core</artifactId>
            <version>${datanucleus-core.version}</version>
            <scope>runtime</scope>
            <exclusions>
                <exclusion>
                    <groupId>javax.transaction</groupId>
                    <artifactId>transaction-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

保持gae插件部分简单:

<plugin>
                <groupId>org.datanucleus</groupId>
                <artifactId>maven-datanucleus-plugin</artifactId>
                <version>${maven-datanucleus-plugin.version}</version>
                <configuration>
                    <!--
                        Make sure this path contains your persistent classes!
                    -->
                    <mappingIncludes>**/model/*.class</mappingIncludes>
                    <verbose>true</verbose>
                    <enhancerName>ASM</enhancerName>
                    <api>JDO</api>
                </configuration>
                <executions>
                    <execution>
                        <phase>compile</phase>
                        <goals>
                            <goal>enhance</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

2
阅读完“如何在Maven中覆盖插件的依赖项”之后,我发现了另一种解决方法。这是我的POM文件:
<plugin>
  <groupId>org.datanucleus</groupId>
  <artifactId>maven-datanucleus-plugin</artifactId>
  <version>3.1.0-m3</version>
  <configuration>
    <verbose>true</verbose>
  </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.0.4</version>
    </dependency>
  </dependencies>
</plugin>

我认为这是更明智的答案。将范围限定为运行时对我来说也不起作用。我真正想要的是修复增强器使用的datanucleus-core版本与我的应用程序使用的版本相同。 - John Michelau

0

Maven-datanucleus-plugin自3.1.1版本以来已经停止拉取可用的datanucleus-core的最新版本。

请检查Maven-datanucleus-plugin 3.1.1 (http://repo1.maven.org/maven2/org/datanucleus/maven-datanucleus-plugin/3.1.1/maven-datanucleus-plugin-3.1.1.pom)和3.1.0-release (http://mvnrepository.com/artifact/org.datanucleus/maven-datanucleus-plugin/3.1.0-release)之间的POM文件差异。

对于 maven-datanucleus-plugin 3.1.1,datanucleus-core 依赖的版本范围是 (3.0.99, 3.1.99),而对于 maven-datanucleus-plugin 3.1.0-release,则是 (3.0.99, )。因此,在旧版本的 maven-datanucleus-plugin 中,自动拉取 datanucleus-core 的最新版本也就不足为奇了。

0
清除你本地Maven仓库中的旧版本Datanucleus也能解决这个问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接