Skip to content

LaunchedURLClassLoader#findResource(s) is startup bottleneck #4557

@tsachev

Description

@tsachev

Our app is using spring boot and is starting usually in around a minute on my laptop, when launched with spring-boot:run, However after repackage things get ugly the startup time increases to 3 mins!!!.
I have investigated where the slow down came from and here is what I found:
trace profiler shows that 40 percent of the startup time goes in Throwable#fillStackTrace()
We have lots of jars as dependencies (400+) and I noticed that LauncedURLClassLoder already does some optimization in this area Handler.setUseFastConnectionExceptions(true) the thing is that this is not called for findResource, and this method is heavily used.
For example aspectj is loading classes bytecode (and not caching) (we use cache and custom aspects).

After the patch below the application started in reasonable time (only around 10 seconds slower then mvn spring-boot:run)

--- a/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/LaunchedURLClassLoader.java
+++ b/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/LaunchedURLClassLoader.java
@@ -82,7 +82,13 @@ public class LaunchedURLClassLoader extends URLClassLoader {
                        if (name.equals("") && hasURLs()) {
                                return getURLs()[0];
                        }
-                       return super.findResource(name);
+                       Handler.setUseFastConnectionExceptions(true);
+                       try {
+                               return super.findResource(name);
+                       }
+                       finally {
+                               Handler.setUseFastConnectionExceptions(false);
+                       }
                }
                catch (IllegalArgumentException ex) {
                        return null;
@@ -94,7 +100,13 @@ public class LaunchedURLClassLoader extends URLClassLoader {
                if (name.equals("") && hasURLs()) {
                        return Collections.enumeration(Arrays.asList(getURLs()));
                }
-               return super.findResources(name);
+               Handler.setUseFastConnectionExceptions(true);
+               try {
+                       return super.findResources(name);
+               }
+               finally {
+                       Handler.setUseFastConnectionExceptions(false);
+               }
        }

        private boolean hasURLs() {

I can create a pull request if this seems reasonable fix.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions