Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
S
spring-boot
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
DEMO
spring-boot
Commits
bce4bb88
Commit
bce4bb88
authored
Jun 04, 2015
by
Phillip Webb
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Polish start stop support
parent
09a29a72
Changes
13
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
274 additions
and
232 deletions
+274
-232
SpringApplicationLifecycleAutoConfiguration.java
.../context/SpringApplicationLifecycleAutoConfiguration.java
+6
-5
SpringApplicationLifecycleAutoConfigurationTests.java
...ext/SpringApplicationLifecycleAutoConfigurationTests.java
+12
-14
RunProcess.java
...ava/org/springframework/boot/loader/tools/RunProcess.java
+8
-9
SampleApplication.java
...t-stop-fork/src/main/java/org/test/SampleApplication.java
+8
-6
SampleApplication.java
.../start-stop/src/main/java/org/test/SampleApplication.java
+8
-6
AbstractRunMojo.java
.../java/org/springframework/boot/maven/AbstractRunMojo.java
+13
-13
RunArguments.java
...ain/java/org/springframework/boot/maven/RunArguments.java
+1
-1
RunMojo.java
...src/main/java/org/springframework/boot/maven/RunMojo.java
+5
-4
SpringApplicationLifecycleClient.java
...ramework/boot/maven/SpringApplicationLifecycleClient.java
+29
-26
StartMojo.java
...c/main/java/org/springframework/boot/maven/StartMojo.java
+134
-103
StopMojo.java
...rc/main/java/org/springframework/boot/maven/StopMojo.java
+27
-24
SpringApplicationLifecycleRegistrar.java
...ork/boot/context/SpringApplicationLifecycleRegistrar.java
+13
-12
SpringApplicationLifecycleRegistrarTests.java
...oot/context/SpringApplicationLifecycleRegistrarTests.java
+10
-9
No files found.
spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/context/SpringApplicationLifecycleAutoConfiguration.java
View file @
bce4bb88
...
...
@@ -43,7 +43,8 @@ import org.springframework.jmx.export.MBeanExporter;
class
SpringApplicationLifecycleAutoConfiguration
{
/**
* The property to use to customize the {@code ObjectName} of the application lifecycle mbean.
* The property to use to customize the {@code ObjectName} of the application
* lifecycle mbean.
*/
static
final
String
JMX_NAME_PROPERTY
=
"spring.context.lifecycle.jmx-name"
;
...
...
@@ -61,10 +62,10 @@ class SpringApplicationLifecycleAutoConfiguration {
@Bean
public
SpringApplicationLifecycleRegistrar
springApplicationLifecycleRegistrar
()
throws
MalformedObjectNameException
{
String
jmxName
=
this
.
environment
.
getProperty
(
JMX_NAME_PROPERTY
,
DEFAULT_JMX_NAME
);
if
(
mbeanExporter
!=
null
)
{
// Make sure to not register that MBean twice
mbeanExporter
.
addExcludedBean
(
jmxName
);
String
jmxName
=
this
.
environment
.
getProperty
(
JMX_NAME_PROPERTY
,
DEFAULT_JMX_NAME
);
if
(
this
.
mbeanExporter
!=
null
)
{
// Make sure to not register that MBean twice
this
.
mbeanExporter
.
addExcludedBean
(
jmxName
);
}
return
new
SpringApplicationLifecycleRegistrar
(
jmxName
);
}
...
...
spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/context/SpringApplicationLifecycleAutoConfigurationTests.java
View file @
bce4bb88
...
...
@@ -17,6 +17,7 @@
package
org
.
springframework
.
boot
.
autoconfigure
.
context
;
import
java.lang.management.ManagementFactory
;
import
javax.management.InstanceNotFoundException
;
import
javax.management.MBeanServer
;
import
javax.management.MalformedObjectNameException
;
...
...
@@ -28,7 +29,6 @@ import org.junit.Before;
import
org.junit.Rule
;
import
org.junit.Test
;
import
org.junit.rules.ExpectedException
;
import
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration
;
import
org.springframework.boot.test.EnvironmentTestUtils
;
import
org.springframework.context.annotation.AnnotationConfigApplicationContext
;
...
...
@@ -65,17 +65,16 @@ public class SpringApplicationLifecycleAutoConfigurationTests {
}
@Test
public
void
notRegisteredByDefault
()
throws
MalformedObjectNameException
,
InstanceNotFoundException
{
public
void
notRegisteredByDefault
()
throws
MalformedObjectNameException
,
InstanceNotFoundException
{
load
();
thrown
.
expect
(
InstanceNotFoundException
.
class
);
this
.
thrown
.
expect
(
InstanceNotFoundException
.
class
);
this
.
mBeanServer
.
getObjectInstance
(
createDefaultObjectName
());
}
@Test
public
void
registeredWithProperty
()
throws
Exception
{
load
(
ENABLE_LIFECYCLE_PROP
);
ObjectName
objectName
=
createDefaultObjectName
();
ObjectInstance
objectInstance
=
this
.
mBeanServer
.
getObjectInstance
(
objectName
);
assertNotNull
(
"Lifecycle bean should have been registered"
,
objectInstance
);
...
...
@@ -84,18 +83,17 @@ public class SpringApplicationLifecycleAutoConfigurationTests {
@Test
public
void
registerWithCustomJmxName
()
throws
InstanceNotFoundException
{
String
customJmxName
=
"org.acme:name=FooBar"
;
System
.
setProperty
(
SpringApplicationLifecycleAutoConfiguration
.
JMX_NAME_PROPERTY
,
customJmxName
);
System
.
setProperty
(
SpringApplicationLifecycleAutoConfiguration
.
JMX_NAME_PROPERTY
,
customJmxName
);
try
{
load
(
ENABLE_LIFECYCLE_PROP
);
try
{
this
.
mBeanServer
.
getObjectInstance
(
createObjectName
(
customJmxName
));
}
catch
(
InstanceNotFoundException
e
)
{
catch
(
InstanceNotFoundException
e
x
)
{
fail
(
"lifecycle MBean should have been exposed with custom name"
);
}
thrown
.
expect
(
InstanceNotFoundException
.
class
);
// Should not be exposed
this
.
thrown
.
expect
(
InstanceNotFoundException
.
class
);
// Should not be exposed
this
.
mBeanServer
.
getObjectInstance
(
createDefaultObjectName
());
}
finally
{
...
...
@@ -111,18 +109,18 @@ public class SpringApplicationLifecycleAutoConfigurationTests {
try
{
return
new
ObjectName
(
jmxName
);
}
catch
(
MalformedObjectNameException
e
)
{
throw
new
IllegalStateException
(
"Invalid jmx name "
+
jmxName
,
e
);
catch
(
MalformedObjectNameException
e
x
)
{
throw
new
IllegalStateException
(
"Invalid jmx name "
+
jmxName
,
e
x
);
}
}
private
void
load
(
String
...
environment
)
{
AnnotationConfigApplicationContext
applicationContext
=
new
AnnotationConfigApplicationContext
();
EnvironmentTestUtils
.
addEnvironment
(
applicationContext
,
environment
);
applicationContext
.
register
(
JmxAutoConfiguration
.
class
,
SpringApplicationLifecycleAutoConfiguration
.
class
);
applicationContext
.
register
(
JmxAutoConfiguration
.
class
,
SpringApplicationLifecycleAutoConfiguration
.
class
);
applicationContext
.
refresh
();
this
.
context
=
applicationContext
;
}
}
spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/RunProcess.java
View file @
bce4bb88
...
...
@@ -55,13 +55,6 @@ public class RunProcess {
return
run
(
waitForProcess
,
Arrays
.
asList
(
args
));
}
/**
* Kill this process.
*/
public
void
kill
()
{
doKill
();
}
protected
int
run
(
boolean
waitForProcess
,
Collection
<
String
>
args
)
throws
IOException
{
ProcessBuilder
builder
=
new
ProcessBuilder
(
this
.
command
);
builder
.
command
().
addAll
(
args
);
...
...
@@ -131,7 +124,7 @@ public class RunProcess {
return
true
;
}
}
catch
(
Exception
e
)
{
catch
(
Exception
e
x
)
{
return
true
;
}
return
false
;
...
...
@@ -180,6 +173,13 @@ public class RunProcess {
}
/**
* Kill this process.
*/
public
void
kill
()
{
doKill
();
}
private
boolean
doKill
()
{
// destroy the running process
Process
process
=
this
.
process
;
...
...
@@ -194,7 +194,6 @@ public class RunProcess {
Thread
.
currentThread
().
interrupt
();
}
}
return
false
;
}
...
...
spring-boot-tools/spring-boot-maven-plugin/src/it/start-stop-fork/src/main/java/org/test/SampleApplication.java
View file @
bce4bb88
...
...
@@ -22,8 +22,7 @@ import javax.management.MBeanServer;
import
javax.management.ObjectName
;
/**
* This sample app simulates the JMX Mbean that is exposed by the Spring
* Boot application.
* This sample app simulates the JMX Mbean that is exposed by the Spring Boot application.
*/
public
class
SampleApplication
{
...
...
@@ -31,7 +30,8 @@ public class SampleApplication {
public
static
void
main
(
String
[]
args
)
throws
Exception
{
MBeanServer
mbs
=
ManagementFactory
.
getPlatformMBeanServer
();
ObjectName
name
=
new
ObjectName
(
"org.springframework.boot:type=Lifecycle,name=springApplicationLifecycle"
);
ObjectName
name
=
new
ObjectName
(
"org.springframework.boot:type=Lifecycle,name=springApplicationLifecycle"
);
SpringApplicationLifecycle
mbean
=
new
SpringApplicationLifecycle
();
mbs
.
registerMBean
(
mbean
,
name
);
...
...
@@ -41,7 +41,8 @@ public class SampleApplication {
int
waitAttempts
=
0
;
while
(!
mbean
.
shutdownInvoked
)
{
if
(
waitAttempts
>
10
)
{
throw
new
IllegalStateException
(
"Shutdown should have been invoked by now"
);
throw
new
IllegalStateException
(
"Shutdown should have been invoked by now"
);
}
synchronized
(
lock
)
{
lock
.
wait
(
250
);
...
...
@@ -50,7 +51,6 @@ public class SampleApplication {
}
}
public
interface
SpringApplicationLifecycleMXBean
{
boolean
isReady
();
...
...
@@ -76,5 +76,7 @@ public class SampleApplication {
this
.
shutdownInvoked
=
true
;
System
.
out
.
println
(
"Shutdown requested"
);
}
}
}
spring-boot-tools/spring-boot-maven-plugin/src/it/start-stop/src/main/java/org/test/SampleApplication.java
View file @
bce4bb88
...
...
@@ -21,8 +21,7 @@ import javax.management.MBeanServer;
import
javax.management.ObjectName
;
/**
* This sample app simulates the JMX Mbean that is exposed by the Spring
* Boot application.
* This sample app simulates the JMX Mbean that is exposed by the Spring Boot application.
*/
public
class
SampleApplication
{
...
...
@@ -30,7 +29,8 @@ public class SampleApplication {
public
static
void
main
(
String
[]
args
)
throws
Exception
{
MBeanServer
mbs
=
ManagementFactory
.
getPlatformMBeanServer
();
ObjectName
name
=
new
ObjectName
(
"org.springframework.boot:type=Lifecycle,name=springApplicationLifecycle"
);
ObjectName
name
=
new
ObjectName
(
"org.springframework.boot:type=Lifecycle,name=springApplicationLifecycle"
);
SpringApplicationLifecycle
mbean
=
new
SpringApplicationLifecycle
();
mbs
.
registerMBean
(
mbean
,
name
);
...
...
@@ -40,7 +40,8 @@ public class SampleApplication {
int
waitAttempts
=
0
;
while
(!
mbean
.
shutdownInvoked
)
{
if
(
waitAttempts
>
10
)
{
throw
new
IllegalStateException
(
"Shutdown should have been invoked by now"
);
throw
new
IllegalStateException
(
"Shutdown should have been invoked by now"
);
}
synchronized
(
lock
)
{
lock
.
wait
(
250
);
...
...
@@ -49,7 +50,6 @@ public class SampleApplication {
}
}
public
interface
SpringApplicationLifecycleMXBean
{
boolean
isReady
();
...
...
@@ -75,5 +75,7 @@ public class SampleApplication {
this
.
shutdownInvoked
=
true
;
System
.
out
.
println
(
"Shutdown requested"
);
}
}
}
spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractRunMojo.java
View file @
bce4bb88
...
...
@@ -36,7 +36,6 @@ import org.apache.maven.plugins.annotations.Parameter;
import
org.apache.maven.project.MavenProject
;
import
org.apache.maven.shared.artifact.filter.collection.AbstractArtifactFeatureFilter
;
import
org.apache.maven.shared.artifact.filter.collection.FilterArtifacts
;
import
org.springframework.boot.loader.tools.FileUtils
;
import
org.springframework.boot.loader.tools.MainClassFinder
;
...
...
@@ -137,8 +136,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
* @return {@code true} if the application process should be forked
*/
protected
boolean
isFork
()
{
return
(
Boolean
.
TRUE
.
equals
(
this
.
fork
)
||
(
this
.
fork
==
null
&&
(
hasAgent
()
||
hasJvmArgs
())));
return
(
Boolean
.
TRUE
.
equals
(
this
.
fork
)
||
(
this
.
fork
==
null
&&
(
hasAgent
()
||
hasJvmArgs
())));
}
private
boolean
hasAgent
()
{
...
...
@@ -165,7 +163,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
}
CodeSource
source
=
loaded
.
getProtectionDomain
().
getCodeSource
();
if
(
source
!=
null
)
{
this
.
agent
=
new
File
[]
{
new
File
(
source
.
getLocation
().
getFile
())
};
this
.
agent
=
new
File
[]
{
new
File
(
source
.
getLocation
().
getFile
())
};
}
}
}
...
...
@@ -178,7 +176,8 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
}
}
private
void
run
(
String
startClassName
)
throws
MojoExecutionException
,
MojoFailureException
{
private
void
run
(
String
startClassName
)
throws
MojoExecutionException
,
MojoFailureException
{
findAgent
();
if
(
isFork
())
{
doRunWithForkedJvm
(
startClassName
);
...
...
@@ -196,8 +195,8 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
}
}
private
void
doRunWithForkedJvm
(
String
startClassName
)
throws
MojoExecutionException
,
MojoFailureException
{
private
void
doRunWithForkedJvm
(
String
startClassName
)
throws
MojoExecutionException
,
MojoFailureException
{
List
<
String
>
args
=
new
ArrayList
<
String
>();
addAgents
(
args
);
addJvmArgs
(
args
);
...
...
@@ -213,8 +212,8 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
* @throws MojoExecutionException
* @throws MojoFailureException
*/
protected
abstract
void
runWithForkedJvm
(
List
<
String
>
args
)
throws
MojoExecutionException
,
MojoFailureException
;
protected
abstract
void
runWithForkedJvm
(
List
<
String
>
args
)
throws
MojoExecutionException
,
MojoFailureException
;
/**
* Run with the current VM, using the specified arguments.
...
...
@@ -277,8 +276,8 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
args
.
add
(
"-cp"
);
args
.
add
(
classpath
.
toString
());
}
catch
(
Exception
e
)
{
throw
new
MojoExecutionException
(
"Could not build classpath"
,
e
);
catch
(
Exception
e
x
)
{
throw
new
MojoExecutionException
(
"Could not build classpath"
,
e
x
);
}
}
...
...
@@ -358,8 +357,8 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
getLog
().
debug
(
sb
.
toString
().
trim
());
}
private
static
class
TestArtifactFilter
extends
AbstractArtifactFeatureFilter
{
public
TestArtifactFilter
()
{
super
(
""
,
Artifact
.
SCOPE_TEST
);
}
...
...
@@ -368,6 +367,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
protected
String
getArtifactFeature
(
Artifact
artifact
)
{
return
artifact
.
getScope
();
}
}
/**
...
...
@@ -423,7 +423,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
if
(!
mainMethod
.
isAccessible
())
{
mainMethod
.
setAccessible
(
true
);
}
mainMethod
.
invoke
(
null
,
new
Object
[]
{
this
.
args
});
mainMethod
.
invoke
(
null
,
new
Object
[]
{
this
.
args
});
}
catch
(
NoSuchMethodException
ex
)
{
Exception
wrappedEx
=
new
Exception
(
...
...
spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RunArguments.java
View file @
bce4bb88
...
...
@@ -42,7 +42,7 @@ class RunArguments {
}
public
LinkedList
<
String
>
getArgs
()
{
return
args
;
return
this
.
args
;
}
public
String
[]
asArray
()
{
...
...
spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RunMojo.java
View file @
bce4bb88
...
...
@@ -24,7 +24,6 @@ import org.apache.maven.plugins.annotations.Execute;
import
org.apache.maven.plugins.annotations.LifecyclePhase
;
import
org.apache.maven.plugins.annotations.Mojo
;
import
org.apache.maven.plugins.annotations.ResolutionScope
;
import
org.springframework.boot.loader.tools.JavaExecutable
;
import
org.springframework.boot.loader.tools.RunProcess
;
...
...
@@ -41,15 +40,17 @@ public class RunMojo extends AbstractRunMojo {
@Override
protected
void
runWithForkedJvm
(
List
<
String
>
args
)
throws
MojoExecutionException
{
try
{
new
RunProcess
(
new
JavaExecutable
().
toString
()).
run
(
true
,
args
.
toArray
(
new
String
[
args
.
size
()]));
new
RunProcess
(
new
JavaExecutable
().
toString
()).
run
(
true
,
args
.
toArray
(
new
String
[
args
.
size
()]));
}
catch
(
Exception
ex
)
{
throw
new
MojoExecutionException
(
"Could not exec java"
,
ex
);
}
}
protected
void
runWithMavenJvm
(
String
startClassName
,
String
...
arguments
)
throws
MojoExecutionException
{
@Override
protected
void
runWithMavenJvm
(
String
startClassName
,
String
...
arguments
)
throws
MojoExecutionException
{
IsolatedThreadGroup
threadGroup
=
new
IsolatedThreadGroup
(
startClassName
);
Thread
launchThread
=
new
Thread
(
threadGroup
,
new
LaunchRunner
(
startClassName
,
arguments
),
startClassName
+
".main()"
);
...
...
spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/SpringApplicationLifecycleClient.java
View file @
bce4bb88
...
...
@@ -17,6 +17,7 @@
package
org
.
springframework
.
boot
.
maven
;
import
java.io.IOException
;
import
javax.management.AttributeNotFoundException
;
import
javax.management.InstanceNotFoundException
;
import
javax.management.MBeanException
;
...
...
@@ -35,20 +36,19 @@ import org.apache.maven.plugin.MojoExecutionException;
* information about the lifecycle of a given Spring application.
*
* @author Stephane Nicoll
* @since 1.3.0
*/
class
SpringApplicationLifecycleClient
{
//Note: see org.springframework.boot.autoconfigure.test.SpringApplicationLifecycleAutoConfiguration
static
final
String
DEFAULT_OBJECT_NAME
=
"org.springframework.boot:type=Lifecycle,name=springApplicationLifecycle"
;
// Note: see SpringApplicationLifecycleAutoConfiguration
static
final
String
DEFAULT_OBJECT_NAME
=
"org.springframework.boot:type=Lifecycle,name=springApplicationLifecycle"
;
private
final
MBeanServerConnection
mBeanServerC
onnection
;
private
final
MBeanServerConnection
c
onnection
;
private
final
ObjectName
objectName
;
public
SpringApplicationLifecycleClient
(
MBeanServerConnection
mBeanServerConnection
,
String
jmxName
)
{
this
.
mBeanServerConnection
=
mBeanServerConnection
;
public
SpringApplicationLifecycleClient
(
MBeanServerConnection
connection
,
String
jmxName
)
{
this
.
connection
=
connection
;
this
.
objectName
=
toObjectName
(
jmxName
);
}
...
...
@@ -66,30 +66,32 @@ class SpringApplicationLifecycleClient {
}
/**
* Check if the spring application managed by this instance is ready.
*
<p>Returns {@code false} if the mbean is not yet deployed so this method
*
should be repeatedly
called until a timeout is reached.
* Check if the spring application managed by this instance is ready.
Returns
*
{@code false} if the mbean is not yet deployed so this method should be repeatedly
* called until a timeout is reached.
* @return {@code true} if the application is ready to service requests
* @throws MojoExecutionException if the JMX service could not be contacted
*/
public
boolean
isReady
()
throws
MojoExecutionException
{
try
{
return
(
Boolean
)
this
.
mBeanServerC
onnection
.
getAttribute
(
this
.
objectName
,
"Ready"
);
return
(
Boolean
)
this
.
c
onnection
.
getAttribute
(
this
.
objectName
,
"Ready"
);
}
catch
(
InstanceNotFoundException
e
)
{
catch
(
InstanceNotFoundException
e
x
)
{
return
false
;
// Instance not available yet
}
catch
(
AttributeNotFoundException
e
)
{
throw
new
IllegalStateException
(
"Unexpected: attribute 'Ready' not available"
,
e
);
catch
(
AttributeNotFoundException
ex
)
{
throw
new
IllegalStateException
(
"Unexpected: attribute 'Ready' not available"
,
ex
);
}
catch
(
ReflectionException
e
)
{
throw
new
MojoExecutionException
(
"Failed to retrieve Ready attribute"
,
e
.
getCause
());
catch
(
ReflectionException
ex
)
{
throw
new
MojoExecutionException
(
"Failed to retrieve Ready attribute"
,
ex
.
getCause
());
}
catch
(
MBeanException
e
)
{
throw
new
MojoExecutionException
(
e
.
getMessage
(),
e
);
catch
(
MBeanException
e
x
)
{
throw
new
MojoExecutionException
(
e
x
.
getMessage
(),
ex
);
}
catch
(
IOException
e
)
{
throw
new
MojoExecutionException
(
e
.
getMessage
(),
e
);
catch
(
IOException
e
x
)
{
throw
new
MojoExecutionException
(
e
x
.
getMessage
(),
ex
);
}
}
...
...
@@ -99,15 +101,16 @@ class SpringApplicationLifecycleClient {
* @throws IOException if an I/O error occurs
* @throws InstanceNotFoundException if the lifecycle mbean cannot be found
*/
public
void
stop
()
throws
MojoExecutionException
,
IOException
,
InstanceNotFoundException
{
public
void
stop
()
throws
MojoExecutionException
,
IOException
,
InstanceNotFoundException
{
try
{
this
.
mBeanServerC
onnection
.
invoke
(
this
.
objectName
,
"shutdown"
,
null
,
null
);
this
.
c
onnection
.
invoke
(
this
.
objectName
,
"shutdown"
,
null
,
null
);
}
catch
(
ReflectionException
e
)
{
throw
new
MojoExecutionException
(
"Shutdown failed"
,
e
.
getCause
());
catch
(
ReflectionException
e
x
)
{
throw
new
MojoExecutionException
(
"Shutdown failed"
,
e
x
.
getCause
());
}
catch
(
MBeanException
e
)
{
throw
new
MojoExecutionException
(
"Could not invoke shutdown operation"
,
e
);
catch
(
MBeanException
e
x
)
{
throw
new
MojoExecutionException
(
"Could not invoke shutdown operation"
,
e
x
);
}
}
...
...
spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StartMojo.java
View file @
bce4bb88
This diff is collapsed.
Click to expand it.
spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StopMojo.java
View file @
bce4bb88
...
...
@@ -18,6 +18,7 @@ package org.springframework.boot.maven;
import
java.io.IOException
;
import
java.lang.management.ManagementFactory
;
import
javax.management.InstanceNotFoundException
;
import
javax.management.MBeanServerConnection
;
import
javax.management.remote.JMXConnector
;
...
...
@@ -40,23 +41,23 @@ import org.apache.maven.plugins.annotations.Parameter;
public
class
StopMojo
extends
AbstractMojo
{
/**
* Flag to indicate if the run processes should be forked. Must be aligned to the
value
* used to {@link StartMojo start} the process
* Flag to indicate if the run processes should be forked. Must be aligned to the
*
value
used to {@link StartMojo start} the process
* @since 1.2
*/
@Parameter
(
property
=
"fork"
)
private
Boolean
fork
;
/**
* The JMX name of the automatically deployed MBean managing the lifecycle
*
of the
application.
* The JMX name of the automatically deployed MBean managing the lifecycle
of the
* application.
*/
@Parameter
private
String
jmxName
=
SpringApplicationLifecycleClient
.
DEFAULT_OBJECT_NAME
;
/**
* The port to use to lookup the platform MBeanServer if the application
*
has been
forked.
* The port to use to lookup the platform MBeanServer if the application
has been
* forked.
*/
@Parameter
private
int
jmxPort
=
9001
;
...
...
@@ -72,36 +73,38 @@ public class StopMojo extends AbstractMojo {
stop
();
}
}
catch
(
IOException
e
)
{
catch
(
IOException
e
x
)
{
// The response won't be received as the server has died - ignoring
getLog
().
debug
(
"Service is not reachable anymore ("
+
e
.
getMessage
()
+
")"
);
}
getLog
().
debug
(
"Service is not reachable anymore ("
+
ex
.
getMessage
()
+
")"
);
}
private
void
stop
()
throws
IOException
,
MojoFailureException
,
MojoExecutionException
{
doStop
(
ManagementFactory
.
getPlatformMBeanServer
());
}
private
void
stopForkedProcess
()
throws
IOException
,
MojoFailureException
,
MojoExecutionException
{
JMXConnector
jmxConnector
=
SpringApplicationLifecycleClient
.
createLocalJmxConnector
(
this
.
jmxPort
);
private
void
stopForkedProcess
()
throws
IOException
,
MojoFailureException
,
MojoExecutionException
{
JMXConnector
connector
=
SpringApplicationLifecycleClient
.
createLocalJmxConnector
(
this
.
jmxPort
);
try
{
MBeanServerConnection
mBeanServerConnection
=
jmxC
onnector
.
getMBeanServerConnection
();
doStop
(
mBeanServerC
onnection
);
MBeanServerConnection
connection
=
c
onnector
.
getMBeanServerConnection
();
doStop
(
c
onnection
);
}
finally
{
jmxC
onnector
.
close
();
c
onnector
.
close
();
}
}
private
void
doStop
(
MBeanServerConnection
connection
)
throws
IOException
,
MojoExecutionException
{
SpringApplicationLifecycleClient
helper
=
new
SpringApplicationLifecycleClient
(
connection
,
this
.
jmxName
);
private
void
stop
()
throws
IOException
,
MojoFailureException
,
MojoExecutionException
{
doStop
(
ManagementFactory
.
getPlatformMBeanServer
());
}
private
void
doStop
(
MBeanServerConnection
connection
)
throws
IOException
,
MojoExecutionException
{
try
{
helper
.
stop
();
new
SpringApplicationLifecycleClient
(
connection
,
this
.
jmxName
)
.
stop
();
}
catch
(
InstanceNotFoundException
e
)
{
throw
new
MojoExecutionException
(
"Spring application lifecycle JMX bean not found (fork is "
+
""
+
this
.
fork
+
"). Could not stop application gracefully"
,
e
);
catch
(
InstanceNotFoundException
ex
)
{
throw
new
MojoExecutionException
(
"Spring application lifecycle JMX bean not found (fork is "
+
""
+
this
.
fork
+
"). Could not stop application gracefully"
,
ex
);
}
}
...
...
spring-boot/src/main/java/org/springframework/boot/context/SpringApplicationLifecycleRegistrar.java
View file @
bce4bb88
...
...
@@ -17,13 +17,13 @@
package
org
.
springframework
.
boot
.
context
;
import
java.lang.management.ManagementFactory
;
import
javax.management.MBeanServer
;
import
javax.management.MalformedObjectNameException
;
import
javax.management.ObjectName
;
import
org.apache.commons.logging.Log
;
import
org.apache.commons.logging.LogFactory
;
import
org.springframework.beans.BeansException
;
import
org.springframework.beans.factory.DisposableBean
;
import
org.springframework.beans.factory.InitializingBean
;
...
...
@@ -52,50 +52,51 @@ public class SpringApplicationLifecycleRegistrar implements ApplicationContextAw
private
boolean
ready
=
false
;
public
SpringApplicationLifecycleRegistrar
(
String
name
)
throws
MalformedObjectNameException
{
public
SpringApplicationLifecycleRegistrar
(
String
name
)
throws
MalformedObjectNameException
{
this
.
objectName
=
new
ObjectName
(
name
);
}
@Override
public
void
setApplicationContext
(
ApplicationContext
applicationContext
)
throws
BeansException
{
Assert
.
isTrue
(
applicationContext
instanceof
ConfigurableApplicationContext
,
public
void
setApplicationContext
(
ApplicationContext
applicationContext
)
throws
BeansException
{
Assert
.
state
(
applicationContext
instanceof
ConfigurableApplicationContext
,
"ApplicationContext does not implement ConfigurableApplicationContext"
);
this
.
applicationContext
=
(
ConfigurableApplicationContext
)
applicationContext
;
}
@Override
public
void
onApplicationEvent
(
ApplicationReadyEvent
event
)
{
ready
=
true
;
this
.
ready
=
true
;
}
@Override
public
void
afterPropertiesSet
()
throws
Exception
{
MBeanServer
server
=
ManagementFactory
.
getPlatformMBeanServer
();
server
.
registerMBean
(
new
SpringApplicationLifecycle
(),
objectName
);
server
.
registerMBean
(
new
SpringApplicationLifecycle
(),
this
.
objectName
);
if
(
logger
.
isDebugEnabled
())
{
logger
.
debug
(
"Application lifecycle MBean registered with name '"
+
objectName
+
"'"
);
logger
.
debug
(
"Application lifecycle MBean registered with name '"
+
this
.
objectName
+
"'"
);
}
}
@Override
public
void
destroy
()
throws
Exception
{
ManagementFactory
.
getPlatformMBeanServer
().
unregisterMBean
(
objectName
);
ManagementFactory
.
getPlatformMBeanServer
().
unregisterMBean
(
this
.
objectName
);
}
private
class
SpringApplicationLifecycle
implements
SpringApplicationLifecycleMXBean
{
@Override
public
boolean
isReady
()
{
return
ready
;
return
SpringApplicationLifecycleRegistrar
.
this
.
ready
;
}
@Override
public
void
shutdown
()
{
logger
.
info
(
"Application shutdown requested."
);
applicationContext
.
close
();
SpringApplicationLifecycleRegistrar
.
this
.
applicationContext
.
close
();
}
}
}
spring-boot/src/test/java/org/springframework/boot/context/SpringApplicationLifecycleRegistrarTests.java
View file @
bce4bb88
...
...
@@ -17,6 +17,7 @@
package
org
.
springframework
.
boot
.
context
;
import
java.lang.management.ManagementFactory
;
import
javax.management.InstanceNotFoundException
;
import
javax.management.MBeanServer
;
import
javax.management.MalformedObjectNameException
;
...
...
@@ -27,7 +28,6 @@ import org.junit.Before;
import
org.junit.Rule
;
import
org.junit.Test
;
import
org.junit.rules.ExpectedException
;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.context.ApplicationListener
;
import
org.springframework.context.ConfigurableApplicationContext
;
...
...
@@ -75,15 +75,18 @@ public class SpringApplicationLifecycleRegistrarTests {
@Override
public
void
onApplicationEvent
(
ContextRefreshedEvent
event
)
{
try
{
assertFalse
(
"Application should not be ready yet"
,
isCurrentApplicationReady
(
objectName
));
assertFalse
(
"Application should not be ready yet"
,
isCurrentApplicationReady
(
objectName
));
}
catch
(
Exception
e
)
{
throw
new
IllegalStateException
(
"Could not contact spring application lifecycle bean"
,
e
);
catch
(
Exception
ex
)
{
throw
new
IllegalStateException
(
"Could not contact spring application lifecycle bean"
,
ex
);
}
}
});
this
.
context
=
application
.
run
();
assertTrue
(
"application should be ready now"
,
isCurrentApplicationReady
(
objectName
));
assertTrue
(
"application should be ready now"
,
isCurrentApplicationReady
(
objectName
));
}
@Test
...
...
@@ -95,8 +98,7 @@ public class SpringApplicationLifecycleRegistrarTests {
assertTrue
(
"application should be running"
,
this
.
context
.
isRunning
());
invokeShutdown
(
objectName
);
assertFalse
(
"application should not be running"
,
this
.
context
.
isRunning
());
thrown
.
expect
(
InstanceNotFoundException
.
class
);
// JMX cleanup
this
.
thrown
.
expect
(
InstanceNotFoundException
.
class
);
// JMX cleanup
this
.
mBeanServer
.
getObjectInstance
(
objectName
);
}
...
...
@@ -127,16 +129,15 @@ public class SpringApplicationLifecycleRegistrarTests {
}
}
@Configuration
static
class
Config
{
@Bean
public
SpringApplicationLifecycleRegistrar
springApplicationLifecycle
()
throws
MalformedObjectNameException
{
return
new
SpringApplicationLifecycleRegistrar
(
OBJECT_NAME
);
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment