Spring Boot:排除打包依赖项

9
我是一名有用的助手,可以为您翻译文本。
我正在开发一个 Spring Boot 项目(项目 A),将其包含在其他项目中(项目 B、项目 C...)。在项目 A 中,我有几个依赖项,但在导入项目 A 的项目中,可能只需要其中的一些或某一个。
我正在尝试找到一种方法,在打包项目 A 时排除 jar 依赖项,以便在运行时由项目 B 提供所需的依赖项。当单独运行 Project A 进行测试时,我希望这些依赖项可用。 已经尝试过以下方法: 我已经尝试使用:
<scope>provided</scope>
<optional>true</optional>

这些jar包最终都会出现在最终的成果物中。

我也尝试将以下内容添加到spring-boot-maven-plugin中:

           <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                        <configuration>
                            <excludeArtifactIds>spring-boot-starter-redis</excludeArtifactIds>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>

这只是移除了spring-boot依赖,但是该依赖的子模块仍会出现在最终构建的文件中。

3个回答

10

在我们当前的项目中,我们需要创建一个war文件来部署在JEE服务器中的应用程序。该war文件必须仅包含所需的jar文件,并且不包括JEE服务器已提供的任何API或实现。

但是,为了测试目的,我们想保留生成可执行的war或jar文件的可能性,就像Boot默认提供的一样。

为了实现这一点,我们将所有可选依赖项设置为provided。例如,我们有一些在开发中使用的直接依赖项,如JDBC驱动程序,我们不想包含在部署的war文件中。还有一些Boot主要启动器,它们提供了其他启动器和库的依赖项,而在JEE服务器中我们不需要这些。这是spring-boot-starter-tomcatspring-boot-starter-jdbc启动器的情况。在我们的项目中,我们在pom.xml文件中拥有以下依赖项:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
    <scope>provided</scope>
</dependency>
<dependency>
  <groupId>com.oracle</groupId>
  <artifactId>ojdbc7</artifactId>
  <scope>provided</scope>
</dependency>
这样,这些依赖项就不会被包含在原始的jar/war文件中,但是Spring Boot Maven插件将它们包含在重新打包的jar/war的lib-provided文件夹中。
这些依赖项不会被JEE服务器看到,但会使打包的应用程序比需要的要大。解决方案是告诉Spring Boot Maven插件以另一个名称创建重新打包的文件,并排除开发工具:
<plugin>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-maven-plugin</artifactId>
  <configuration>
      <mainClass>${start-class}</mainClass>
      <classifier>exec</classifier>
  </configuration>
</plugin>

这样做,maven将会为你的应用生成两个包:

  • 默认的jar/war包,没有所有提供的依赖。
  • 重打包的文件名以_exec.jar/.war结尾,其中有所有提供的依赖在lib-provided文件夹中,并支持使用java -jar file运行应用程序。

在您的情况下,您可以使用相同的技术来生成项目A的包,以便将其包含在项目B中,并生成可独立运行的项目A的包。

如果您不需要创建可单独运行项目A的包,并且仅在IDE中进行测试,则甚至可以从pom.xml中删除Spring Boot Maven插件。


我使用了你指定的方法,使用<classifier>解决了我的问题。这将创建artifact-exec.jarartifact.jar,其中artifact.jar可以用作库,而artifact-exec.jar可以用于独立运行。 干净的解决方案,没有对pom文件进行任何黑客攻击。 谢谢Cèsar :) - Sandheep

0

它是否也移除了传递依赖关系?(如果有的话,com.foo.bar的依赖关系) - Wortig

-2
在项目B的pom.xml文件中,你可以做如下操作:
  <dependencies>
    ....
    <dependency>
        <groupId>com.example</groupId>
        <artifactId>projectA</artifactId>

        <exclusions>
            <exclusion>
                <groupId>com.foo.bar</groupId>
                <artifactId>baz</artifactId>
            </exclusion>
            ....
        </exclusions>
    </dependency>
    .....
   </dependencies>

谢谢你的建议。但是我已经知道可以在项目B上进行这种排除。我想知道是否有一种方法可以在打包项目A本身时实现这一点。希望能够减轻从实施项目中排除不需要的依赖项的负担。使用<provided>范围和<optional>标记不应该在最终构件中包含JAR文件。想要检查是否是由spring-boot-maven-plugin进行了某些覆盖。 - Sandheep
1
根据http://docs.spring.io/spring-boot/docs/current/maven-plugin/examples/exclude-dependency.html,你只是排除了构件本身,但没有排除它的传递依赖。 - WeMakeSoftware

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