17
17
package org .springframework .boot .gradle .run ;
18
18
19
19
import java .io .File ;
20
+ import java .lang .reflect .Field ;
20
21
import java .util .ArrayList ;
21
22
import java .util .LinkedHashSet ;
22
23
import java .util .List ;
25
26
import org .gradle .api .internal .file .collections .SimpleFileCollection ;
26
27
import org .gradle .api .tasks .JavaExec ;
27
28
import org .gradle .api .tasks .SourceSet ;
29
+ import org .gradle .process .ExecResult ;
30
+ import org .gradle .process .internal .DefaultJavaExecAction ;
31
+ import org .gradle .process .internal .ExecHandle ;
28
32
import org .springframework .boot .loader .tools .FileUtils ;
33
+ import org .springframework .boot .loader .tools .SignalUtils ;
34
+ import org .springframework .util .ReflectionUtils ;
29
35
30
36
/**
31
37
* Extension of the standard 'run' task with additional Spring Boot features.
@@ -38,8 +44,8 @@ public class BootRunTask extends JavaExec {
38
44
@ Override
39
45
public void exec () {
40
46
SourceSet mainSourceSet = SourceSets .findMainSourceSet (getProject ());
41
- final File outputDir = (mainSourceSet == null ? null : mainSourceSet . getOutput ()
42
- .getResourcesDir ());
47
+ final File outputDir = (mainSourceSet == null ? null
48
+ : mainSourceSet . getOutput () .getResourcesDir ());
43
49
final Set <File > resources = new LinkedHashSet <File >();
44
50
if (mainSourceSet != null ) {
45
51
resources .addAll (mainSourceSet .getResources ().getSrcDirs ());
@@ -53,7 +59,32 @@ public void exec() {
53
59
FileUtils .removeDuplicatesFromOutputDirectory (outputDir , directory );
54
60
}
55
61
}
56
- super .exec ();
62
+ try {
63
+ executeReflectively ();
64
+ } catch (Exception e ) {
65
+ getLogger ().info ("Cannot execute action reflectively" );
66
+ super .exec ();
67
+ }
57
68
}
58
69
70
+ private ExecResult executeReflectively () throws Exception {
71
+ Field builder = ReflectionUtils .findField (JavaExec .class , "javaExecHandleBuilder" );
72
+ builder .setAccessible (true );
73
+ DefaultJavaExecAction action = (DefaultJavaExecAction ) builder .get (this );
74
+ setMain (getMain ());
75
+ final ExecHandle execHandle = action .build ();
76
+ ExecResult execResult = execHandle .start ().waitForFinish ();
77
+ if (!isIgnoreExitValue ()) {
78
+ execResult .assertNormalExitValue ();
79
+ }
80
+ SignalUtils .attachSignalHandler (new Runnable () {
81
+ @ Override
82
+ public void run () {
83
+ getLogger ().info ("Aborting java sub-process" );
84
+ execHandle .abort ();
85
+ }
86
+ });
87
+ return execResult ;
88
+ }
89
+
59
90
}
0 commit comments