《Java 编程实战》附录 A Maven 配置模板

给出一套可直接对照的 libraryd 多模块 Maven 配置:父 POM 的属性与 dependencyManagement、五个子模块的依赖声明、编译与测试插件、Enforcer、JaCoCo、Checkstyle、SpotBugs、Shade、Jib 的完整片段,以及 quality、integration 两个 profile 与常用诊断命令。

这份附录怎么用

正文按章节逐步添加配置,读的时候容易只看到「这一节新增的那一段」。这份附录把 libraryd 最终的 Maven 配置集中放在一起,作为对照和抄写模板。

两点说明:

  • 片段省略了 <modelVersion> 之外的 XML 命名空间声明;实际文件需要完整的 <project xmlns="http://maven.apache.org/POM/4.0.0" ...>。
  • 版本号与正文一致:JDK 25、Maven 3.9.12。升级依赖时先改父 POM 的属性,不要在子模块里覆盖。

父 POM

<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>

  <groupId>com.plume</groupId>
  <artifactId>libraryd-parent</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>pom</packaging>

  <modules>
    <module>libraryd-domain</module>
    <module>libraryd-persistence</module>
    <module>libraryd-web</module>
    <module>libraryd-app</module>
    <module>libraryd-integration-tests</module>
  </modules>

  <properties>
    <maven.compiler.release>25</maven.compiler.release>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <project.build.outputTimestamp>2026-10-16T00:00:00Z</project.build.outputTimestamp>

    <javalin.version>7.2.4</javalin.version>
    <jackson.version>2.22.4</jackson.version>
    <postgresql.version>42.7.14</postgresql.version>
    <hikari.version>7.1.0</hikari.version>
    <flyway.version>13.11.1</flyway.version>
    <slf4j.version>2.0.20</slf4j.version>
    <logback.version>1.6.6</logback.version>
    <logstash-encoder.version>9.0</logstash-encoder.version>
    <junit.version>5.14.4</junit.version>
    <testcontainers.version>1.21.4</testcontainers.version>
    <hibernate-validator.version>9.1.5.Final</hibernate-validator.version>
    <jakarta-validation.version>3.1.1</jakarta-validation.version>
    <expressly.version>6.0.0</expressly.version>
    <micrometer.version>1.17.2</micrometer.version>
    <otel.version>1.67.0</otel.version>
    <caffeine.version>3.3.1</caffeine.version>
    <jedis.version>8.0.2</jedis.version>
    <jacoco.version>0.8.16</jacoco.version>
  </properties>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>io.javalin</groupId>
        <artifactId>javalin</artifactId>
        <version>${javalin.version}</version>
      </dependency>
      <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${jackson.version}</version>
      </dependency>
      <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr310</artifactId>
        <version>${jackson.version}</version>
      </dependency>
      <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>${postgresql.version}</version>
      </dependency>
      <dependency>
        <groupId>com.zaxxer</groupId>
        <artifactId>HikariCP</artifactId>
        <version>${hikari.version}</version>
      </dependency>
      <dependency>
        <groupId>org.flywaydb</groupId>
        <artifactId>flyway-core</artifactId>
        <version>${flyway.version}</version>
      </dependency>
      <dependency>
        <groupId>org.flywaydb</groupId>
        <artifactId>flyway-database-postgresql</artifactId>
        <version>${flyway.version}</version>
      </dependency>
      <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>${slf4j.version}</version>
      </dependency>
      <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>${logback.version}</version>
      </dependency>
      <dependency>
        <groupId>net.logstash.logback</groupId>
        <artifactId>logstash-logback-encoder</artifactId>
        <version>${logstash-encoder.version}</version>
      </dependency>
      <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
        <version>${junit.version}</version>
      </dependency>
      <dependency>
        <groupId>org.testcontainers</groupId>
        <artifactId>postgresql</artifactId>
        <version>${testcontainers.version}</version>
      </dependency>
      <dependency>
        <groupId>org.hibernate.validator</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>${hibernate-validator.version}</version>
      </dependency>
      <dependency>
        <groupId>jakarta.validation</groupId>
        <artifactId>jakarta.validation-api</artifactId>
        <version>${jakarta-validation.version}</version>
      </dependency>
      <dependency>
        <groupId>org.glassfish.expressly</groupId>
        <artifactId>expressly</artifactId>
        <version>${expressly.version}</version>
      </dependency>
      <dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-core</artifactId>
        <version>${micrometer.version}</version>
      </dependency>
      <dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-registry-prometheus</artifactId>
        <version>${micrometer.version}</version>
      </dependency>
      <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-sdk</artifactId>
        <version>${otel.version}</version>
      </dependency>
      <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-exporter-logging</artifactId>
        <version>${otel.version}</version>
      </dependency>
      <dependency>
        <groupId>com.github.ben-manes.caffeine</groupId>
        <artifactId>caffeine</artifactId>
        <version>${caffeine.version}</version>
      </dependency>
      <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>${jedis.version}</version>
      </dependency>

      <!-- 内部模块 -->
      <dependency>
        <groupId>com.plume</groupId>
        <artifactId>libraryd-domain</artifactId>
        <version>${project.version}</version>
      </dependency>
      <dependency>
        <groupId>com.plume</groupId>
        <artifactId>libraryd-persistence</artifactId>
        <version>${project.version}</version>
      </dependency>
      <dependency>
        <groupId>com.plume</groupId>
        <artifactId>libraryd-web</artifactId>
        <version>${project.version}</version>
      </dependency>
      <dependency>
        <groupId>com.plume</groupId>
        <artifactId>libraryd-app</artifactId>
        <version>${project.version}</version>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.16.0</version>
          <configuration>
            <release>${maven.compiler.release}</release>
            <parameters>true</parameters>
            <showWarnings>true</showWarnings>
            <compilerArgs>
              <arg>-Xlint:all,-processing</arg>
              <arg>-Werror</arg>
            </compilerArgs>
          </configuration>
        </plugin>

        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>3.6.1</version>
        </plugin>

        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-failsafe-plugin</artifactId>
          <version>3.6.1</version>
          <executions>
            <execution>
              <goals>
                <goal>integration-test</goal>
                <goal>verify</goal>
              </goals>
            </execution>
          </executions>
        </plugin>

        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-enforcer-plugin</artifactId>
          <version>3.6.3</version>
        </plugin>

        <plugin>
          <groupId>org.jacoco</groupId>
          <artifactId>jacoco-maven-plugin</artifactId>
          <version>${jacoco.version}</version>
        </plugin>

        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-checkstyle-plugin</artifactId>
          <version>3.6.0</version>
          <dependencies>
            <dependency>
              <groupId>com.puppycrawl.tools</groupId>
              <artifactId>checkstyle</artifactId>
              <version>10.26.1</version>
            </dependency>
          </dependencies>
        </plugin>

        <plugin>
          <groupId>com.github.spotbugs</groupId>
          <artifactId>spotbugs-maven-plugin</artifactId>
          <version>4.10.5.0</version>
        </plugin>

        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-shade-plugin</artifactId>
          <version>3.6.2</version>
        </plugin>

        <plugin>
          <groupId>com.google.cloud.tools</groupId>
          <artifactId>jib-maven-plugin</artifactId>
          <version>3.5.2</version>
        </plugin>
      </plugins>
    </pluginManagement>

    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-enforcer-plugin</artifactId>
        <executions>
          <execution>
            <id>enforce-toolchain</id>
            <goals>
              <goal>enforce</goal>
            </goals>
            <configuration>
              <rules>
                <requireMavenVersion>
                  <version>[3.9,4.0)</version>
                </requireMavenVersion>
                <requireJavaVersion>
                  <version>[25,26)</version>
                </requireJavaVersion>
                <dependencyConvergence/>
              </rules>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

几个容易忽略的点:

  • pluginManagement 只声明版本和默认配置,不会自动执行插件。要执行的插件(如 Enforcer)必须再写进 <build><plugins>。
  • dependencyConvergence 对传递依赖很严格,遇到冲突会直接失败。它的价值是逼你显式解决版本分歧,而不是让 Maven 悄悄选一个。
  • -Xlint:all,-processing 里的 -processing 关闭注解处理器告警,避免与 Hibernate Validator 等库的处理器冲突。第 2.1 节会解释哪些告警值得保留。

子模块 POM

domain

<parent>
  <groupId>com.plume</groupId>
  <artifactId>libraryd-parent</artifactId>
  <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>libraryd-domain</artifactId>

<dependencies>
  <dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <scope>test</scope>
  </dependency>
</dependencies>

domain 不依赖 JDBC、Javalin、Jackson。这条约束靠 code review 维持,不靠 Maven 强制;如果 domain 需要某个第三方类型,通常说明边界画错了。

persistence

<parent>
  <groupId>com.plume</groupId>
  <artifactId>libraryd-parent</artifactId>
  <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>libraryd-persistence</artifactId>

<dependencies>
  <dependency>
    <groupId>com.plume</groupId>
    <artifactId>libraryd-domain</artifactId>
  </dependency>
  <dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <scope>runtime</scope>
  </dependency>
  <dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
  </dependency>
  <dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
  </dependency>
  <dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-database-postgresql</artifactId>
  </dependency>
  <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
  </dependency>

  <dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>postgresql</artifactId>
    <scope>test</scope>
  </dependency>
</dependencies>

PostgreSQL 驱动用 runtime 作用域:编译期只需要 java.sql,运行时才需要驱动实现。这样能避免代码里误用 org.postgresql.* 的具体类。

web

<parent>
  <groupId>com.plume</groupId>
  <artifactId>libraryd-parent</artifactId>
  <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>libraryd-web</artifactId>

<dependencies>
  <dependency>
    <groupId>com.plume</groupId>
    <artifactId>libraryd-domain</artifactId>
  </dependency>
  <dependency>
    <groupId>io.javalin</groupId>
    <artifactId>javalin</artifactId>
  </dependency>
  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
  </dependency>
  <dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
  </dependency>
  <dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
  </dependency>
  <dependency>
    <groupId>jakarta.validation</groupId>
    <artifactId>jakarta.validation-api</artifactId>
  </dependency>
  <dependency>
    <groupId>org.glassfish.expressly</groupId>
    <artifactId>expressly</artifactId>
  </dependency>
  <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
  </dependency>

  <dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <scope>test</scope>
  </dependency>
</dependencies>

app

<parent>
  <groupId>com.plume</groupId>
  <artifactId>libraryd-parent</artifactId>
  <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>libraryd-app</artifactId>

<dependencies>
  <dependency>
    <groupId>com.plume</groupId>
    <artifactId>libraryd-domain</artifactId>
  </dependency>
  <dependency>
    <groupId>com.plume</groupId>
    <artifactId>libraryd-persistence</artifactId>
  </dependency>
  <dependency>
    <groupId>com.plume</groupId>
    <artifactId>libraryd-web</artifactId>
  </dependency>
  <dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
  </dependency>
  <dependency>
    <groupId>net.logstash.logback</groupId>
    <artifactId>logstash-logback-encoder</artifactId>
  </dependency>
  <dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-core</artifactId>
  </dependency>
  <dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
  </dependency>
  <dependency>
    <groupId>io.opentelemetry</groupId>
    <artifactId>opentelemetry-sdk</artifactId>
  </dependency>
  <dependency>
    <groupId>io.opentelemetry</groupId>
    <artifactId>opentelemetry-exporter-logging</artifactId>
  </dependency>
  <dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
  </dependency>
  <dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
  </dependency>
</dependencies>

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-shade-plugin</artifactId>
      <executions>
        <execution>
          <phase>package</phase>
          <goals>
            <goal>shade</goal>
          </goals>
          <configuration>
            <createDependencyReducedPom>false</createDependencyReducedPom>
            <filters>
              <filter>
                <artifact>*:*</artifact>
                <excludes>
                  <exclude>META-INF/*.SF</exclude>
                  <exclude>META-INF/*.DSA</exclude>
                  <exclude>META-INF/*.RSA</exclude>
                </excludes>
              </filter>
            </filters>
            <transformers>
              <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
              <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                <mainClass>com.plume.library.AppMain</mainClass>
              </transformer>
            </transformers>
          </configuration>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

integration-tests

<parent>
  <groupId>com.plume</groupId>
  <artifactId>libraryd-parent</artifactId>
  <version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>libraryd-integration-tests</artifactId>

<dependencies>
  <dependency>
    <groupId>com.plume</groupId>
    <artifactId>libraryd-app</artifactId>
  </dependency>
  <dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>postgresql</artifactId>
    <scope>test</scope>
  </dependency>
</dependencies>

集成测试模块本身没有主代码,测试类放在 src/test/java 下,由 Failsafe 执行。

质量插件

JaCoCo

<plugin>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  <executions>
    <execution>
      <id>prepare-agent</id>
      <goals>
        <goal>prepare-agent</goal>
      </goals>
    </execution>
    <execution>
      <id>report</id>
      <phase>verify</phase>
      <goals>
        <goal>report</goal>
      </goals>
    </execution>
    <execution>
      <id>check</id>
      <phase>verify</phase>
      <goals>
        <goal>check</goal>
      </goals>
      <configuration>
        <rules>
          <rule>
            <element>BUNDLE</element>
            <limits>
              <limit>
                <counter>LINE</counter>
                <value>COVEREDRATIO</value>
                <minimum>0.60</minimum>
              </limit>
            </limits>
          </rule>
        </rules>
      </configuration>
    </execution>
  </executions>
</plugin>

覆盖率阈值不要定得太高。60% 的行覆盖率对业务模块是合理起点,domain 可以要求更高,web 的路由和配置类通常较低。按模块配置比全局一个数字更有意义。

Checkstyle

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-checkstyle-plugin</artifactId>
  <executions>
    <execution>
      <id>checkstyle</id>
      <phase>verify</phase>
      <goals>
        <goal>check</goal>
      </goals>
      <configuration>
        <configLocation>.config/checkstyle.xml</configLocation>
        <includeTestSourceDirectory>true</includeTestSourceDirectory>
        <failOnViolation>true</failOnViolation>
        <violationSeverity>warning</violationSeverity>
      </configuration>
    </execution>
  </executions>
</plugin>

Checkstyle 的规则集要按团队习惯裁剪。默认 Sun 规则会要求 Javadoc 和 80 列换行,对现代项目过严;第 2.2 节给了一份以命名、导入、空块、魔法数字为主的精简规则。

SpotBugs

<plugin>
  <groupId>com.github.spotbugs</groupId>
  <artifactId>spotbugs-maven-plugin</artifactId>
  <executions>
    <execution>
      <id>spotbugs</id>
      <phase>verify</phase>
      <goals>
        <goal>check</goal>
      </goals>
      <configuration>
        <effort>Max</effort>
        <threshold>Low</threshold>
        <excludeFilterFile>.config/spotbugs-exclude.xml</excludeFilterFile>
        <failOnError>true</failOnError>
      </configuration>
    </execution>
  </executions>
</plugin>

threshold=Low 会报告大量低优先级问题,第一次接入时容易淹没。建议先设为 Medium 建立基线,再逐条关闭或加排除;排除文件必须写原因,否则半年后没人知道为什么忽略。

镜像插件

<plugin>
  <groupId>com.google.cloud.tools</groupId>
  <artifactId>jib-maven-plugin</artifactId>
  <configuration>
    <from>
      <image>eclipse-temurin:25-jre-alpine</image>
    </from>
    <to>
      <image>registry.example.com/libraryd</image>
      <tags>
        <tag>${project.version}</tag>
        <tag>latest</tag>
      </tags>
    </to>
    <container>
      <mainClass>com.plume.library.AppMain</mainClass>
      <ports>
        <port>8080</port>
      </ports>
      <environment>
        <LIBRARYD_HTTP_PORT>8080</LIBRARYD_HTTP_PORT>
      </environment>
      <jvmFlags>
        <jvmFlag>-XX:MaxRAMPercentage=75</jvmFlag>
      </jvmFlags>
    </container>
  </configuration>
</plugin>

Jib 默认把依赖、资源、应用类分成三层,改代码时只推送最后一层。MaxRAMPercentage 让 JVM 按容器内存上限计算堆大小,比固定 -Xmx 更适合容器环境。

Profile

quality

<profile>
  <id>quality</id>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-checkstyle-plugin</artifactId>
      </plugin>
      <plugin>
        <groupId>com.github.spotbugs</groupId>
        <artifactId>spotbugs-maven-plugin</artifactId>
      </plugin>
      <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</profile>

本地开发默认只跑编译和测试,CI 用 -Pquality 启用静态分析与覆盖率门禁。这样日常反馈快,提交前再跑完整检查。

integration

<profile>
  <id>integration</id>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-failsafe-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</profile>

Failsafe 默认匹配 *IT.java。单元测试用 Surefire 的 *Test.java,集成测试用 *IT.java,两者分开执行。

常用诊断命令

# 查看最终生效的 POM(含父级继承与 profile)
mvn -q help:effective-pom -Doutput=/tmp/effective-pom.xml

# 查某个依赖从哪来
mvn -q dependency:tree -Dincludes=com.fasterxml.jackson.core:jackson-databind

# 查冲突
mvn -q dependency:tree -Dverbose -Dincludes=org.slf4j

# 只构建某个模块及其依赖
mvn -q -pl libraryd-web -am -DskipTests package

# 跳测试但保留编译
mvn -q -DskipTests package

# 只跑某个测试类
mvn -q -pl libraryd-persistence -Dtest=JdbcBookRepositoryTest test

help:effective-pom 是排查「为什么版本不是我写的那个」最快的方式。dependency:tree -Dverbose 会显示被省略的冲突路径,但输出很长,建议配合 -Dincludes 过滤。

五个常见配置错误

  1. 插件写在 pluginManagement 里却以为会执行。 它只提供版本和默认配置,执行要写进 <build><plugins>。
  2. 子模块重复写版本。 父 POM 已经锁定的依赖,子模块再写版本会覆盖统一管理,升级时漏改。
  3. Shade 没有过滤签名文件。 运行时报 Invalid signature file digest for Manifest main attributes。
  4. Shade 没有合并 META-INF/services。 Jackson、Flyway 等库的 SPI 文件被覆盖,运行时表现为「找不到实现」。
  5. JaCoCo 的 argLine 被 Surefire 覆盖。 如果自定义了 argLine,要写成 <argLine>@{argLine} ...</argLine>,否则覆盖率数据为空。

小结

  • 父 POM 负责版本、编码、编译目标与插件默认配置;子模块只声明依赖和必要的构建行为。
  • Enforcer 负责工具链和依赖收敛,Checkstyle/SpotBugs 负责静态质量,JaCoCo 负责覆盖率,Shade/Jib 负责产物。
  • 质量插件放在 quality profile,本地快、CI 严。
  • 最常见的配置问题是插件没执行、版本被覆盖、Shade 资源合并与 JaCoCo argLine。
  • 排查配置先看 help:effective-pom,再看 dependency:tree,不要靠猜。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「java」更多文章

  1. 《Netty 高性能网络编程》15.3 linkd-v2 验收与复盘
  2. 《Netty 高性能网络编程》15.2 限流、超时与降级
  3. 《Netty 高性能网络编程》15.1 网关路由与转发