Skip to content

Commit f5b03c8

Browse files
committed
Rework Repacakger timeout code
Pull up common timeout code into Repackager and remove the need for custom subclasses. See gh-7263
1 parent dada742 commit f5b03c8

File tree

3 files changed

+62
-50
lines changed
  • spring-boot-tools
    • spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/repackage
    • spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools
    • spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven

3 files changed

+62
-50
lines changed

spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/repackage/RepackageTask.java

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import java.util.HashSet;
2222
import java.util.Map;
2323
import java.util.Set;
24-
import java.util.concurrent.TimeUnit;
2524

2625
import org.gradle.api.Action;
2726
import org.gradle.api.DefaultTask;
@@ -35,6 +34,7 @@
3534
import org.springframework.boot.loader.tools.DefaultLaunchScript;
3635
import org.springframework.boot.loader.tools.LaunchScript;
3736
import org.springframework.boot.loader.tools.Repackager;
37+
import org.springframework.boot.loader.tools.Repackager.MainClassTimeoutWarningListener;
3838
import org.springframework.util.FileCopyUtils;
3939

4040
/**
@@ -46,8 +46,6 @@
4646
*/
4747
public class RepackageTask extends DefaultTask {
4848

49-
private static final long FIND_WARNING_TIMEOUT = TimeUnit.SECONDS.toMillis(10);
50-
5149
private String customConfiguration;
5250

5351
private Object withJarTask;
@@ -215,7 +213,9 @@ private void repackage(File file) {
215213
copy(file, outputFile);
216214
file = outputFile;
217215
}
218-
Repackager repackager = new LoggingRepackager(file);
216+
Repackager repackager = new Repackager(file);
217+
repackager.addMainClassTimeoutWarningListener(
218+
new LoggingMainClassTimeoutWarningListener());
219219
setMainClass(repackager);
220220
if (this.extension.convertLayout() != null) {
221221
repackager.setLayout(this.extension.convertLayout());
@@ -305,26 +305,13 @@ private Map<String, String> getEmbeddedLaunchScriptProperties() {
305305
/**
306306
* {@link Repackager} that also logs when searching takes too long.
307307
*/
308-
private class LoggingRepackager extends Repackager {
309-
310-
LoggingRepackager(File source) {
311-
super(source);
312-
}
308+
private class LoggingMainClassTimeoutWarningListener
309+
implements MainClassTimeoutWarningListener {
313310

314311
@Override
315-
protected String findMainMethod(java.util.jar.JarFile source) throws IOException {
316-
long startTime = System.currentTimeMillis();
317-
try {
318-
return super.findMainMethod(source);
319-
}
320-
finally {
321-
long duration = System.currentTimeMillis() - startTime;
322-
if (duration > FIND_WARNING_TIMEOUT) {
323-
getLogger().warn("Searching for the main-class is taking "
324-
+ "some time, consider using setting "
325-
+ "'springBoot.mainClass'");
326-
}
327-
}
312+
public void handleTimeoutWarning(long duration, String mainMethod) {
313+
getLogger().warn("Searching for the main-class is taking "
314+
+ "some time, consider using setting " + "'springBoot.mainClass'");
328315
}
329316

330317
}

spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Repackager.java

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.util.HashSet;
2525
import java.util.List;
2626
import java.util.Set;
27+
import java.util.concurrent.TimeUnit;
2728
import java.util.jar.JarEntry;
2829
import java.util.jar.JarFile;
2930
import java.util.jar.Manifest;
@@ -53,6 +54,10 @@ public class Repackager {
5354

5455
private static final byte[] ZIP_FILE_HEADER = new byte[] { 'P', 'K', 3, 4 };
5556

57+
private static final long FIND_WARNING_TIMEOUT = TimeUnit.SECONDS.toMillis(10);
58+
59+
private List<MainClassTimeoutWarningListener> mainClassTimeoutListeners = new ArrayList<MainClassTimeoutWarningListener>();
60+
5661
private String mainClass;
5762

5863
private boolean backupSource = true;
@@ -69,6 +74,16 @@ public Repackager(File source) {
6974
this.layout = Layouts.forFile(source);
7075
}
7176

77+
/**
78+
* Add a listener that will be triggered to dispaly a warning if searching for the
79+
* main class takes too long.
80+
* @param listener the listener to add
81+
*/
82+
public void addMainClassTimeoutWarningListener(
83+
MainClassTimeoutWarningListener listener) {
84+
this.mainClassTimeoutListeners.add(listener);
85+
}
86+
7287
/**
7388
* Sets the main class that should be run. If not specified the value from the
7489
* MANIFEST will be used, or if no manifest entry is found the archive will be
@@ -281,7 +296,7 @@ private Manifest buildManifest(JarFile source) throws IOException {
281296
startClass = manifest.getMainAttributes().getValue(MAIN_CLASS_ATTRIBUTE);
282297
}
283298
if (startClass == null) {
284-
startClass = findMainMethod(source);
299+
startClass = findMainMethodWithTimeoutWarning(source);
285300
}
286301
String launcherClassName = this.layout.getLauncherClassName();
287302
if (launcherClassName != null) {
@@ -306,6 +321,18 @@ else if (startClass != null) {
306321
return manifest;
307322
}
308323

324+
private String findMainMethodWithTimeoutWarning(JarFile source) throws IOException {
325+
long startTime = System.currentTimeMillis();
326+
String mainMethod = findMainMethod(source);
327+
long duration = System.currentTimeMillis() - startTime;
328+
if (duration > FIND_WARNING_TIMEOUT) {
329+
for (MainClassTimeoutWarningListener listener : this.mainClassTimeoutListeners) {
330+
listener.handleTimeoutWarning(duration, mainMethod);
331+
}
332+
}
333+
return mainMethod;
334+
}
335+
309336
protected String findMainMethod(JarFile source) throws IOException {
310337
return MainClassFinder.findSingleMainClass(source,
311338
this.layout.getClassesLocation());
@@ -324,6 +351,21 @@ private void deleteFile(File file) {
324351
}
325352
}
326353

354+
/**
355+
* Callback interface used to present a warning when finding the main class takes too
356+
* long.
357+
*/
358+
public interface MainClassTimeoutWarningListener {
359+
360+
/**
361+
* Handle a timeout warning.
362+
* @param duration the amount of time it took to find the main method
363+
* @param mainMethod the main method that was actually found
364+
*/
365+
void handleTimeoutWarning(long duration, String mainMethod);
366+
367+
}
368+
327369
/**
328370
* An {@code EntryTransformer} that renames entries by applying a prefix.
329371
*/

spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RepackageMojo.java

Lines changed: 10 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,11 @@
2222
import java.util.List;
2323
import java.util.Properties;
2424
import java.util.Set;
25-
import java.util.concurrent.TimeUnit;
26-
import java.util.jar.JarFile;
2725

2826
import org.apache.maven.artifact.Artifact;
2927
import org.apache.maven.model.Dependency;
3028
import org.apache.maven.plugin.MojoExecutionException;
3129
import org.apache.maven.plugin.MojoFailureException;
32-
import org.apache.maven.plugin.logging.Log;
3330
import org.apache.maven.plugins.annotations.Component;
3431
import org.apache.maven.plugins.annotations.LifecyclePhase;
3532
import org.apache.maven.plugins.annotations.Mojo;
@@ -46,6 +43,7 @@
4643
import org.springframework.boot.loader.tools.Layouts;
4744
import org.springframework.boot.loader.tools.Libraries;
4845
import org.springframework.boot.loader.tools.Repackager;
46+
import org.springframework.boot.loader.tools.Repackager.MainClassTimeoutWarningListener;
4947

5048
/**
5149
* Repackages existing JAR and WAR archives so that they can be executed from the command
@@ -59,8 +57,6 @@
5957
@Mojo(name = "repackage", defaultPhase = LifecyclePhase.PACKAGE, requiresProject = true, threadSafe = true, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, requiresDependencyCollection = ResolutionScope.COMPILE_PLUS_RUNTIME)
6058
public class RepackageMojo extends AbstractDependencyFilterMojo {
6159

62-
private static final long FIND_WARNING_TIMEOUT = TimeUnit.SECONDS.toMillis(10);
63-
6460
/**
6561
* The Maven project.
6662
* @since 1.0
@@ -224,7 +220,9 @@ private File getTargetFile() {
224220
}
225221

226222
private Repackager getRepackager(File source) {
227-
Repackager repackager = new LoggingRepackager(source, getLog());
223+
Repackager repackager = new Repackager(source);
224+
repackager.addMainClassTimeoutWarningListener(
225+
new LoggingMainClassTimeoutWarningListener());
228226
repackager.setMainClass(this.mainClass);
229227
if (this.layout != null) {
230228
getLog().info("Layout: " + this.layout);
@@ -356,30 +354,15 @@ public Layout layout() {
356354

357355
}
358356

359-
private static class LoggingRepackager extends Repackager {
360-
361-
private final Log log;
362-
363-
LoggingRepackager(File source, Log log) {
364-
super(source);
365-
this.log = log;
366-
}
357+
private class LoggingMainClassTimeoutWarningListener
358+
implements MainClassTimeoutWarningListener {
367359

368360
@Override
369-
protected String findMainMethod(JarFile source) throws IOException {
370-
long startTime = System.currentTimeMillis();
371-
try {
372-
return super.findMainMethod(source);
373-
}
374-
finally {
375-
long duration = System.currentTimeMillis() - startTime;
376-
if (duration > FIND_WARNING_TIMEOUT) {
377-
this.log.warn("Searching for the main-class is taking some time, "
378-
+ "consider using the mainClass configuration "
379-
+ "parameter");
380-
}
381-
}
361+
public void handleTimeoutWarning(long duration, String mainMethod) {
362+
getLog().warn("Searching for the main-class is taking some time, "
363+
+ "consider using the mainClass configuration " + "parameter");
382364
}
383365

384366
}
367+
385368
}

0 commit comments

Comments
 (0)