构建 Spring 启动应用程序的冲突问题

Conflict problem building the Spring boot application

我在构建 spring 引导应用程序时遇到问题。我们需要使用 Maven 构建具有 'lib/bin/conf' 结构的项目。我用另一个项目做的,没有问题。但是现在,发生了冲突,建议采取措施。


Description:

An attempt was made to call a method that does not exist. The attempt was made from the following location:

    org.springframework.context.support.GenericApplicationContext.setApplicationStartup(GenericApplicationContext.java:165)

The following method did not exist:

    'void org.springframework.beans.factory.support.DefaultListableBeanFactory.setApplicationStartup(org.springframework.core.metrics.ApplicationStartup)'

The method's class, org.springframework.beans.factory.support.DefaultListableBeanFactory, is available from the following locations:

    jar:file:/target/OrderManager/libs/communication-latest.jar!/org/springframework/beans/factory/support/DefaultListableBeanFactory.class
    jar:file:target/OrderManager/libs/spring-beans-5.3.8.jar!/org/springframework/beans/factory/support/DefaultListableBeanFactory.class

The class hierarchy was loaded from the following locations:

    org.springframework.beans.factory.support.DefaultListableBeanFactory: file:target/OrderManager/libs/communication-latest.jar
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory: file:target/OrderManager/libs/communication-latest.jar
    org.springframework.beans.factory.support.AbstractBeanFactory: file:target/OrderManager/libs/communication-latest.jar
    org.springframework.beans.factory.support.FactoryBeanRegistrySupport: file:target/OrderManager/libs/communication-latest.jar
    org.springframework.beans.factory.support.DefaultSingletonBeanRegistry: file:target/OrderManager/libs/communication-latest.jar
    org.springframework.core.SimpleAliasRegistry: file:target/OrderManager/libs/communication-latest.jar


Action:

Correct the classpath of your application so that it contains a single, compatible version of org.springframework.beans.factory.support.DefaultListableBeanFactory

我该如何解决这个问题?我正在使用我们公司提供的名为 communication 的库。 这是我的 pom 文件。

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example.artifact</groupId>
    <artifactId>ordermanager</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>Order Manager Component</name>
    <properties>
        <java.version>11</java.version>
        <spring-cloud.version>Hoxton.SR7</spring-cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
            <version>2.4.2</version>
        </dependency>


        <dependency>
            <groupId>com.excample.myArtifact</groupId>
            <artifactId>communication</artifactId>
            <version>latest</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>appassembler-maven-plugin</artifactId>
                <version>2.1.0</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>assemble</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <assembleDirectory>target/OrderManager</assembleDirectory>
                    <repositoryName>libs</repositoryName>

                    <configurationDirectory>conf</configurationDirectory>
                    <configurationSourceDirectory>src/main/resources</configurationSourceDirectory>
                    <copyConfigurationDirectory>true</copyConfigurationDirectory>
                    <repositoryLayout>flat</repositoryLayout>
                    <useWildcardClassPath>true</useWildcardClassPath>

                    <programs>
                        <program>
                            <mainClass>com.example.artifact.ordermanager.OrderManagerComponentApplication</mainClass>
                            <id>OrderManager</id>
                        </program>
                    </programs>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

为了解决这个冲突,你可以使用 excludes-dependencies https://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html

在这种情况下,应该是

<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>

来自

<groupId>com.excample.myArtifact</groupId>
<artifactId>communication</artifactId>

答案已经存在:

Correct the classpath of your application so that it contains a single, compatible version of org.springframework.beans.factory.support.DefaultListableBeanFactory

您的问题是,您有 2 个包含相同 class org.springframework.beans.factory.support.DefaultListableBeanFactory 的 JAR 文件。它们是:

  • /target/OrderManager/libs/communication-latest.jar
  • target/OrderManager/libs/spring-beans-5.3.8.jar

您必须删除其中一个。现在我不知道你的项目和架构,但如果你使用的是公司定制的 spring 库,那么你应该删除标准的 spring jar。为此使用 Maven 的 exclude mechanism,它是所谓的瞬态依赖,因此您没有明确定义它,但是您定义的依赖之一依赖于它。

首先你必须找出哪个依赖带来了 spring-beans 依赖。使用 maven 的依赖树来做到这一点:

mvn dependency:tree

您也可以使用dependency analysis or read about the whole dependency management

如果你想踢出 communication-latest.jar 你应该只删除 pom.xml 中的以下内容:

<dependency>
  <groupId>com.excample.myArtifact</groupId> 
  <artifactId>communication</artifactId>
  <version>latest</version>
</dependency>

问题是版本与通信库中使用的 spring 引导不匹配,而不是与主项目的 spring 引导不匹配。所以,我将 spring 引导版本更改为 2.3.3.RELEASE ,问题就解决了。
一些朋友告诉我排除 spring-beans 神器。我没有这样做,版本更改就足够了,但是测试关于这个主题的方法可能会有用。