Skip to content
Permalink
Browse files

Made JmxServer and JmxWebServer be Closeable.

  • Loading branch information
j256 committed Mar 20, 2017
1 parent b24a97a commit 5ee3daa1ff6bc02f3008dc09b70c52d836c53be9
Showing with 208 additions and 77 deletions.
  1. +4 −4 src/main/java/com/j256/simplejmx/client/CommandLineJmxClient.java
  2. +10 −6 src/main/java/com/j256/simplejmx/client/JmxClient.java
  3. +25 −0 src/main/java/com/j256/simplejmx/common/IoUtils.java
  4. +11 −1 src/main/java/com/j256/simplejmx/server/JmxServer.java
  5. +47 −0 src/main/java/com/j256/simplejmx/server/JmxUsernamePasswordAuthenticator.java
  6. +14 −1 src/main/java/com/j256/simplejmx/web/JmxWebServer.java
  7. +1 −0 src/main/javadoc/doc-files/changelog.txt
  8. +9 −11 src/test/java/com/j256/simplejmx/client/JmxClientTest.java
  9. +2 −1 src/test/java/com/j256/simplejmx/client/MainTest.java
  10. +4 −5 src/test/java/com/j256/simplejmx/common/BaseJmxSelfNamingTest.java
  11. +2 −3 src/test/java/com/j256/simplejmx/common/JmxSelfNamingTest.java
  12. +2 −2 src/test/java/com/j256/simplejmx/example/BasicExample.java
  13. +1 −1 src/test/java/com/j256/simplejmx/example/PublishAllExample.java
  14. +1 −1 src/test/java/com/j256/simplejmx/example/RandomObjectExample.java
  15. +2 −2 src/test/java/com/j256/simplejmx/example/WebServerExample.java
  16. +3 −2 src/test/java/com/j256/simplejmx/server/DoubleServerTest.java
  17. +23 −28 src/test/java/com/j256/simplejmx/server/JmxServerTest.java
  18. +37 −0 src/test/java/com/j256/simplejmx/server/JmxUsernamePasswordAuthenticatorTest.java
  19. +2 −1 src/test/java/com/j256/simplejmx/server/PlatformMbeanServerTest.java
  20. +3 −3 src/test/java/com/j256/simplejmx/server/PublishAllBeanWrapperTest.java
  21. +5 −5 src/test/java/com/j256/simplejmx/server/ReflectionMbeanTest.java
@@ -21,6 +21,8 @@
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;

import com.j256.simplejmx.common.IoUtils;

/**
* Command-line client that can be used to support interactive or batch-file JMX operations. It can be used with the
* {@link Main} class as a jmx client out of the SimpleJMX jar directly.
@@ -140,10 +142,8 @@ public String getNextLine(String prompt) throws IOException {
* Close the associated Jmx client.
*/
public void close() {
if (jmxClient != null) {
jmxClient.close();
jmxClient = null;
}
IoUtils.closeQuietly(jmxClient);
jmxClient = null;
}

/**
@@ -22,6 +22,7 @@
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

import com.j256.simplejmx.common.IoUtils;
import com.j256.simplejmx.common.ObjectNameUtil;

/**
@@ -106,6 +107,13 @@ public JmxClient(String hostName, int port) throws JMException {
this(generalJmxUrlForHostNamePort(hostName, port), null);
}

/**
* Connect the client to a host and port combination and a username and password.
*/
public JmxClient(String hostName, int port, String userName, String password) throws JMException {
this(generalJmxUrlForHostNamePort(hostName, port), addCredentialsToMap(userName, password, null));
}

/**
* Connect the client to a host and port combination.
*/
@@ -147,11 +155,7 @@ public JmxClient(String jmxUrl, Map<String, Object> environmentMap) throws JMExc
mbeanConn = jmxConnector.getMBeanServerConnection();
} catch (IOException e) {
if (jmxConnector != null) {
try {
jmxConnector.close();
} catch (IOException e1) {
// ignore, we did our best
}
IoUtils.closeQuietly(jmxConnector);
jmxConnector = null;
}
throw createJmException("Problems connecting to the server" + e, e);
@@ -459,7 +463,7 @@ public Object invokeOperation(ObjectName objectName, String operName, Object...
}
if (userName != null || password != null) {
String[] credentials = new String[] { userName, password };
environmentMap.put("jmx.remote.credentials", credentials);
environmentMap.put(JMXConnector.CREDENTIALS, credentials);
}
return environmentMap;
}
@@ -0,0 +1,25 @@
package com.j256.simplejmx.common;

import java.io.Closeable;
import java.io.IOException;

/**
* Some simple IO utils.
*
* @author graywatson
*/
public class IoUtils {

/**
* Close a closeable and hide any exceptions.
*/
public static void closeQuietly(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException ioe) {
// ignore exception
}
}
}
}
@@ -1,5 +1,6 @@
package com.j256.simplejmx.server;

import java.io.Closeable;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.net.InetAddress;
@@ -34,7 +35,7 @@
*
* @author graywatson
*/
public class JmxServer {
public class JmxServer implements Closeable {

private final String RMI_SERVER_HOST_NAME_PROPERTY = "java.rmi.server.hostname";

@@ -169,6 +170,15 @@ public synchronized void stop() {
}
}

@Override
public void close() throws IOException {
try {
stopThrow();
} catch (JMException jme) {
throw new IOException(jme);
}
}

/**
* Stop the JMX server by closing the connector and unpublishing it from the RMI registry. This throws a JMException
* on any issues.
@@ -0,0 +1,47 @@
package com.j256.simplejmx.server;

import java.security.Principal;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.management.remote.JMXAuthenticator;
import javax.management.remote.JMXPrincipal;
import javax.security.auth.Subject;

/**
* Username/password authenticator. Thanks much to wodencafe for the basis of the code.
*
* @author wodencafe
*/
public class JmxUsernamePasswordAuthenticator implements JMXAuthenticator {

private Map<String, String> authMap = Collections.emptyMap();

@Override
public Subject authenticate(Object credentials) {
if (!(credentials instanceof String[])) {
throw new SecurityException("Was expected credentials String[2] object");
}
String[] usernamePassword = (String[]) credentials;
if (usernamePassword.length != 2) {
throw new SecurityException("Was expected credentials String[2] object");
}

String username = usernamePassword[0];
String password = usernamePassword[1];
String expectedPassword = authMap.get(username);
if (expectedPassword == null || !expectedPassword.equals(password)) {
throw new SecurityException("Unknown username/password combination");
}

Set<Principal> principals = new HashSet<Principal>();
principals.add(new JMXPrincipal(username));
return new Subject(true, principals, Collections.emptySet(), Collections.emptySet());
}

public void setAuthMap(Map<String, String> authMap) {
this.authMap = authMap;
}
}
@@ -1,5 +1,7 @@
package com.j256.simplejmx.web;

import java.io.Closeable;
import java.io.IOException;
import java.net.InetAddress;

import org.eclipse.jetty.server.Connector;
@@ -17,7 +19,7 @@
*
* @author graywatson
*/
public class JmxWebServer {
public class JmxWebServer implements Closeable {

private InetAddress serverAddress;
private int serverPort;
@@ -57,6 +59,17 @@ public void stop() throws Exception {
server = null;
}

@Override
public void close() throws IOException {
try {
stop();
} catch (IOException ioe) {
throw ioe;
} catch (Exception e) {
throw new IOException(e);
}
}

/**
* Optional address that the Jetty web server will be running on.
*/
@@ -1,5 +1,6 @@
1.15: 3/20/2017
* Added environment map arguments to constructor. Thanks to nicoulaj.
* Made JmxServer and JmxWebServer be Closeable.

1.14: 3/16/2017
* Ton of improvements to tests to get them to work with circle-ci and (I suspect) other systems.
@@ -6,9 +6,9 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.Collections;
import java.net.InetAddress;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
@@ -19,11 +19,11 @@
import javax.management.MBeanParameterInfo;
import javax.management.ObjectName;

import com.sun.jmx.remote.util.EnvHelp;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import com.j256.simplejmx.common.IoUtils;
import com.j256.simplejmx.common.JmxAttributeMethod;
import com.j256.simplejmx.common.JmxOperation;
import com.j256.simplejmx.common.JmxResource;
@@ -65,14 +65,10 @@ public static void beforeClass() throws Exception {

@AfterClass
public static void afterClass() {
if (client != null) {
client.close();
client = null;
}
if (server != null) {
server.stop();
server = null;
}
IoUtils.closeQuietly(client);
client = null;
IoUtils.closeQuietly(server);
server = null;
}

@Test(expected = IllegalArgumentException.class)
@@ -98,7 +94,9 @@ public void testHostPort() throws Exception {

@Test
public void testHostPortEnvironment() throws Exception {
JmxClient client = new JmxClient("localhost", JMX_PORT, Collections.<String,Object> singletonMap(EnvHelp.CLIENT_CONNECTION_CHECK_PERIOD, 5000L));
@SuppressWarnings("resource")
JmxClient client = new JmxClient("localhost", JMX_PORT,
Collections.<String, Object> singletonMap("jmx.remote.x.client.connection.check.period", 5000L));
try {
client.getAttribute(objectName, "x");
} finally {
@@ -11,6 +11,7 @@
import org.junit.BeforeClass;
import org.junit.Test;

import com.j256.simplejmx.common.IoUtils;
import com.j256.simplejmx.server.JmxServer;

public class MainTest {
@@ -102,7 +103,7 @@ public void testConnectToServer() throws Exception {
new Main().doMain(new String[] { JmxClient.generalJmxUrlForHostNamePort(address.getHostAddress(), port) },
true);
} finally {
server.stop();
IoUtils.closeQuietly(server);
}
}
}
@@ -7,7 +7,6 @@

import javax.management.JMException;

import org.apache.commons.io.IOUtils;
import org.junit.Test;

import com.j256.simplejmx.client.JmxClient;
@@ -46,8 +45,8 @@ public void testOverrideOne() throws Exception {
.getAttribute(ObjectNameUtil.makeObjectName(DOMAIN_NAME, JMX_SELF_NAMING_BEAN_NAME), "foo");
assertEquals(jmxObject.foo, value);
} finally {
IOUtils.closeQuietly(client);
server.stop();
IoUtils.closeQuietly(client);
IoUtils.closeQuietly(server);
}
}

@@ -67,8 +66,8 @@ public void testOverrideNone() throws Exception {
"foo");
assertEquals(jmxObject.foo, value);
} finally {
IOUtils.closeQuietly(client);
server.stop();
IoUtils.closeQuietly(client);
IoUtils.closeQuietly(server);
}
}

@@ -7,7 +7,6 @@

import javax.management.JMException;

import org.apache.commons.io.IOUtils;
import org.junit.Test;

import com.j256.simplejmx.client.JmxClient;
@@ -46,8 +45,8 @@ public void testGetAll() throws Exception {
JMX_SELF_NAMING_BEAN_NAME, new String[] { "zing" }), "foo");
assertEquals(jmxObject.foo, value);
} finally {
IOUtils.closeQuietly(client);
server.stop();
IoUtils.closeQuietly(client);
IoUtils.closeQuietly(server);
}
}

@@ -56,8 +56,8 @@ private void doMain(String[] args) throws Exception {
} finally {
// unregister is not necessary if we are stopping the server
jmxServer.unregister(counter);
// stop our server
jmxServer.stop();
// close our server
jmxServer.close();
}
}

@@ -48,7 +48,7 @@ private void doMain(String[] args) throws Exception {
// unregister is not necessary if we are stopping the server
jmxServer.unregister(counter);
// stop our server
jmxServer.stop();
jmxServer.close();
}
}

@@ -75,7 +75,7 @@ private void doMain(String[] args) throws Exception {
// unregister is not necessary if we are stopping the server
jmxServer.unregister(lookupCache);
// stop our server
jmxServer.stop();
jmxServer.close();
}
}

@@ -49,8 +49,8 @@ private void doMain(String[] args) throws Exception {

} finally {
// stop our server
jmxWebServer.stop();
jmxServer.stop();
jmxWebServer.close();
jmxServer.close();
}
}

@@ -8,6 +8,7 @@
import org.junit.Test;

import com.j256.simplejmx.client.JmxClient;
import com.j256.simplejmx.common.IoUtils;
import com.j256.simplejmx.common.JmxAttributeMethod;
import com.j256.simplejmx.common.JmxOperation;
import com.j256.simplejmx.common.JmxResource;
@@ -53,11 +54,11 @@ public void testJmxServer() throws Exception {
} finally {
if (server1 != null) {
server1.unregister(testObject);
server1.stop();
IoUtils.closeQuietly(server1);
}
if (server2 != null) {
server2.unregister(testObject);
server2.stop();
IoUtils.closeQuietly(server2);
}
}
}

0 comments on commit 5ee3daa

Please sign in to comment.
You can’t perform that action at this time.