Skip to content

Commit 1c17a06

Browse files
committed
Merge branch '3.1.x' into 3.2.x
2 parents bc0d233 + e3d398b commit 1c17a06

File tree

4 files changed

+331
-144
lines changed

4 files changed

+331
-144
lines changed
Lines changed: 24 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,36 @@
1+
/*
2+
* Copyright 2015 original 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+
*/
116
package grails.boot.config
217

318
import grails.config.Config
4-
import grails.config.Settings
519
import grails.core.GrailsApplication
20+
import grails.boot.config.tools.ClassPathScanner
621
import grails.core.GrailsApplicationClass
7-
import grails.io.IOUtils
822
import groovy.transform.CompileStatic
9-
import groovy.transform.InheritConstructors
10-
import groovy.transform.Memoized
1123
import groovy.util.logging.Slf4j
12-
import org.grails.asm.AnnotationMetadataReader
1324
import org.grails.compiler.injection.AbstractGrailsArtefactTransformer
1425
import org.grails.spring.aop.autoproxy.GroovyAwareAspectJAwareAdvisorAutoProxyCreator
1526
import org.springframework.aop.config.AopConfigUtils
1627
import org.springframework.context.ApplicationContext
1728
import org.springframework.context.ApplicationContextAware
18-
import org.springframework.context.ResourceLoaderAware
1929
import org.springframework.context.annotation.Bean
20-
import org.springframework.core.io.DefaultResourceLoader
21-
import org.springframework.core.io.Resource
22-
import org.springframework.core.io.UrlResource
2330
import org.springframework.core.io.support.PathMatchingResourcePatternResolver
24-
import org.springframework.core.io.support.ResourcePatternResolver
25-
import org.springframework.core.type.classreading.CachingMetadataReaderFactory
26-
import org.springframework.util.ClassUtils
2731

2832
import java.lang.reflect.Field
33+
2934
/**
3035
* A base class for configurations that bootstrap a Grails application
3136
*
@@ -38,7 +43,6 @@ import java.lang.reflect.Field
3843
class GrailsAutoConfiguration implements GrailsApplicationClass, ApplicationContextAware {
3944

4045
private static final String APC_PRIORITY_LIST_FIELD = "APC_PRIORITY_LIST";
41-
private static final List DEFAULT_IGNORED_ROOT_PACKAGES = ['com', 'org', 'net', 'co', 'java', 'javax', 'groovy']
4246

4347
static {
4448
try {
@@ -55,8 +59,6 @@ class GrailsAutoConfiguration implements GrailsApplicationClass, ApplicationCont
5559
}
5660
}
5761

58-
ResourcePatternResolver resourcePatternResolver = new GrailsClasspathIgnoringResourceResolver(getClass())
59-
6062
ApplicationContext applicationContext
6163

6264
/**
@@ -71,34 +73,17 @@ class GrailsAutoConfiguration implements GrailsApplicationClass, ApplicationCont
7173
* @return The classes that constitute the Grails application
7274
*/
7375
Collection<Class> classes() {
74-
def readerFactory = new CachingMetadataReaderFactory(resourcePatternResolver)
75-
def packages = packageNames().unique()
7676
Collection<Class> classes = new HashSet()
77-
for (pkg in packages) {
78-
if(pkg == null) continue
79-
if(ignoredRootPackages().contains(pkg)) {
80-
continue
81-
}
82-
// if it is the default package
83-
if(pkg == "") {
84-
// try the default package in case of a script without recursing into subpackages
85-
log.error("The application defines a Groovy source using the default package. Please move all Groovy sources into a package.")
86-
String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + "*.class"
87-
classes.addAll scanUsingPattern(pattern, readerFactory)
88-
}
89-
else {
90-
91-
String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
92-
ClassUtils.convertClassNameToResourcePath(pkg) + Settings.CLASS_RESOURCE_PATTERN;
93-
94-
95-
classes.addAll scanUsingPattern(pattern, readerFactory)
96-
}
9777

78+
ClassPathScanner scanner = new ClassPathScanner()
79+
if(limitScanningToApplication()) {
80+
classes.addAll scanner.scan(getClass(), packageNames())
81+
}
82+
else {
83+
classes.addAll scanner.scan(new PathMatchingResourcePatternResolver(applicationContext), packageNames())
9884
}
9985

100-
101-
def classLoader = Thread.currentThread().contextClassLoader
86+
ClassLoader classLoader = getClass().getClassLoader()
10287
for(cls in AbstractGrailsArtefactTransformer.transformedClassNames) {
10388
try {
10489
classes << classLoader.loadClass(cls)
@@ -110,12 +95,6 @@ class GrailsAutoConfiguration implements GrailsApplicationClass, ApplicationCont
11095
return classes
11196
}
11297

113-
/**
114-
* @return The root packages to ignore by default
115-
*/
116-
protected List ignoredRootPackages() {
117-
DEFAULT_IGNORED_ROOT_PACKAGES
118-
}
11998

12099
/**
121100
* Whether classpath scanning should be limited to the application and not dependent JAR files. Users can override this method to enable more broad scanning
@@ -143,23 +122,6 @@ class GrailsAutoConfiguration implements GrailsApplicationClass, ApplicationCont
143122
}
144123

145124

146-
private Collection<Class> scanUsingPattern(String pattern, CachingMetadataReaderFactory readerFactory) {
147-
def resources = limitScanningToApplication() ? this.resourcePatternResolver.getResources(pattern) : new PathMatchingResourcePatternResolver(applicationContext).getResources(pattern)
148-
def classLoader = Thread.currentThread().contextClassLoader
149-
Collection<Class> classes = []
150-
for (Resource res in resources) {
151-
// ignore closures / inner classes
152-
if(!res.filename.contains('$') && !res.filename.startsWith("gsp_")) {
153-
def reader = new AnnotationMetadataReader(res, classLoader)
154-
def metadata = reader.annotationMetadata
155-
if (metadata.annotationTypes.any() { String annotation -> annotation.startsWith('grails.') }) {
156-
classes << classLoader.loadClass(reader.classMetadata.className)
157-
}
158-
}
159-
}
160-
return classes
161-
}
162-
163125
@Override
164126
Closure doWithSpring() { null }
165127

@@ -196,87 +158,5 @@ class GrailsAutoConfiguration implements GrailsApplicationClass, ApplicationCont
196158
grailsApplication.config
197159
}
198160

199-
@CompileStatic
200-
@InheritConstructors
201-
@Slf4j
202-
private static class GrailsClasspathIgnoringResourceResolver extends PathMatchingResourcePatternResolver {
203-
204-
GrailsClasspathIgnoringResourceResolver(Class applicationClass) {
205-
super(new DefaultResourceLoader(new ApplicationRelativeClassLoader(applicationClass)))
206-
}
207-
208-
@Memoized(maxCacheSize = 20)
209-
protected Set<Resource> doFindAllClassPathResources(String path) throws IOException {
210-
Set<Resource> result = new LinkedHashSet<Resource>(16)
211-
ClassLoader cl = getClassLoader()
212-
Enumeration<URL> resourceUrls = (cl != null ? cl.getResources(path) : ClassLoader.getSystemResources(path))
213-
while (resourceUrls.hasMoreElements()) {
214-
215-
URL url = resourceUrls.nextElement()
216-
// if the path is from a JAR file ignore, plugins inside JAR files will have their own mechanism for loading
217-
if(!url.path.contains('jar!/grails/')) {
218-
result.add(convertClassLoaderURL(url))
219-
}
220-
221-
}
222-
return result
223-
}
224-
225-
@Memoized
226-
protected Resource[] findAllClassPathResources(String location) throws IOException {
227-
return super.findAllClassPathResources(location)
228-
}
229-
230-
@Memoized
231-
protected Resource[] findPathMatchingResources(String locationPattern) throws IOException {
232-
return super.findPathMatchingResources(locationPattern)
233-
}
234-
235-
}
236-
237-
private static class ApplicationRelativeClassLoader extends URLClassLoader {
238-
239-
final URL rootResource
240-
final Class applicationClass
241-
final boolean jarDeployed
242-
243-
ApplicationRelativeClassLoader(Class applicationClass) {
244-
super([ IOUtils.findRootResource(applicationClass)] as URL[])
245-
246-
this.rootResource = getURLs()[0]
247-
this.applicationClass = applicationClass
248-
String urlStr = rootResource.toString()
249-
jarDeployed = urlStr.startsWith("jar:")
250-
try {
251-
URL withoutBang = new URL("${urlStr.substring(0, urlStr.length() - 2)}/")
252-
addURL(withoutBang)
253-
254-
} catch (MalformedURLException e) {
255-
// ignore, running as a WAR
256-
}
257-
}
258-
259-
@Override
260-
Enumeration<URL> getResources(String name) throws IOException {
261-
if(jarDeployed && name == '') {
262-
return applicationClass.getClassLoader().getResources(name)
263-
}
264-
else {
265-
return super.findResources(name)
266-
}
267-
}
268-
269-
@Override
270-
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
271-
try {
272-
return super.loadClass(name, resolve)
273-
} catch (ClassNotFoundException cnfe) {
274-
return applicationClass.getClassLoader().loadClass(name)
275-
}
276-
}
277-
}
278-
279-
280-
281161
}
282162

0 commit comments

Comments
 (0)