From 7bec780281fd613a9ef6b0bedccf8f66284aceb9 Mon Sep 17 00:00:00 2001 From: Wenwei Liao Date: Mon, 2 Apr 2018 11:56:27 +0800 Subject: [PATCH 1/2] Use modifiable set for @ServletComponentScan with no packages Previously, when a project contained multiple `@ServletComponentScan` annotated classes in classpath, and at least one annotation don't explicitly specify `basePackages` and `basePackageClass` attribute, the application could fail to start with an UnsupportedOperationException. The failure occurred due to the creating of an unmodifiable set when no base packages are configured and a subsequent attempt to add base packages to that sit. This commit fixes the issue by removing the use of an unmodifiable set when `@ServletComponentScan` with no base packages in processed before any other `@ServletComponentScan` annotations. See gh-12715 --- .../boot/web/servlet/ServletComponentScanRegistrar.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrar.java b/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrar.java index f3c6b98ac7a..9489d01dc29 100644 --- a/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrar.java +++ b/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrar.java @@ -17,7 +17,6 @@ package org.springframework.boot.web.servlet; import java.util.Arrays; -import java.util.Collections; import java.util.LinkedHashSet; import java.util.Set; @@ -84,8 +83,7 @@ class ServletComponentScanRegistrar implements ImportBeanDefinitionRegistrar { packagesToScan.add(ClassUtils.getPackageName(basePackageClass)); } if (packagesToScan.isEmpty()) { - return Collections - .singleton(ClassUtils.getPackageName(metadata.getClassName())); + packagesToScan.add(ClassUtils.getPackageName(metadata.getClassName())); } return packagesToScan; } From 6078fdaed82cf96bc427fd9107d14d2ba5e8eece Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 3 Apr 2018 10:42:07 +0100 Subject: [PATCH 2/2] Polish "Use modifiable set for @ServletComponentScan with no packages" Closes gh-12715 --- .../ServletComponentScanRegistrar.java | 2 +- .../ServletComponentScanRegistrarTests.java | 39 ++++++++++++++++++- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrar.java b/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrar.java index 9489d01dc29..5c787edc0de 100644 --- a/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrar.java +++ b/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrar.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * Copyright 2012-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/spring-boot/src/test/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrarTests.java b/spring-boot/src/test/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrarTests.java index 5b1b6d2c80f..8d1ddf8313e 100644 --- a/spring-boot/src/test/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrarTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/web/servlet/ServletComponentScanRegistrarTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * Copyright 2012-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -107,6 +107,37 @@ public class ServletComponentScanRegistrarTests { "com.example.bar", "com.example.baz"); } + @Test + public void withNoBasePackagesScanningUsesBasePackageOfAnnotatedClass() { + this.context = new AnnotationConfigApplicationContext(NoBasePackages.class); + ServletComponentRegisteringPostProcessor postProcessor = this.context + .getBean(ServletComponentRegisteringPostProcessor.class); + assertThat(postProcessor.getPackagesToScan()) + .containsExactly("org.springframework.boot.web.servlet"); + } + + @Test + public void noBasePackageAndBasePackageAreCombinedCorrectly() { + this.context = new AnnotationConfigApplicationContext(NoBasePackages.class, + BasePackages.class); + ServletComponentRegisteringPostProcessor postProcessor = this.context + .getBean(ServletComponentRegisteringPostProcessor.class); + assertThat(postProcessor.getPackagesToScan()).containsExactlyInAnyOrder( + "org.springframework.boot.web.servlet", "com.example.foo", + "com.example.bar"); + } + + @Test + public void basePackageAndNoBasePackageAreCombinedCorrectly() { + this.context = new AnnotationConfigApplicationContext(BasePackages.class, + NoBasePackages.class); + ServletComponentRegisteringPostProcessor postProcessor = this.context + .getBean(ServletComponentRegisteringPostProcessor.class); + assertThat(postProcessor.getPackagesToScan()).containsExactlyInAnyOrder( + "org.springframework.boot.web.servlet", "com.example.foo", + "com.example.bar"); + } + @Configuration @ServletComponentScan({ "com.example.foo", "com.example.bar" }) static class ValuePackages { @@ -137,4 +168,10 @@ public class ServletComponentScanRegistrarTests { } + @Configuration + @ServletComponentScan + static class NoBasePackages { + + } + }