在多模块Maven项目中共享公共模块

时间:2015-09-02 11:26:25

标签: java maven spring-boot pom.xml spring-boot-maven-plugin

我的项目有三个模块:A,B和COMMON。 我想将公共逻辑放在COMMON模块(例如模型)中,然后是其他两个依赖于它的模块。

将分别构建两个模块(A,B)以创建两个不同的罐。

我正在测试它试图将日志依赖项放在COMMON模块中,然后构建A项目。它会正确构建,但如果我尝试使用“java -jar a.jar”运行jar,它会失败并带有NoClassDefFound:

Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory

根pom:

<modules>
    <module>common</module>
    <module>a</module>
</modules>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.12</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.1.3</version>
        </dependency>
    </dependencies>
</dependencyManagement>

常见的pom:

<dependencies>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
    </dependency>
</dependencies>

和pom:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                        <mainClass>bla.bla.Main</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

<dependencies>
    <dependency>
        <groupId>bla.blu</groupId>
        <artifactId>common</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>
</dependencies>

2 个答案:

答案 0 :(得分:2)

默认情况下,Maven不会将所有依赖项打包到您的JAR中。因此它缺失了。您可以在运行时在类路径上提供该jar。

其他选择是创建所谓的胖罐。 This is SO thread how to do that

顺便说一句,我备份了@Boris关于Spring Boot的Spider评论。走这条路,开箱即可解决很多问题。

编辑 - 对第一条评论的反应:

通常情况下,应将公共依赖项部署到工件存档(Nexus,Artifactory)中,并从那里作为任何第三方依赖项。

由于您没有这样做,因此您需要在构建A期间在本地存储库中具有公共依赖性。因此,将Spring-boot-maven-plugin放入A构建并使用您的多模块项目构建胖jar。

答案 1 :(得分:0)

尝试从A.jar运行依赖于常用功能的东西时,需要在类路径中包含COMMON模块。简单地将其声明为依赖项将不包括a.jar工件中的公共类(如果需要,您将需要使用程序集maven插件)。

此外,公共jar带来的所有传递依赖也应该列在类路径中。

所以你必须像java -cp common.jar:slf4j-a.b.c.jar:logback-x.y.jar[:...] -jar a.jar一样运行它。

Maven本身以及任何了解maven的IDE都会为您做到这一点,因此您不必手动完成。要构建一个在生产环境中运行的jar,您应该考虑使用assemblyshade插件并构建一个&#34; fat&#34; (或uber-)jar,它将包含单个文件中的所有依赖项。