Commit bce4bb88 authored by Phillip Webb's avatar Phillip Webb

Polish start stop support

parent 09a29a72
......@@ -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);
}
......
......@@ -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 ex) {
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 ex) {
throw new IllegalStateException("Invalid jmx name " + jmxName, ex);
}
}
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;
}
}
......@@ -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 ex) {
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;
}
......
......@@ -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");
}
}
}
......@@ -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");
}
}
}
......@@ -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 ex) {
throw new MojoExecutionException("Could not build classpath", ex);
}
}
......@@ -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(
......
......@@ -42,7 +42,7 @@ class RunArguments {
}
public LinkedList<String> getArgs() {
return args;
return this.args;
}
public String[] asArray() {
......
......@@ -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()");
......
......@@ -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 mBeanServerConnection;
private final MBeanServerConnection connection;
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.mBeanServerConnection.getAttribute(this.objectName, "Ready");
return (Boolean) this.connection.getAttribute(this.objectName, "Ready");
}
catch (InstanceNotFoundException e) {
catch (InstanceNotFoundException ex) {
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 ex) {
throw new MojoExecutionException(ex.getMessage(), ex);
}
catch (IOException e) {
throw new MojoExecutionException(e.getMessage(), e);
catch (IOException ex) {
throw new MojoExecutionException(ex.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.mBeanServerConnection.invoke(this.objectName, "shutdown", null, null);
this.connection.invoke(this.objectName, "shutdown", null, null);
}
catch (ReflectionException e) {
throw new MojoExecutionException("Shutdown failed", e.getCause());
catch (ReflectionException ex) {
throw new MojoExecutionException("Shutdown failed", ex.getCause());
}
catch (MBeanException e) {
throw new MojoExecutionException("Could not invoke shutdown operation", e);
catch (MBeanException ex) {
throw new MojoExecutionException("Could not invoke shutdown operation", ex);
}
}
......
......@@ -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 ex) {
// 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 = jmxConnector.getMBeanServerConnection();
doStop(mBeanServerConnection);
MBeanServerConnection connection = connector.getMBeanServerConnection();
doStop(connection);
}
finally {
jmxConnector.close();
connector.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);
}
}
......
......@@ -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();
}
}
}
......@@ -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);
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment