3.0.3
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您可以通过设置为 来禁用 Resilience4J 自动配置
false。
1.1.3. 默认配置
要为所有断路器提供默认配置,请创建一个Customizer传递
Resilience4JCircuitBreakerFactory或 的bean ReactiveResilience4JCircuitBreakerFactory。该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传递 a
Resilience4JCircuitBreakerFactory或 的bean ReactiveResilience4JCircuitBreakerFactory。
@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。断路器属性配置
您可以在应用程序的配置属性文件中进行配置CircuitBreaker和配置或实例。TimeLimiter属性配置的优先级高于JavaCustomizer配置。
优先级从上到下递减。
-
Method(id) config - 关于特定方法或操作
-
服务(组)配置 - 针对特定应用程序服务或操作
-
全局默认配置
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 and config groupC TimeLimiter properties
有关 Resilience4j 属性配置的更多信息,请参阅Resilience4J Spring Boot 2 配置。
1.1.6。舱壁图案支撑
如果resilience4j-bulkhead位于类路径上,Spring Cloud CircuitBreaker 将使用 Resilience4j Bulkhead 包装所有方法。spring.cloud.circuitbreaker.bulkhead.resilience4j.enabled您可以通过设置为 来禁用 Resilience4j Bulkhead false。
Spring Cloud CircuitBreaker Resilience4j 提供了两种舱壁模式的实现:
-
a
SemaphoreBulkhead使用信号量 -
a
FixedThreadPoolBulkhead使用有界队列和固定线程池。
默认情况下,Spring Cloud CircuitBreaker Resilience4j 使用FixedThreadPoolBulkhead. 要修改要使用的默认行为,SemaphoreBulkhead请将该属性设置spring.cloud.circuitbreaker.resilience4j.enableSemaphoreDefaultBulkhead为true。
有关 Bulkhead 模式实现的更多信息,请参阅Resilience4j Bulkhead。
可Customizer<Resilience4jBulkheadProvider>用于提供默认值Bulkhead和ThreadPoolBulkhead配置。
@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传递Resilience4jBulkheadProvider.
@Bean
public Customizer<Resilience4jBulkheadProvider> slowBulkheadProviderCustomizer() {
return provider -> provider.configure(builder -> builder
.bulkheadConfig(BulkheadConfig.custom().maxConcurrentCalls(1).build())
.threadPoolBulkheadConfig(ThreadPoolBulkheadConfig.ofDefaults()), "slowBulkhead");
}
除了配置创建的隔板之外,您还可以在创建隔板和线程池隔板之后但将其返回给调用者之前自定义隔板和线程池隔板。为此,您可以使用addBulkheadCustomizer和addThreadPoolBulkheadCustomizer
方法。
舱壁示例
@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 实例。属性配置的优先级高于JavaCustomizer配置。
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-actuator, 和io.github.resilience4j:resilience4j-micrometer。有关存在这些依赖项时生成的指标的更多信息,请参阅Resilience4j 文档。
您不必micrometer-core直接包含,因为它是由spring-boot-starter-actuator
|
1.2. 配置 Spring Retry 断路器
Spring Retry 为 Spring 应用程序提供声明式重试支持。该项目的一个子集包括实现断路器功能的能力。CircuitBreakerRetryPolicy
Spring Retry 通过它和有状态重试的组合提供了断路器实现
。所有使用 Spring Retry 创建的断路器都将使用CircuitBreakerRetryPolicy和 a
创建DefaultRetryState。这两个类都可以使用 进行配置SpringRetryConfigBuilder。
1.2.1. 默认配置
要为所有断路器提供默认配置,请创建一个Customizer传递
SpringRetryCircuitBreakerFactory. 该configureDefault方法可用于提供默认配置。
@Bean
public Customizer<SpringRetryCircuitBreakerFactory> defaultCustomizer() {
return factory -> factory.configureDefault(id -> new SpringRetryConfigBuilder(id)
.retryPolicy(new TimeoutRetryPolicy()).build());
}
1.2.2. 具体断路器配置
与提供默认配置类似,您可以创建一个Customizerbean,并通过
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的命令。如果您这样做,如果您的本地 Maven 设置不包含 Spring 预发布工件的存储库声明,
./mvnw您可能还需要添加。-P spring |
MAVEN_OPTS请注意,您可能需要通过设置环境变量的值(例如 )
来增加 Maven 可用的内存量-Xmx512m -XX:MaxPermSize=128m。我们尝试在配置中涵盖这一点.mvn,因此如果您发现必须这样做才能成功构建,请提出请求以将设置添加到源代码管理中。
|
需要中间件(即Redis)进行测试的项目通常需要安装并运行[Docker]( www.docker.com/get-started )的本地实例。
2.2. 文档
spring-cloud-build 模块有一个“docs”配置文件,如果您打开它,它将尝试从
src/main/asciidoc. 作为该过程的一部分,它将查找 a
README.adoc并通过加载所有包含内容来处理它,但不解析或渲染它,只是将其复制到${main.basedir}
(默认为$/tmp/releaser-1690490183390-0/spring-cloud-circuitbreaker/docs,即项目的根目录)。如果 README 中有任何更改,它将在 Maven 构建后作为修改后的文件显示在正确的位置。只需提交并推动更改即可。
2.3. 使用代码
如果您没有 IDE 偏好,我们建议您 在处理代码时使用Spring Tools Suite或 Eclipse 。我们使用 m2eclipse eclipse 插件来提供 Maven 支持。其他 IDE 和工具只要使用 Maven 3.3.3 或更高版本,也应该可以正常工作。
2.3.1. 激活 Spring Maven 配置文件
Spring Cloud 项目需要激活“spring”Maven 配置文件才能解析 spring 里程碑和快照存储库。使用您首选的 IDE 将此配置文件设置为活动状态,否则您可能会遇到构建错误。
2.3.2. 使用 m2eclipse 导入到 eclipse
使用 eclipse 时,我们推荐使用m2eclipse eclipse 插件。如果您尚未安装 m2eclipse,则可以从“eclipse market”获取它。
旧版本的 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 项目可以通过import existing projects
从file菜单中选择来导入。
3. 贡献
Spring Cloud 在非限制性 Apache 2.0 许可证下发布,并遵循非常标准的 Github 开发流程,使用 Github 跟踪器处理问题并将拉取请求合并到 master 中。如果您想贡献一些微不足道的东西,请不要犹豫,但请遵循以下准则。
3.1. 签署贡献者许可协议
在我们接受重要的补丁或拉取请求之前,我们需要您签署 贡献者许可协议。签署贡献者协议并不授予任何人对主存储库的提交权,但这确实意味着我们可以接受您的贡献,如果我们这样做,您将获得作者信用。活跃的贡献者可能会被要求加入核心团队,并被赋予合并拉取请求的能力。
3.2. 行为守则
该项目遵守贡献者契约行为准则。通过参与,您应该遵守此准则。请向spring-code-of-conduct@pivotal.io报告不可接受的行为。
3.3. 代码约定和内务管理
这些对于拉取请求来说都不是必需的,但它们都会有所帮助。它们也可以在原始拉取请求之后、合并之前添加。
-
使用 Spring 框架代码格式约定。如果您使用 Eclipse,则可以使用 Spring Cloud Build
eclipse-code-formatter.xml项目中的文件 导入格式化程序设置。如果使用 IntelliJ,您可以使用 Eclipse Code Formatter 插件导入相同的文件。 -
确保所有新
.java文件都有一个简单的 Javadoc 类注释,其中至少有一个@author标识您的标签,最好至少有一段说明该类的用途。 -
将 ASF 许可证头注释添加到所有新
.java文件(从项目中的现有文件复制) -
将您自己添加到
@author您进行大量修改(不仅仅是外观更改)的 .java 文件中。 -
添加一些 Javadocs,如果更改命名空间,还添加一些 XSD 文档元素。
-
一些单元测试也会有很大帮助——必须有人来做。
-
如果没有其他人在使用您的分支,请根据当前主分支(或主项目中的其他目标分支)重新调整其基础。
-
编写提交消息时请遵循以下约定,如果您要修复现有问题,请
Fixes gh-XXXX在提交消息末尾添加(其中 XXXX 是问题编号)。
3.4. 格子风格
Spring Cloud Build 附带了一组 checkstyle 规则。您可以在模块中找到它们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 添加到您的项目中,只需定义以下属性和插件。
<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抑制下定义一个文件就足够了。例子:
<?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项目中可以找到以下文件。
└── 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 | 应用大多数 Checkstyle 规则的 Intellij 项目样式约定 |
转到File→ Settings→ Editor→ Code style。单击该Scheme部分旁边的图标。在那里,单击该Import Scheme值并选择该Intellij IDEA code style XML选项。导入spring-cloud-build-tools/src/main/resources/intellij/Intellij_Spring_Boot_Java_Conventions.xml文件。
转到File→ Settings→ Editor→ Inspections。单击该Profile部分旁边的图标。在那里,单击Import Profile并导入spring-cloud-build-tools/src/main/resources/intellij/Intellij_Project_Defaults.xml文件。
要让 Intellij 与 Checkstyle 配合使用,您必须安装该Checkstyle插件。建议还安装Assertions2Assertj自动转换 JUnit 断言
转到File→ Settings→ Other settings→ Checkstyle。单击+该Configuration file部分中的图标。在那里,您必须定义应从何处选择检查样式规则。在上图中,我们从克隆的 Spring Cloud Build 存储库中选择了规则。但是,您可以指向 Spring Cloud Build 的 GitHub 存储库(例如checkstyle.xml: raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/main/resources/checkstyle.xml)。我们需要提供以下变量:
-
checkstyle.header.file- 请将其指向 Spring Cloud Build,spring-cloud-build-tools/src/main/resources/checkstyle-header.txt文件可以在您的克隆存储库中或通过raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/main/resources/checkstyle-header.txtURL。 -
checkstyle.suppressions.file- 默认抑制。请将其指向spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xml您克隆的存储库中或通过raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xmlURL 的 Spring Cloud Build 文件。 -
checkstyle.additional.suppressions.file- 此变量对应于本地项目中的抑制。例如,您正在研究spring-cloud-contract. 然后指向该project-root/src/checkstyle/checkstyle-suppressions.xml文件夹。的示例spring-cloud-contract是:/home/username/spring-cloud-contract/src/checkstyle/checkstyle-suppressions.xml。
请记住设置为,Scan Scope因为All sources我们对生产和测试源应用 checkstyle 规则。
|
3.6. 重复查找器
Spring Cloud Build 带来了 basepom:duplicate-finder-maven-plugin, ,可以在 java 类路径上标记重复和冲突的类和资源。
3.6.1. 重复查找器配置
重复查找器默认启用,并将在verify您的 Maven 构建阶段运行,但只有将 添加到duplicate-finder-maven-plugin项目build的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以便在构建中跳过重复检查。
如果您需要添加ignoredClassPatterns或ignoredResourcePatterns到您的设置中,请确保将它们添加到项目的插件配置部分:
<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>