Skip to content

Commit a9b98ca

Browse files
committed
Allow loading from package names without dots
Update BeanDefinitionLoader to support loading from package names that do not contain dots. Prior to this commit `new BeanDefinitionLoader(registry, "somepackage")` would fail because "somepackage" exists and is a resource but does not contain valid XML. Somewhat surprisingly the InputStream returned by the resource actually contains the listing of files in the package. Fixes gh-6126
1 parent 1528764 commit a9b98ca

File tree

3 files changed

+59
-1
lines changed

3 files changed

+59
-1
lines changed

spring-boot/src/main/java/org/springframework/boot/BeanDefinitionLoader.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
3434
import org.springframework.core.annotation.AnnotationUtils;
3535
import org.springframework.core.env.ConfigurableEnvironment;
36+
import org.springframework.core.io.ClassPathResource;
3637
import org.springframework.core.io.Resource;
3738
import org.springframework.core.io.ResourceLoader;
3839
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
@@ -201,7 +202,7 @@ private int load(CharSequence source) {
201202
int loadCount = 0;
202203
boolean atLeastOneResourceExists = false;
203204
for (Resource resource : resources) {
204-
if (resource != null && resource.exists()) {
205+
if (isLoadCandidate(resource)) {
205206
atLeastOneResourceExists = true;
206207
loadCount += load(resource);
207208
}
@@ -235,6 +236,28 @@ private Resource[] findResources(String source) {
235236
}
236237
}
237238

239+
private boolean isLoadCandidate(Resource resource) {
240+
if (resource == null || !resource.exists()) {
241+
return false;
242+
}
243+
if (resource instanceof ClassPathResource) {
244+
// A simple package without a '.' may accidentally get loaded as an XML
245+
// document if we're not careful. The result of getInputStream() will be
246+
// a file list of the package content. We double check here that it's not
247+
// actually a package.
248+
String path = ((ClassPathResource) resource).getPath();
249+
if (path.indexOf(".") == -1) {
250+
try {
251+
return Package.getPackage(path) == null;
252+
}
253+
catch (Exception ex) {
254+
// Ignore
255+
}
256+
}
257+
}
258+
return true;
259+
}
260+
238261
private Package findPackage(CharSequence source) {
239262
Package pkg = Package.getPackage(source.toString());
240263
if (pkg != null) {

spring-boot/src/test/java/org/springframework/boot/BeanDefinitionLoaderTests.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.junit.After;
2020
import org.junit.Before;
2121
import org.junit.Test;
22+
import sampleconfig.MyComponentInPackageWithoutDot;
2223

2324
import org.springframework.boot.sampleconfig.MyComponent;
2425
import org.springframework.context.support.StaticApplicationContext;
@@ -134,6 +135,16 @@ public void loadPackageName() throws Exception {
134135
assertTrue(this.registry.containsBean("myComponent"));
135136
}
136137

138+
@Test
139+
public void loadPackageNameWithoutDot() throws Exception {
140+
// See gh-6126
141+
BeanDefinitionLoader loader = new BeanDefinitionLoader(this.registry,
142+
MyComponentInPackageWithoutDot.class.getPackage().getName());
143+
int loaded = loader.load();
144+
assertThat(loaded, equalTo(1));
145+
assertTrue(this.registry.containsBean("myComponentInPackageWithoutDot"));
146+
}
147+
137148
@Test
138149
public void loadPackageAndClassDoesNotDoubleAdd() throws Exception {
139150
BeanDefinitionLoader loader = new BeanDefinitionLoader(this.registry,
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright 2012-2013 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package sampleconfig;
18+
19+
import org.springframework.stereotype.Component;
20+
21+
@Component
22+
public class MyComponentInPackageWithoutDot {
23+
24+
}

0 commit comments

Comments
 (0)