3.0.4

1. 使用文档

Spring Cloud CircuitBreaker 项目包含 Resilience4J 和 Spring Retry 的实现。Spring Cloud CircuitBreaker 中实现的 API 存在于 Spring Cloud Commons 中。这些 API 的使用文档位于Spring Cloud Commons 文档中。

1.1. 配置 Resilience4J 断路器

1.1.1. 启动器

Resilience4J 实现有两个启动器,一个用于响应式应用程序,一个用于非响应式应用程序。

  • org.springframework.cloud:spring-cloud-starter-circuitbreaker-resilience4j - 非响应式应用程序

  • org.springframework.cloud:spring-cloud-starter-circuitbreaker-reactor-resilience4j - 响应式应用程序

1.1.2. 自动配置

通过将 spring.cloud.circuitbreaker.resilience4j.enabled 设置为 false,可以禁用 Resilience4J 自动配置。

1.1.3. 默认配置

要为所有断路器提供默认配置,请创建一个 Customizer bean,该 bean 接收 Resilience4JCircuitBreakerFactoryReactiveResilience4JCircuitBreakerFactory。可以使用 configureDefault 方法提供默认配置。

@Bean
public Customizer<Resilience4JCircuitBreakerFactory> defaultCustomizer() {
    return factory -> factory.configureDefault(id -> new Resilience4JConfigBuilder(id)
            .timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofSeconds(4)).build())
            .circuitBreakerConfig(CircuitBreakerConfig.ofDefaults())
            .build());
}
响应式示例
@Bean
public Customizer<ReactiveResilience4JCircuitBreakerFactory> defaultCustomizer() {
    return factory -> factory.configureDefault(id -> new Resilience4JConfigBuilder(id)
            .circuitBreakerConfig(CircuitBreakerConfig.ofDefaults())
            .timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofSeconds(4)).build()).build());
}
自定义 ExecutorService

如果要配置执行断路器的 ExecutorService,可以使用 Resilience4JCircuitBreakerFactory 进行配置。

例如,如果要使用上下文感知的 ExecutorService,可以执行以下操作。

@Bean
public Customizer<ReactiveResilience4JCircuitBreakerFactory> defaultCustomizer() {
    return factory -> {
        ContextAwareScheduledThreadPoolExecutor executor = ContextAwareScheduledThreadPoolExecutor.newScheduledThreadPool().corePoolSize(5)
            .build();
        factory.configureExecutorService(executor);
    };
}

1.1.4. 特定断路器配置

与提供默认配置类似,您可以创建一个 Customizer bean,该 bean 接收 Resilience4JCircuitBreakerFactoryReactiveResilience4JCircuitBreakerFactory

@Bean
public Customizer<Resilience4JCircuitBreakerFactory> slowCustomizer() {
    return factory -> factory.configure(builder -> builder.circuitBreakerConfig(CircuitBreakerConfig.ofDefaults())
            .timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofSeconds(2)).build()), "slow");
}

除了配置创建的断路器之外,您还可以在断路器创建后但在返回给调用者之前对其进行自定义。为此,可以使用 addCircuitBreakerCustomizer 方法。这对于向 Resilience4J 断路器添加事件处理程序非常有用。

@Bean
public Customizer<Resilience4JCircuitBreakerFactory> slowCustomizer() {
    return factory -> factory.addCircuitBreakerCustomizer(circuitBreaker -> circuitBreaker.getEventPublisher()
    .onError(normalFluxErrorConsumer).onSuccess(normalFluxSuccessConsumer), "normalflux");
}
响应式示例
@Bean
public Customizer<ReactiveResilience4JCircuitBreakerFactory> slowCustomizer() {
    return factory -> {
        factory.configure(builder -> builder
        .timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofSeconds(2)).build())
        .circuitBreakerConfig(CircuitBreakerConfig.ofDefaults()), "slow", "slowflux");
        factory.addCircuitBreakerCustomizer(circuitBreaker -> circuitBreaker.getEventPublisher()
            .onError(normalFluxErrorConsumer).onSuccess(normalFluxSuccessConsumer), "normalflux");
     };
}

1.1.5. 断路器属性配置

您可以在应用程序的配置文件中配置 CircuitBreakerTimeLimiter 配置或实例。属性配置的优先级高于 Java Customizer 配置。

优先级从高到低依次为:

  • 方法(id) 配置 - 针对特定方法或操作

  • 服务(组) 配置 - 针对特定应用程序服务或操作

  • 全局默认配置

ReactiveResilience4JCircuitBreakerFactory.create(String id, String groupName)
Resilience4JCircuitBreakerFactory.create(String id, String groupName)
全局默认属性配置
resilience4j.circuitbreaker:
    configs:
        default:
            registerHealthIndicator: true
            slidingWindowSize: 50

resilience4j.timelimiter:
    configs:
        default:
            timeoutDuration: 5s
            cancelRunningFuture: true
配置属性配置
resilience4j.circuitbreaker:
    configs:
        groupA:
            registerHealthIndicator: true
            slidingWindowSize: 200

resilience4j.timelimiter:
    configs:
        groupC:
            timeoutDuration: 3s
            cancelRunningFuture: true
实例属性配置
resilience4j.circuitbreaker:
 instances:
     backendA:
         registerHealthIndicator: true
         slidingWindowSize: 100
     backendB:
         registerHealthIndicator: true
         slidingWindowSize: 10
         permittedNumberOfCallsInHalfOpenState: 3
         slidingWindowType: TIME_BASED
         recordFailurePredicate: io.github.robwin.exception.RecordFailurePredicate

resilience4j.timelimiter:
 instances:
     backendA:
         timeoutDuration: 2s
         cancelRunningFuture: true
     backendB:
         timeoutDuration: 1s
         cancelRunningFuture: false
  • ReactiveResilience4JCircuitBreakerFactory.create("backendA")Resilience4JCircuitBreakerFactory.create("backendA") 将应用 instances backendA properties

  • ReactiveResilience4JCircuitBreakerFactory.create("backendA", "groupA")Resilience4JCircuitBreakerFactory.create("backendA", "groupA") 将应用 instances backendA properties

  • ReactiveResilience4JCircuitBreakerFactory.create("backendC")Resilience4JCircuitBreakerFactory.create("backendC") 将应用 global default properties

  • ReactiveResilience4JCircuitBreakerFactory.create("backendC", "groupC")Resilience4JCircuitBreakerFactory.create("backendC", "groupC") 将应用 global default CircuitBreaker properties 和 config groupC TimeLimiter properties

有关 Resilience4j 属性配置的更多信息,请参阅Resilience4J Spring Boot 2 配置

1.1.6. 舱壁模式支持

如果 resilience4j-bulkhead 在类路径中,Spring Cloud CircuitBreaker 将使用 Resilience4j 舱壁包装所有方法。通过将 spring.cloud.circuitbreaker.bulkhead.resilience4j.enabled 设置为 false,可以禁用 Resilience4j 舱壁。

Spring Cloud CircuitBreaker Resilience4j 提供了两种舱壁模式实现

  • 使用信号量的 SemaphoreBulkhead

  • 使用有界队列和固定线程池的 FixedThreadPoolBulkhead

默认情况下,Spring Cloud CircuitBreaker Resilience4j 使用 FixedThreadPoolBulkhead。要修改默认行为以使用 SemaphoreBulkhead,请将属性 spring.cloud.circuitbreaker.resilience4j.enableSemaphoreDefaultBulkhead 设置为 true

有关舱壁模式实现的更多信息,请参阅Resilience4j 舱壁

Customizer<Resilience4jBulkheadProvider> 可用于提供默认的 BulkheadThreadPoolBulkhead 配置。

@Bean
public Customizer<Resilience4jBulkheadProvider> defaultBulkheadCustomizer() {
    return provider -> provider.configureDefault(id -> new Resilience4jBulkheadConfigurationBuilder()
        .bulkheadConfig(BulkheadConfig.custom().maxConcurrentCalls(4).build())
        .threadPoolBulkheadConfig(ThreadPoolBulkheadConfig.custom().coreThreadPoolSize(1).maxThreadPoolSize(1).build())
        .build()
);
}

1.1.7. 特定舱壁配置

与提供默认的“Bulkhead”或“ThreadPoolBulkhead”配置类似,您可以创建一个 Customizer bean,该 bean 接收 Resilience4jBulkheadProvider

@Bean
public Customizer<Resilience4jBulkheadProvider> slowBulkheadProviderCustomizer() {
    return provider -> provider.configure(builder -> builder
        .bulkheadConfig(BulkheadConfig.custom().maxConcurrentCalls(1).build())
        .threadPoolBulkheadConfig(ThreadPoolBulkheadConfig.ofDefaults()), "slowBulkhead");
}

除了配置创建的舱壁之外,您还可以在舱壁和线程池舱壁创建后但在返回给调用者之前对其进行自定义。为此,可以使用 addBulkheadCustomizeraddThreadPoolBulkheadCustomizer 方法。

舱壁示例
@Bean
public Customizer<Resilience4jBulkheadProvider> customizer() {
    return provider -> provider.addBulkheadCustomizer(bulkhead -> bulkhead.getEventPublisher()
        .onCallRejected(slowRejectedConsumer)
        .onCallFinished(slowFinishedConsumer), "slowBulkhead");
}
线程池舱壁示例
@Bean
public Customizer<Resilience4jBulkheadProvider> slowThreadPoolBulkheadCustomizer() {
    return provider -> provider.addThreadPoolBulkheadCustomizer(threadPoolBulkhead -> threadPoolBulkhead.getEventPublisher()
        .onCallRejected(slowThreadPoolRejectedConsumer)
        .onCallFinished(slowThreadPoolFinishedConsumer), "slowThreadPoolBulkhead");
}

1.1.8. 舱壁属性配置

您可以在应用程序的配置文件中配置 ThreadPoolBulkhead 和 SemaphoreBulkhead 实例。属性配置的优先级高于 Java Customizer 配置。

resilience4j.thread-pool-bulkhead:
    instances:
        backendA:
            maxThreadPoolSize: 1
            coreThreadPoolSize: 1
resilience4j.bulkhead:
    instances:
        backendB:
            maxConcurrentCalls: 10

有关 Resilience4j 属性配置的更多信息,请参阅Resilience4J Spring Boot 2 配置

1.1.9. 收集指标

Spring Cloud Circuit Breaker Resilience4j 包含自动配置,只要类路径中包含正确的依赖项,即可设置指标收集。要启用指标收集,必须包含 org.springframework.boot:spring-boot-starter-actuatorio.github.resilience4j:resilience4j-micrometer。有关存在这些依赖项时生成的指标的更多信息,请参阅Resilience4j 文档

您无需直接包含 micrometer-core,因为它由 spring-boot-starter-actuator 引入。

1.2. 配置 Spring Retry 断路器

Spring Retry 为 Spring 应用程序提供了声明式重试支持。该项目的一个子集包括实现断路器功能的能力。Spring Retry 通过其 CircuitBreakerRetryPolicy有状态重试 的组合提供断路器实现。所有使用 Spring Retry 创建的断路器都将使用 CircuitBreakerRetryPolicyDefaultRetryState 创建。这两个类都可以使用 SpringRetryConfigBuilder 进行配置。

1.2.1. 默认配置

要为所有断路器提供默认配置,请创建一个 Customizer bean,该 bean 接收 SpringRetryCircuitBreakerFactory。可以使用 configureDefault 方法提供默认配置。

@Bean
public Customizer<SpringRetryCircuitBreakerFactory> defaultCustomizer() {
    return factory -> factory.configureDefault(id -> new SpringRetryConfigBuilder(id)
        .retryPolicy(new TimeoutRetryPolicy()).build());
}

1.2.2. 特定断路器配置

与提供默认配置类似,您可以创建一个 Customizer bean,该 bean 接收 SpringRetryCircuitBreakerFactory

@Bean
public Customizer<SpringRetryCircuitBreakerFactory> slowCustomizer() {
    return factory -> factory.configure(builder -> builder.retryPolicy(new SimpleRetryPolicy(1)).build(), "slow");
}

除了配置创建的断路器之外,您还可以在断路器创建后但在返回给调用者之前对其进行自定义。为此,可以使用 addRetryTemplateCustomizers 方法。这对于向 RetryTemplate 添加事件处理程序非常有用。

@Bean
public Customizer<SpringRetryCircuitBreakerFactory> slowCustomizer() {
    return factory -> factory.addRetryTemplateCustomizers(retryTemplate -> retryTemplate.registerListener(new RetryListener() {

        @Override
        public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
            return false;
        }

        @Override
        public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {

        }

        @Override
        public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {

        }
    }));
}

2. 构建

2.1. 基本编译和测试

要构建源代码,您需要安装 JDK 17。

Spring Cloud 使用 Maven 进行大多数构建相关活动,您应该能够通过克隆您感兴趣的项目并输入以下命令很快上手

$ ./mvnw install
您也可以自行安装 Maven(>=3.3.3),并在下面的示例中用 mvn 命令代替 ./mvnw。如果您这样做,并且您的本地 Maven 设置不包含 Spring 预发布构件的仓库声明,您可能还需要添加 -P spring
请注意,您可能需要通过设置 MAVEN_OPTS 环境变量,并将其值设置为 -Xmx512m -XX:MaxPermSize=128m 来增加 Maven 可用的内存量。我们尝试在 .mvn 配置中涵盖这一点,因此如果您发现必须这样做才能使构建成功,请提出一个问题,将这些设置添加到源代码控制中。

需要中间件(即 Redis)进行测试的项目通常要求安装并运行本地 [Docker](www.docker.com/get-started) 实例。

2.2. 文档

spring-cloud-build 模块有一个“docs”配置文件,如果启用它,它将尝试从 src/main/asciidoc 构建 asciidoc 源。作为该过程的一部分,它将查找 README.adoc 并通过加载所有包含来处理它,但不解析或渲染它,只是将其复制到 ${main.basedir}(默认为 $/tmp/releaser-1706275114670-0/spring-cloud-circuitbreaker/docs,即项目的根目录)。如果 README 中有任何更改,它将在 Maven 构建后显示为正确位置的修改文件。只需提交并推送更改。

2.3. 使用代码

如果您没有 IDE 偏好,我们建议您在处理代码时使用 Spring Tools SuiteEclipse。我们使用 m2eclipse eclipse 插件进行 Maven 支持。只要它们使用 Maven 3.3.3 或更高版本,其他 IDE 和工具也应该可以正常工作。

2.3.1. 激活 Spring Maven 配置

Spring Cloud 项目需要激活“spring”Maven 配置文件才能解析 Spring 里程碑和快照仓库。请使用您首选的 IDE 将此配置文件设置为活动状态,否则您可能会遇到构建错误。

2.3.2. 使用 m2eclipse 导入到 eclipse

我们建议在与 eclipse 合作时使用 m2eclipse eclipse 插件。如果您尚未安装 m2eclipse,可以从“eclipse marketplace”获取。

旧版本的 m2e 不支持 Maven 3.3,因此一旦项目导入 Eclipse,您还需要告诉 m2eclipse 为项目使用正确的配置文件。如果您看到项目中与 POM 相关的许多不同错误,请检查您的安装是否最新。如果您无法升级 m2e,请将“spring”配置文件添加到您的 settings.xml 中。或者,您可以将父 pom 的“spring”配置文件中的存储库设置复制到您的 settings.xml 中。

2.3.3. 不使用 m2eclipse 导入到 eclipse

如果您不想使用 m2eclipse,可以使用以下命令生成 Eclipse 项目元数据:

$ ./mvnw eclipse:eclipse

生成的 Eclipse 项目可以通过从“文件”菜单中选择“导入现有项目”来导入。

3. 贡献

Spring Cloud 在非限制性的 Apache 2.0 许可证下发布,并遵循非常标准的 Github 开发流程,使用 Github 跟踪器处理问题并将拉取请求合并到 master。如果您想贡献哪怕是微不足道的东西,请不要犹豫,但请遵循以下准则。

3.1. 签署贡献者许可协议

在接受非平凡补丁或拉取请求之前,我们需要您签署贡献者许可协议。签署贡献者协议并不授予任何人对主仓库的提交权限,但这意味着我们可以接受您的贡献,并且如果我们接受,您将获得作者署名。活跃的贡献者可能会被邀请加入核心团队,并获得合并拉取请求的权限。

3.2. 行为准则

本项目遵循贡献者盟约 行为准则。通过参与,您应该遵守此准则。请向 [email protected] 报告不可接受的行为。

3.3. 代码约定和内务管理

这些对于拉取请求都不是必不可少的,但它们都会有所帮助。它们也可以在原始拉取请求之后但在合并之前添加。

  • 使用 Spring Framework 代码格式约定。如果您使用 Eclipse,可以使用 Spring Cloud Build 项目中的 eclipse-code-formatter.xml 文件导入格式化程序设置。如果使用 IntelliJ,可以使用 Eclipse Code Formatter Plugin 导入相同的文件。

  • 确保所有新的 .java 文件都包含一个简单的 Javadoc 类注释,至少包含一个标识您的 @author 标签,并且最好至少有一个段落说明该类的用途。

  • 将 ASF 许可头注释添加到所有新的 .java 文件中(从项目中的现有文件复制)

  • 如果您对 .java 文件进行了大量修改(不仅仅是表面上的更改),请将自己添加为 @author

  • 添加一些 Javadoc,如果您更改了命名空间,还要添加一些 XSD 文档元素。

  • 一些单元测试也会有很大帮助——总得有人去做。

  • 如果您的分支没有其他人使用,请将其重新基于当前 master(或主项目中的其他目标分支)。

  • 编写提交消息时请遵循 这些约定,如果您正在修复现有问题,请在提交消息末尾添加 Fixes gh-XXXX(其中 XXXX 是问题编号)。

3.4. Checkstyle

Spring Cloud Build 附带一套 Checkstyle 规则。您可以在 spring-cloud-build-tools 模块中找到它们。该模块下最值得注意的文件是

spring-cloud-build-tools/
└── src
    ├── checkstyle
    │   └── checkstyle-suppressions.xml (3)
    └── main
        └── resources
            ├── checkstyle-header.txt (2)
            └── checkstyle.xml (1)
1 默认 Checkstyle 规则
2 文件头设置
3 默认抑制规则

3.4.1. Checkstyle 配置

Checkstyle 规则默认禁用。要将 Checkstyle 添加到您的项目中,只需定义以下属性和插件。

pom.xml
<properties>
<maven-checkstyle-plugin.failsOnError>true</maven-checkstyle-plugin.failsOnError> (1)
        <maven-checkstyle-plugin.failsOnViolation>true
        </maven-checkstyle-plugin.failsOnViolation> (2)
        <maven-checkstyle-plugin.includeTestSourceDirectory>true
        </maven-checkstyle-plugin.includeTestSourceDirectory> (3)
</properties>

<build>
        <plugins>
            <plugin> (4)
                <groupId>io.spring.javaformat</groupId>
                <artifactId>spring-javaformat-maven-plugin</artifactId>
            </plugin>
            <plugin> (5)
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-checkstyle-plugin</artifactId>
            </plugin>
        </plugins>

    <reporting>
        <plugins>
            <plugin> (5)
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-checkstyle-plugin</artifactId>
            </plugin>
        </plugins>
    </reporting>
</build>
1 Checkstyle 错误时构建失败
2 Checkstyle 违规时构建失败
3 Checkstyle 也会分析测试源代码
4 添加 Spring Java Format 插件,该插件将重新格式化您的代码以通过大多数 Checkstyle 格式化规则
5 将 Checkstyle 插件添加到您的构建和报告阶段

如果您需要抑制某些规则(例如,行长需要更长),那么只需在 ${project.root}/src/checkstyle/checkstyle-suppressions.xml 下定义一个包含抑制内容的文件即可。示例

projectRoot/src/checkstyle/checkstyle-suppressions.xml
<?xml version="1.0"?>
<!DOCTYPE suppressions PUBLIC
        "-//Puppy Crawl//DTD Suppressions 1.1//EN"
        "https://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
<suppressions>
    <suppress files=".*ConfigServerApplication\.java" checks="HideUtilityClassConstructor"/>
    <suppress files=".*ConfigClientWatch\.java" checks="LineLengthCheck"/>
</suppressions>

建议将 ${spring-cloud-build.rootFolder}/.editorconfig${spring-cloud-build.rootFolder}/.springformat 复制到您的项目中。这样,将应用一些默认格式规则。您可以通过运行此脚本来完成

$ curl https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/.editorconfig -o .editorconfig
$ touch .springformat

3.5. IDE 设置

3.5.1. Intellij IDEA

为了设置 Intellij,您应该导入我们的编码约定、检查配置文件并设置 Checkstyle 插件。以下文件可以在 Spring Cloud Build 项目中找到。

spring-cloud-build-tools/
└── src
    ├── checkstyle
    │   └── checkstyle-suppressions.xml (3)
    └── main
        └── resources
            ├── checkstyle-header.txt (2)
            ├── checkstyle.xml (1)
            └── intellij
                ├── Intellij_Project_Defaults.xml (4)
                └── Intellij_Spring_Boot_Java_Conventions.xml (5)
1 默认 Checkstyle 规则
2 文件头设置
3 默认抑制规则
4 Intellij 的项目默认设置,应用了大部分 Checkstyle 规则
5 Intellij 的项目样式约定,应用了大部分 Checkstyle 规则
Code style
图 1. 代码样式

转到 FileSettingsEditorCode style。在那里点击 Scheme 部分旁边的图标。然后,点击 Import Scheme 值并选择 Intellij IDEA code style XML 选项。导入 spring-cloud-build-tools/src/main/resources/intellij/Intellij_Spring_Boot_Java_Conventions.xml 文件。

Code style
图 2. 检查配置文件

转到 FileSettingsEditorInspections。在那里点击 Profile 部分旁边的图标。然后,点击 Import Profile 并导入 spring-cloud-build-tools/src/main/resources/intellij/Intellij_Project_Defaults.xml 文件。

Checkstyle

要使 Intellij 与 Checkstyle 配合使用,您必须安装 Checkstyle 插件。建议也安装 Assertions2Assertj 以自动转换 JUnit 断言。

Checkstyle

转到 FileSettingsOther settingsCheckstyle。在那里点击 Configuration file 部分的 + 图标。在那里,您必须定义从何处获取 Checkstyle 规则。在上面的图片中,我们从克隆的 Spring Cloud Build 仓库中选择了规则。但是,您可以指向 Spring Cloud Build 的 GitHub 仓库(例如,对于 checkstyle.xmlraw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/main/resources/checkstyle.xml)。我们需要提供以下变量

请记住将 Scan Scope 设置为 All sources,因为我们将 Checkstyle 规则应用于生产和测试源代码。

3.6. 重复查找器

Spring Cloud Build 带来了 basepom:duplicate-finder-maven-plugin,它能够标记 Java 类路径上的重复和冲突的类和资源。

3.6.1. 重复查找器配置

重复查找器默认启用,将在 Maven 构建的 verify 阶段运行,但只有当您将 duplicate-finder-maven-plugin 添加到项目的 pom.xmlbuild 部分时,它才会在您的项目中生效。

pom.xml
<build>
    <plugins>
        <plugin>
            <groupId>org.basepom.maven</groupId>
            <artifactId>duplicate-finder-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

对于其他属性,我们已按照插件文档中列出的默认值进行设置。

您可以通过设置所选属性的值并加上 duplicate-finder-maven-plugin 前缀来轻松覆盖它们。例如,将 duplicate-finder-maven-plugin.skip 设置为 true 以跳过构建中的重复检查。

如果您需要在设置中添加 ignoredClassPatternsignoredResourcePatterns,请务必将它们添加到项目的插件配置部分。

<build>
    <plugins>
        <plugin>
            <groupId>org.basepom.maven</groupId>
            <artifactId>duplicate-finder-maven-plugin</artifactId>
            <configuration>
                <ignoredClassPatterns>
                    <ignoredClassPattern>org.joda.time.base.BaseDateTime</ignoredClassPattern>
                    <ignoredClassPattern>.*module-info</ignoredClassPattern>
                </ignoredClassPatterns>
                <ignoredResourcePatterns>
                    <ignoredResourcePattern>changelog.txt</ignoredResourcePattern>
                </ignoredResourcePatterns>
            </configuration>
        </plugin>
    </plugins>
</build>
© . This site is unofficial and not affiliated with VMware.