【问题标题】:camel 3 openjdk 11 hibernate/jpa java.lang.NoSuchMethodError骆驼 3 openjdk 11 休眠/jpa java.lang.NoSuchMethodError
【发布时间】:2020-03-02 19:17:41
【问题描述】:

我正在尝试迁移一个曾经使用骆驼 2 和 jdk 8 的 maven 项目。我正在尝试同时使用更新版本的 spring 和 hibernate。

清理我的本地 maven .m2/ repo 后,“mvn clean install”工作,然后尝试“mvn clean package exec:java”,我有一个 java.lang.NoSuchMethodError 似乎与 spring-core 链接

我的 spring xml 配置文件导入了一个 databaseconfig.xml 文件:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    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/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx 
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd">



<!-- bean post processor to add advisor to repository bean so platform specific exceptions are caught efficiently ie. unchecked  -->
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>


<!-- needed so entitymanager can be injected in spring inside pricevectordaojpa  -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

    <context:property-placeholder location="classpath:config.properties"/>

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${db.driverClassName}"/>
        <property name="url" value="${db.url}"/>
        <property name="username" value="${db.username}"/>
        <property name="password" value="${db.password}"/>
    </bean> 

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="database" value="${db.type}" />
                <property name="showSql" value="false" />
            </bean>
        </property>
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan" value="com.nodenet.domain" />
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.ejb.naming_strategy">${db.namingStrategy}</prop>
                <prop key="hibernate.hbm2ddl.auto">${db.hbm2ddl}</prop>
            </props>
        </property>
    </bean> 

    <bean id="jpa"  class="org.apache.camel.component.jpa.JpaComponent">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

    <bean id="jpaTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean> 

<tx:annotation-driven transaction-manager="jpaTransactionManager"/>

</beans>



看起来这是文件创建了一些问题,因为我收到以下错误,所以找不到一些 spring-core 类/依赖项:


在 burki 的 cmets 之后,我在 pom.xml 中使用强制执行器 maven 插件和排除项清理了传递的 spring 依赖项,它起作用了

【问题讨论】:

    标签: spring hibernate maven apache-camel openjdk-11


    【解决方案1】:

    我猜你有 Spring 依赖项与不同版本的混合。可能存在由其他依赖项(如 ActiveMQ 或其他)拉取的传递 Spring 依赖项。

    所有 Spring 框架依赖项必须具有相同的版本,在您的情况下为 5.1.14.RELEASE。

    使用IDE 的依赖管理 来获取所有项目依赖的列表或使用Maven dependency plugin to list a tree of your dependencies

    您也可以使用Maven enforcer plugin 来解决依赖冲突。但我认为它不会抱怨旧版本的单个 Spring 依赖项。

    自我管理的替代方案

    另一个策略是利用 Spring Boot 社区的出色工作来构建一个运行良好的依赖版本生态系统

    请注意,以下定义只是添加了依赖管理,而不是真正的依赖!

    您可以通过将 Spring Boot POM 声明为您的父 POM 来使用它。

    <parent>
        <artifactId>spring-boot-starter-parent</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>2.1.7.RELEASE</version>
        <relativePath />
    </parent>
    

    如果你不使用 Spring Boot 或者你的 parent 已经在使用,你也可以只使用依赖管理部分。此版本仅定义依赖版本,而父 POM 还定义 Maven 插件版本

    <dependencyManagement>
        <dependencies>
            <dependency>
                <!-- Import dependency management from Spring Boot -->
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.1.7.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    

    使用 POM 中的这些定义之一,您可以省略大多数依赖版本以使用 Spring Boot 已经定义的版本。

    这里以dependency definitions of Spring Boot version 2.1.7 为例。

    Spring Boot docs 中描述了这两种变体以获取更多详细信息。

    【讨论】:

    • 我运行 mvn dependency:tree -Dverbose 并得到很多“省略重复”或“省略冲突”,例如“org.springframework:spring-core:jar:5.2.3. RELEASE:compile - 因与 5.1.14.RELEASE 冲突而省略。这是否一定意味着有问题?如果我需要像 camel-jpa 这样明显使用不同旧版本 spring 的工具,如何确保所有 spring 框架依赖项具有相同的版本?你对春天的评论对骆驼也有效吗?所有骆驼依赖项必须具有相同的版本?
    • 通常,是的。对于像 Camel、Spring 等“包”的所有组件具有相同的版本非常有帮助。在 Spring 中这有点棘手,因为有多个包,如 SpringBoot、Spring Cloud、Spring Framework,它们具有不同的版本。您可以排除您不想拥有的传递依赖项,也可以在所需版本中显式添加依赖项以“覆盖”另一个版本。执行器插件可以帮助您解决这个问题。它列出了 Maven 构建期间的所有冲突。
    • 我刚刚扩展了我的答案,所有依赖版本的自我管理都有另一种选择。您可以使用由 Spring Boot 策划的已定义生态系统。
    • 我会先尝试手动操作。我从来没有像我想的那样使用 当你有多个父/子 pom.xml 并且我在这里运行单独的简单的一个模块程序时。在这种情况下,依赖管理仍然有用吗? (仍在阅读有关它的文档,可能是一个明显的问题。为此道歉)。关于我之前的问题,如果 camel-jpa artifact 需要 spring-core 5.2.3,我该如何强制执行对 spring 5.1.14.RELEASE 的依赖,它甚至有意义吗?阅读您建议的 Maven 执行器插件,它是否与非多模块项目相关?
    • DependencyManagement 中的依赖项只是为了声明所需的版本。依赖项本身(即 JAR)不包含在您的项目中。所以它对任何 Maven 项目都有帮助。要更喜欢 spring-core 5.1.14.RELEASE,你必须在你的 POM 中明确声明这个版本的依赖。像这样它应该有优先权。但是,如果 camel-jpa 不适用于这个旧版本,那么您就有问题了。
    猜你喜欢
    • 2016-01-19
    • 2019-06-29
    • 1970-01-01
    • 2018-11-07
    • 2016-11-19
    • 1970-01-01
    • 2014-01-19
    • 2019-07-07
    • 1970-01-01
    相关资源
    最近更新 更多