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+ */
116package grails.boot.config
217
318import grails.config.Config
4- import grails.config.Settings
519import grails.core.GrailsApplication
20+ import grails.boot.config.tools.ClassPathScanner
621import grails.core.GrailsApplicationClass
7- import grails.io.IOUtils
822import groovy.transform.CompileStatic
9- import groovy.transform.InheritConstructors
10- import groovy.transform.Memoized
1123import groovy.util.logging.Slf4j
12- import org.grails.asm.AnnotationMetadataReader
1324import org.grails.compiler.injection.AbstractGrailsArtefactTransformer
1425import org.grails.spring.aop.autoproxy.GroovyAwareAspectJAwareAdvisorAutoProxyCreator
1526import org.springframework.aop.config.AopConfigUtils
1627import org.springframework.context.ApplicationContext
1728import org.springframework.context.ApplicationContextAware
18- import org.springframework.context.ResourceLoaderAware
1929import 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
2330import 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
2832import 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
3843class 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