maven scope=provided || optional=true会打包到jar文件中吗?

文章目录

问题描述

Maven中的依赖<scope>provided</scope><optional>true</optional>是否会打包到最终的jar包中?

xml 复制代码
 <dependency>
     <groupId>org.apache.commons</groupId>
     <artifactId>commons-lang3</artifactId>
     <scope>provided</scope>
 </dependency>
 <dependency>
     <groupId>commons-beanutils</groupId>
     <artifactId>commons-beanutils</artifactId>
     <version>1.9.4</version>
     <optional>true</optional>
 </dependency>

先说结论:

1、如果是pringboot的打包插件,即使你设置了以上两个属性这两个依赖依然会被打包到可执行jar包中。这是SpringBoot的机制,具体看下文分析。

2、如果是普通原生的maven打包上面两者是不会打包到jar文件中的。

现象分析

探讨分析Spring Boot打包时<scope>provided</scope><optional>true</optional>的行为,两者是否需要被打打包到可执行jar包的BOOT-INFO/lib目录下?

现在让我分析打包后的jar文件,看看实际包含的依赖情况:

bash 复制代码
cd /Users/shouzhi/nvxclouds/project/springboot-x-example && jar -tf target/springboot-x-example-1.0.0.jar | grep -E "(commons-lang3|commons-beanutils)" | head -10

输出输出>>>>>>
<ep -E "(commons-lang3|commons-beanutils)" | head -10
BOOT-INF/lib/commons-lang3-3.12.0.jar
BOOT-INF/lib/commons-beanutils-1.9.4.jar

现在分析一下Maven的依赖树,看看这些依赖是如何被引入的:

bash 复制代码
mvn dependency:tree | grep -A 5 -B 5 -E "(commons-lang3|commons-beanutils)"

输出>>>>>>
Downloading from nexus: http://192.168.50.16:8081/repository/maven-public/com/nvxclouds/baize/tally/tally-co
mmon-s3/3.2.0-springboot2-jdk8-SNAPSHOT/maven-metadata.xml

Downloaded from nexus: http://192.168.50.16:8081/repository/maven-public/com/nvxclouds/baize/tally/tally-com
mon-s3/3.2.0-springboot2-jdk8-SNAPSHOT/maven-metadata.xml (841 B at 49 kB/s)

[INFO] 
[INFO] --- dependency:3.3.0:tree (default-cli) @ springboot-x-example ---
[INFO] com.shouzhi.test:springboot-x-example:jar:1.0.0
[INFO] +- org.apache.commons:commons-lang3:jar:3.12.0:provided
[INFO] +- commons-beanutils:commons-beanutils:jar:1.9.4:compile
[INFO] |  +- commons-logging:commons-logging:jar:1.2:compile
[INFO] |  \- commons-collections:commons-collections:jar:3.2.2:compile
[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:2.7.18:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter:jar:2.7.18:compile
[INFO] |  |  +- org.springframework.boot:spring-boot:jar:2.7.18:compile

查看完整的依赖树来全面分析:

bash 复制代码
mvn dependency:tree

输出>>>>>>
......

Downloaded from nexus: http://192.168.50.16:8081/repository/maven-public/com/nvxclouds/baize/tally/tally-com
mon-s3/3.2.0-springboot2-jdk8-SNAPSHOT/maven-metadata.xml (841 B at 44 kB/s)

[INFO] 
[INFO] --- dependency:3.3.0:tree (default-cli) @ springboot-x-example ---
[INFO] com.shouzhi.test:springboot-x-example:jar:1.0.0
[INFO] +- org.apache.commons:commons-lang3:jar:3.12.0:provided
[INFO] +- commons-beanutils:commons-beanutils:jar:1.9.4:compile
[INFO] |  +- commons-logging:commons-logging:jar:1.2:compile
[INFO] |  \- commons-collections:commons-collections:jar:3.2.2:compile
[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:2.7.18:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter:jar:2.7.18:compile
[INFO] |  |  +- org.springframework.boot:spring-boot:jar:2.7.18:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-autoconfigure:jar:2.7.18:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-starter-logging:jar:2.7.18:compile
[INFO] |  |  |  +- ch.qos.logback:logback-classic:jar:1.2.12:compile
[INFO] |  |  |  |  \- ch.qos.logback:logback-core:jar:1.2.12:compile
[INFO] |  |  |  +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.17.2:compile
[INFO] |  |  |  |  \- org.apache.logging.log4j:log4j-api:jar:2.17.2:compile
[INFO] |  |  |  \- org.slf4j:jul-to-slf4j:jar:1.7.36:compile
[INFO] |  |  +- jakarta.annotation:jakarta.annotation-api:jar:1.3.5:compile
[INFO] |  |  \- org.yaml:snakeyaml:jar:1.30:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-json:jar:2.7.18:compile
[INFO] |  |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.13.5:compile
[INFO] |  |  |  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.13.5:compile
[INFO] |  |  |  \- com.fasterxml.jackson.core:jackson-core:jar:2.13.5:compile
[INFO] |  |  +- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:jar:2.13.5:compile
[INFO] |  |  +- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.13.5:compile
[INFO] |  |  \- com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.13.5:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-tomcat:jar:2.7.18:compile
[INFO] |  |  +- org.apache.tomcat.embed:tomcat-embed-core:jar:9.0.83:compile
[INFO] |  |  +- org.apache.tomcat.embed:tomcat-embed-el:jar:9.0.83:compile
[INFO] |  |  \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:9.0.83:compile
[INFO] |  +- org.springframework:spring-web:jar:5.3.31:compile
[INFO] |  |  \- org.springframework:spring-beans:jar:5.3.31:compile
[INFO] |  \- org.springframework:spring-webmvc:jar:5.3.31:compile
[INFO] |     +- org.springframework:spring-aop:jar:5.3.31:compile
[INFO] |     +- org.springframework:spring-context:jar:5.3.31:compile
[INFO] |     \- org.springframework:spring-expression:jar:5.3.31:compile
[INFO] +- org.springframework.boot:spring-boot-starter-test:jar:2.7.18:test
[INFO] |  +- org.springframework.boot:spring-boot-test:jar:2.7.18:test
[INFO] |  +- org.springframework.boot:spring-boot-test-autoconfigure:jar:2.7.18:test
[INFO] |  +- com.jayway.jsonpath:json-path:jar:2.7.0:test
[INFO] |  |  +- net.minidev:json-smart:jar:2.4.11:test
[INFO] |  |  |  \- net.minidev:accessors-smart:jar:2.4.11:test
[INFO] |  |  |     \- org.ow2.asm:asm:jar:9.3:test
[INFO] |  |  \- org.slf4j:slf4j-api:jar:1.7.36:compile
[INFO] |  +- jakarta.xml.bind:jakarta.xml.bind-api:jar:2.3.3:test
[INFO] |  |  \- jakarta.activation:jakarta.activation-api:jar:1.2.2:test
[INFO] |  +- org.assertj:assertj-core:jar:3.22.0:test
[INFO] |  +- org.hamcrest:hamcrest:jar:2.2:test
[INFO] |  +- org.junit.jupiter:junit-jupiter:jar:5.8.2:test
[INFO] |  |  +- org.junit.jupiter:junit-jupiter-api:jar:5.8.2:test
[INFO] |  |  |  +- org.opentest4j:opentest4j:jar:1.2.0:test
[INFO] |  |  |  +- org.junit.platform:junit-platform-commons:jar:1.8.2:test
[INFO] |  |  |  \- org.apiguardian:apiguardian-api:jar:1.1.2:test
[INFO] |  |  +- org.junit.jupiter:junit-jupiter-params:jar:5.8.2:test
[INFO] |  |  \- org.junit.jupiter:junit-jupiter-engine:jar:5.8.2:test
[INFO] |  |     \- org.junit.platform:junit-platform-engine:jar:1.8.2:test
[INFO] |  +- org.mockito:mockito-core:jar:4.5.1:test
[INFO] |  |  +- net.bytebuddy:byte-buddy:jar:1.12.23:test
[INFO] |  |  +- net.bytebuddy:byte-buddy-agent:jar:1.12.23:test
[INFO] |  |  \- org.objenesis:objenesis:jar:3.2:test
[INFO] |  +- org.mockito:mockito-junit-jupiter:jar:4.5.1:test
[INFO] |  +- org.skyscreamer:jsonassert:jar:1.5.1:test
[INFO] |  |  \- com.vaadin.external.google:android-json:jar:0.0.20131108.vaadin1:test
[INFO] |  +- org.springframework:spring-core:jar:5.3.31:compile
[INFO] |  |  \- org.springframework:spring-jcl:jar:5.3.31:compile
[INFO] |  +- org.springframework:spring-test:jar:5.3.31:test
[INFO] |  \- org.xmlunit:xmlunit-core:jar:2.9.1:test
[INFO] +- com.alibaba.fastjson2:fastjson2:jar:2.0.55:compile
[INFO] +- org.projectlombok:lombok:jar:1.18.30:compile
[INFO] +- com.nvxclouds.baize.tally:tally-common-tidb:jar:3.2.0-springboot2-jdk8-SNAPSHOT:compile
[INFO] |  +- javax.annotation:javax.annotation-api:jar:1.3.2:compile
[INFO] |  +- com.mysql:mysql-connector-j:jar:8.0.33:compile
[INFO] |  \- com.zaxxer:HikariCP:jar:4.0.3:compile
[INFO] \- com.nvxclouds.baize.tally:tally-common-s3:jar:3.2.0-springboot2-jdk8-SNAPSHOT:compile
[INFO]    \- com.amazonaws:aws-java-sdk-s3:jar:1.11.343:compile
[INFO]       +- com.amazonaws:aws-java-sdk-kms:jar:1.11.343:compile
[INFO]       +- com.amazonaws:aws-java-sdk-core:jar:1.11.343:compile
[INFO]       |  +- org.apache.httpcomponents:httpclient:jar:4.5.14:compile
[INFO]       |  |  +- org.apache.httpcomponents:httpcore:jar:4.4.16:compile
[INFO]       |  |  \- commons-codec:commons-codec:jar:1.15:compile
[INFO]       |  +- com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:jar:2.13.5:compile
[INFO]       |  \- joda-time:joda-time:jar:2.8.1:compile
[INFO]       \- com.amazonaws:jmespath-java:jar:1.11.343:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.997 s
[INFO] Finished at: 2025-09-03T08:35:30+08:00
[INFO] ------------------------------------------------------------------------

现在分析一下为什么会出现这种情况。首先让我检查一下是否有其他传递依赖引入了这些包:

bash 复制代码
mvn dependency:tree -Dincludes=org.apache.commons:commons-lang3

输出>>>>>>
[INFO] Scanning for projects...
[INFO] 
[INFO] ---------------< com.shouzhi.test:springboot-x-example >----------------
[INFO] Building tidb-test 1.0.0
[INFO]   from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
。。。。。。。

Downloaded from nexus: http://192.168.50.16:8081/repository/maven-public/com/nvxclouds/baize/tally/tally-com
mon-s3/3.2.0-springboot2-jdk8-SNAPSHOT/maven-metadata.xml (841 B at 44 kB/s)

[INFO] 
[INFO] --- dependency:3.3.0:tree (default-cli) @ springboot-x-example ---
[INFO] com.shouzhi.test:springboot-x-example:jar:1.0.0
[INFO] \- org.apache.commons:commons-lang3:jar:3.12.0:provided
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.902 s
[INFO] Finished at: 2025-09-03T08:35:41+08:00
[INFO] ------------------------------------------------------------------------
bash 复制代码
mvn dependency:tree -Dincludes=commons-beanutils:commons-beanutils

输出>>>>>>
[INFO] Scanning for projects...
[INFO] 
[INFO] ---------------< com.shouzhi.test:springboot-x-example >----------------
[INFO] Building tidb-test 1.0.0
[INFO]   from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
。。。。。。

Downloaded from nexus: http://192.168.50.16:8081/repository/maven-public/com/nvxclouds/baize/tally/tally-com
mon-s3/3.2.0-springboot2-jdk8-SNAPSHOT/maven-metadata.xml (841 B at 44 kB/s)

[INFO] 
[INFO] --- dependency:3.3.0:tree (default-cli) @ springboot-x-example ---
[INFO] com.shouzhi.test:springboot-x-example:jar:1.0.0
[INFO] \- commons-beanutils:commons-beanutils:jar:1.9.4:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.921 s
[INFO] Finished at: 2025-09-03T08:35:45+08:00
[INFO] ------------------------------------------------------------------------

现在查看具体的Spring Boot Maven Plugin配置,看看是否有特殊设置:

bash 复制代码
mvn help:effective-pom | grep -A 20 -B 5 "spring-boot-maven-plugin"

输出>>>>>>
shouzhi@192 springboot-x-example % mvn help:effective-pom | grep -A 20 -B 5 "spring-boot-maven-plugin"
            </execution>
          </executions>
          <dependencies>
            <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-maven-plugin</artifactId>
              <version>2.7.18</version>
            </dependency>
          </dependencies>
          <configuration>
            <!--这个属性导致以上2个包仍然被导报到/lib中-->
            <keepDependenciesWithProvidedScope>true</keepDependenciesWithProvidedScope>
            <createDependencyReducedPom>true</createDependencyReducedPom>
            <filters>
              <filter>
                <artifact>*:*</artifact>
                <excludes>
                  <exclude>META-INF/*.SF</exclude>
                  <exclude>META-INF/*.DSA</exclude>
                  <exclude>META-INF/*.RSA</exclude>
                </excludes>
              </filter>
            </filters>
          </configuration>
        </plugin>
        <plugin>
          <artifactId>maven-source-plugin</artifactId>
--
            </archive>
          </configuration>
        </plugin>
        <plugin>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-maven-plugin</artifactId>
          <version>2.7.18</version>
          <executions>
            <execution>
              <id>repackage</id>
              <goals>
                <goal>repackage</goal>
              </goals>
              <configuration>
                <mainClass>${start-class}</mainClass>
              </configuration>
            </execution>
          </executions>
          <configuration>
            <mainClass>${start-class}</mainClass>
          </configuration>
        </plugin>
        <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>versions-maven-plugin</artifactId>
          <version>2.10.0</version>
--
      </plugins>
    </pluginManagement>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <version>2.7.18</version>
        <executions>
          <execution>
            <id>repackage</id>
            <goals>
              <goal>repackage</goal>
            </goals>
            <configuration>
              <mainClass>${start-class}</mainClass>
            </configuration>
          </execution>
        </executions>
        <configuration>
          <mainClass>${start-class}</mainClass>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-clean-plugin</artifactId>
        <version>3.2.0</version>
        <executions>
shouzhi@192 springboot-x-example %

现在发现了关键问题!从有效POM中可以看到一个关键配置:<keepDependenciesWithProvidedScope>true</keepDependenciesWithProvidedScope>

问题分析

以上现象是正确的 ,这是 Spring Boot Maven Plugin 的默认行为,而不是bug。

根本原因

  1. Spring Boot 的"Fat JAR"策略

    • Spring Boot 创建的是自包含的可执行JAR(Fat JAR/Uber JAR)
    • 为了确保应用可以独立运行,它会默认包含所有依赖 ,包括 providedoptional 的依赖
  2. Spring Boot Maven Plugin 的默认配置

    • 从有效POM可以看到:<keepDependenciesWithProvidedScope>true</keepDependenciesWithProvidedScope>
    • 这个配置导致 provided 依赖也被打包进去
  3. 传统Maven vs Spring Boot的区别

    xml 复制代码
    <!-- 传统Maven:provided依赖不会被打包 -->
    <scope>provided</scope>
    
    <!-- Spring Boot:默认仍会打包,确保独立运行 -->

验证结果解释

  • commons-lang3 (provided) → 被打包 :因为 keepDependenciesWithProvidedScope=true
  • commons-beanutils (optional) → 被打包:optional主要影响传递依赖,当前项目中仍会被打包

如何控制打包行为

如果您确实不想让这些依赖被打包,可以在 spring-boot-maven-plugin 中显式排除:

xml 复制代码
<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <excludes>
            <exclude>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
            </exclude>
            <exclude>
                <groupId>commons-beanutils</groupId>
                <artifactId>commons-beanutils</artifactId>
            </exclude>
        </excludes>
    </configuration>
</plugin>

总结

验证结果是完全正确的 !Spring Boot 的这种设计是有意为之,目的是创建一个完全自包含的可执行应用程序,即使依赖标记为 providedoptional,默认情况下仍会被包含以确保应用的完整性和可移植性。

相关推荐
达文汐1 天前
【困难】力扣算法题解析LeetCode332:重新安排行程
java·数据结构·经验分享·算法·leetcode·力扣
培风图南以星河揽胜1 天前
Java版LeetCode热题100之零钱兑换:动态规划经典问题深度解析
java·leetcode·动态规划
启山智软1 天前
【中大企业选择源码部署商城系统】
java·spring·商城开发
我真的是大笨蛋1 天前
深度解析InnoDB如何保障Buffer与磁盘数据一致性
java·数据库·sql·mysql·性能优化
怪兽源码1 天前
基于SpringBoot的选课调查系统
java·spring boot·后端·选课调查系统
恒悦sunsite1 天前
Redis之配置只读账号
java·redis·bootstrap
梦里小白龙1 天前
java 通过Minio上传文件
java·开发语言
人道领域1 天前
javaWeb从入门到进阶(SpringBoot事务管理及AOP)
java·数据库·mysql
sheji52611 天前
JSP基于信息安全的读书网站79f9s--程序+源码+数据库+调试部署+开发环境
java·开发语言·数据库·算法
毕设源码-邱学长1 天前
【开题答辩全过程】以 基于Java Web的电子商务网站的用户行为分析与个性化推荐系统为例,包含答辩的问题和答案
java·开发语言