<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<title>Apache TomEE</title>
	<meta name="description"
		  content="Apache TomEE is a lightweight, yet powerful, JavaEE Application server with feature rich tooling." />
	<meta name="keywords" content="tomee,asf,apache,javaee,jee,shade,embedded,test,junit,applicationcomposer,maven,arquillian" />
	<meta name="author" content="Luka Cvetinovic for Codrops" />
	<link rel="icon" href="../../favicon.ico">
	<link rel="icon"  type="image/png" href="../../favicon.png">
	<meta name="msapplication-TileColor" content="#80287a">
	<meta name="theme-color" content="#80287a">
	<link rel="stylesheet" type="text/css" href="../../css/normalize.css">
	<link rel="stylesheet" type="text/css" href="../../css/bootstrap.css">
	<link rel="stylesheet" type="text/css" href="../../css/owl.css">
	<link rel="stylesheet" type="text/css" href="../../css/animate.css">
	<link rel="stylesheet" type="text/css" href="../../fonts/font-awesome-4.1.0/css/font-awesome.min.css">
	<link rel="stylesheet" type="text/css" href="../../fonts/eleganticons/et-icons.css">
	<link rel="stylesheet" type="text/css" href="../../css/jqtree.css">
	<link rel="stylesheet" type="text/css" href="../../css/idea.css">
	<link rel="stylesheet" type="text/css" href="../../css/cardio.css">

	<script type="text/javascript">
		<!-- Matomo -->
		var _paq = window._paq = window._paq || [];
		/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
		/* We explicitly disable cookie tracking to avoid privacy issues */
		_paq.push(['disableCookies']);
		_paq.push(['trackPageView']);
		_paq.push(['enableLinkTracking']);
		(function () {
			var u = "//matomo.privacy.apache.org/";
			_paq.push(['setTrackerUrl', u + 'matomo.php']);
			_paq.push(['setSiteId', '5']);
			var d = document, g = d.createElement('script'), s = d.getElementsByTagName('script')[0];
			g.async = true;
			g.src = u + 'matomo.js';
			s.parentNode.insertBefore(g, s);
		})();
		<!-- End Matomo Code -->
    </script>
</head>

<body>
    <div class="preloader">
		<img src="../../img/loader.gif" alt="Preloader image">
	</div>
	    <nav class="navbar">
		<div class="container">
		  <div class="row">          <div class="col-md-12">

			<!-- Brand and toggle get grouped for better mobile display -->
			<div class="navbar-header">
				<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
					<span class="sr-only">Toggle navigation</span>
					<span class="icon-bar"></span>
					<span class="icon-bar"></span>
					<span class="icon-bar"></span>
				</button>
				<a class="navbar-brand" href="/" title="Apache TomEE">
				    <span>

				    
                        <img 
							src="../../img/apache_tomee-logo.svg"
							onerror="this.src='../../img/apache_tomee-logo.jpg'"
							height="50"
							>
                    

                    </span>
                </a>
			</div>
			<!-- Collect the nav links, forms, and other content for toggling -->
			<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
				<ul class="nav navbar-nav navbar-right main-nav">
					<li><a href="../../docs.html">Documentation</a></li>
					<li><a href="../../community/index.html">Community</a></li>
					<li><a href="../../security/security.html">Security</a></li>
					<li><a class="btn btn-accent accent-orange no-shadow" href="../../download.html">Downloads</a></li>
				</ul>
			</div>
			<!-- /.navbar-collapse -->
		   </div></div>
		</div>
		<!-- /.container-fluid -->
	</nav>


    <div id="main-block" class="container main-block">
        <div class="row title">
          <div class="col-md-12">
            <div class='page-header'>
              
              <h1>dynamic-proxy-to-access-mbean</h1>
            </div>
          </div>
        </div>
        <div class="row">
            
            <div class="col-md-12">
                <p><em>Help us document this example! Click the blue pencil icon in the upper right to edit this page.</em></p>
<h2>Example</h2>
<p>Acessing MBean is something simple through the JMX API but it is often technical and not very interesting.</p>
<p>This example simplify this work simply doing it generically in a proxy.</p>
<p>So from an user side you simple declare an interface to access your MBeans.</p>
<p>Note: the example implementation uses a local MBeanServer but enhancing the example API it is easy to imagine a remote connection with user/password if needed.</p>
<h2>ObjectName API (annotation)</h2>
<p>Simply an annotation to get the object</p>
<pre><code>package org.superbiz.dynamic.mbean;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Target({TYPE, METHOD})
@Retention(RUNTIME)
public @interface ObjectName {
    String value();

    // for remote usage only
    String url() default &quot;&quot;;
    String user() default &quot;&quot;;
    String password() default &quot;&quot;;
}
</code></pre>
<h2>DynamicMBeanHandler (thr proxy implementation)</h2>
<pre><code>package org.superbiz.dynamic.mbean;

import javax.annotation.PreDestroy;
import javax.management.Attribute;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo;
import javax.management.MBeanServer;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Need a @PreDestroy method to disconnect the remote host when used in remote mode.
 */
public class DynamicMBeanHandler implements InvocationHandler {
    private final Map&lt;Method, ConnectionInfo&gt; infos = new ConcurrentHashMap&lt;Method, ConnectionInfo&gt;();

    @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        final String methodName = method.getName();
        if (method.getDeclaringClass().equals(Object.class) &amp;&amp; &quot;toString&quot;.equals(methodName)) {
            return getClass().getSimpleName() + &quot; Proxy&quot;;
        }
        if (method.getAnnotation(PreDestroy.class) != null) {
            return destroy();
        }

        final ConnectionInfo info = getConnectionInfo(method);
        final MBeanInfo infos = info.getMBeanInfo();
        if (methodName.startsWith(&quot;set&quot;) &amp;&amp; methodName.length() &gt; 3 &amp;&amp; args != null &amp;&amp; args.length == 1
            &amp;&amp; (Void.TYPE.equals(method.getReturnType()) || Void.class.equals(method.getReturnType()))) {
            final String attributeName = attributeName(infos, methodName, method.getParameterTypes()[0]);
            info.setAttribute(new Attribute(attributeName, args[0]));
            return null;
        } else if (methodName.startsWith(&quot;get&quot;) &amp;&amp; (args == null || args.length == 0) &amp;&amp; methodName.length() &gt; 3) {
            final String attributeName = attributeName(infos, methodName, method.getReturnType());
            return info.getAttribute(attributeName);
        }
        // operation
        return info.invoke(methodName, args, getSignature(method));
    }

    public Object destroy() {
        for (ConnectionInfo info : infos.values()) {
            info.clean();
        }
        infos.clear();
        return null;
    }

    private String[] getSignature(Method method) {
        String[] args = new String[method.getParameterTypes().length];
        for (int i = 0; i &lt; method.getParameterTypes().length; i++) {
            args[i] = method.getParameterTypes()[i].getName();
        }
        return args; // note: null should often work...
    }

    private String attributeName(MBeanInfo infos, String methodName, Class&lt;?&gt; type) {
        String found = null;
        String foundBackUp = null; // without checking the type
        final String attributeName = methodName.substring(3, methodName.length());
        final String lowerName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4, methodName.length());

        for (MBeanAttributeInfo attribute : infos.getAttributes()) {
            final String name = attribute.getName();
            if (attributeName.equals(name)) {
                foundBackUp = attributeName;
                if (attribute.getType().equals(type.getName())) {
                    found = name;
                }
            } else if (found == null &amp;&amp; ((lowerName.equals(name) &amp;&amp; !attributeName.equals(name))
                || lowerName.equalsIgnoreCase(name))) {
                foundBackUp = name;
                if (attribute.getType().equals(type.getName())) {
                    found = name;
                }
            }
        }

        if (found == null &amp;&amp; foundBackUp == null) {
            throw new UnsupportedOperationException(&quot;cannot find attribute &quot; + attributeName);
        }

        if (found != null) {
            return found;
        }
        return foundBackUp;
    }

    private synchronized ConnectionInfo getConnectionInfo(Method method) throws Exception {
        if (!infos.containsKey(method)) {
            synchronized (infos) {
                if (!infos.containsKey(method)) { // double check for synchro
                    org.superbiz.dynamic.mbean.ObjectName on = method.getAnnotation(org.superbiz.dynamic.mbean.ObjectName.class);
                    if (on == null) {
                        Class&lt;?&gt; current = method.getDeclaringClass();
                        do {
                            on = method.getDeclaringClass().getAnnotation(org.superbiz.dynamic.mbean.ObjectName.class);
                            current = current.getSuperclass();
                        } while (on == null &amp;&amp; current != null);
                        if (on == null) {
                            throw new UnsupportedOperationException(&quot;class or method should define the objectName to use for invocation: &quot; + method.toGenericString());
                        }
                    }
                    final ConnectionInfo info;
                    if (on.url().isEmpty()) {
                        info = new LocalConnectionInfo();
                        ((LocalConnectionInfo) info).server = ManagementFactory.getPlatformMBeanServer(); // could use an id...
                    } else {
                        info = new RemoteConnectionInfo();
                        final Map&lt;String, String[]&gt; environment = new HashMap&lt;String, String[]&gt;();
                        if (!on.user().isEmpty()) {
                            environment.put(JMXConnector.CREDENTIALS, new String[]{ on.user(), on.password() });
                        }
                        // ((RemoteConnectionInfo) info).connector = JMXConnectorFactory.newJMXConnector(new JMXServiceURL(on.url()), environment);
                        ((RemoteConnectionInfo) info).connector = JMXConnectorFactory.connect(new JMXServiceURL(on.url()), environment);

                    }
                    info.objectName = new ObjectName(on.value());

                    infos.put(method, info);
                }
            }
        }
        return infos.get(method);
    }

    private abstract static class ConnectionInfo {
        protected ObjectName objectName;

        public abstract void setAttribute(Attribute attribute) throws Exception;
        public abstract Object getAttribute(String attribute) throws Exception;
        public abstract Object invoke(String operationName, Object params[], String signature[]) throws Exception;
        public abstract MBeanInfo getMBeanInfo() throws Exception;
        public abstract void clean();
    }

    private static class LocalConnectionInfo extends ConnectionInfo {
        private MBeanServer server;

        @Override public void setAttribute(Attribute attribute) throws Exception {
            server.setAttribute(objectName, attribute);
        }

        @Override public Object getAttribute(String attribute) throws Exception {
            return server.getAttribute(objectName, attribute);
        }

        @Override
        public Object invoke(String operationName, Object[] params, String[] signature) throws Exception {
            return server.invoke(objectName, operationName, params, signature);
        }

        @Override public MBeanInfo getMBeanInfo() throws Exception {
            return server.getMBeanInfo(objectName);
        }

        @Override public void clean() {
            // no-op
        }
    }

    private static class RemoteConnectionInfo extends ConnectionInfo {
        private JMXConnector connector;
        private MBeanServerConnection connection;

        private void before() throws IOException {
            connection = connector.getMBeanServerConnection();
        }

        private void after() throws IOException {
            // no-op
        }

        @Override public void setAttribute(Attribute attribute) throws Exception {
            before();
            connection.setAttribute(objectName, attribute);
            after();
        }

        @Override public Object getAttribute(String attribute) throws Exception {
            before();
            try {
                return connection.getAttribute(objectName, attribute);
            } finally {
                after();
            }
        }

        @Override
        public Object invoke(String operationName, Object[] params, String[] signature) throws Exception {
            before();
            try {
                return connection.invoke(objectName, operationName, params, signature);
            } finally {
                after();
            }
        }

        @Override public MBeanInfo getMBeanInfo() throws Exception {
            before();
            try {
                return connection.getMBeanInfo(objectName);
            } finally {
                after();
            }
        }

        @Override public void clean() {
            try {
                connector.close();
            } catch (IOException e) {
                // no-op
            }
        }
    }
}
</code></pre>
<h2>Dynamic Proxies</h2>
<h3>DynamicMBeanClient (the dynamic JMX client)</h3>
<pre><code>package org.superbiz.dynamic.mbean;

import org.apache.openejb.api.Proxy;
import org.superbiz.dynamic.mbean.DynamicMBeanHandler;
import org.superbiz.dynamic.mbean.ObjectName;

import javax.ejb.Singleton;

/**
 * @author rmannibucau
 */
@Singleton
@Proxy(DynamicMBeanHandler.class)
@ObjectName(DynamicMBeanClient.OBJECT_NAME)
public interface DynamicMBeanClient {
    static final String OBJECT_NAME = &quot;test:group=DynamicMBeanClientTest&quot;;

    int getCounter();
    void setCounter(int i);
    int length(String aString);
}
</code></pre>
<h3>DynamicMBeanClient (the dynamic JMX client)</h3>
<pre><code>package org.superbiz.dynamic.mbean;

import org.apache.openejb.api.Proxy;

import javax.annotation.PreDestroy;
import javax.ejb.Singleton;


@Singleton
@Proxy(DynamicMBeanHandler.class)
@ObjectName(value = DynamicRemoteMBeanClient.OBJECT_NAME, url = &quot;service:jmx:rmi:///jndi/rmi://localhost:8243/jmxrmi&quot;)
public interface DynamicRemoteMBeanClient {
    static final String OBJECT_NAME = &quot;test:group=DynamicMBeanClientTest&quot;;

    int getCounter();
    void setCounter(int i);
    int length(String aString);

    @PreDestroy void clean();
}
</code></pre>
<h2>The MBean used for the test</h2>
<h3>SimpleMBean</h3>
<pre><code>package org.superbiz.dynamic.mbean.simple;

public interface SimpleMBean {
    int length(String s);

    int getCounter();
    void setCounter(int c);
}
</code></pre>
<h2>Simple</h2>
<pre><code>package org.superbiz.dynamic.mbean.simple;

public class Simple implements SimpleMBean {
    private int counter = 0;

    @Override public int length(String s) {
        if (s == null) {
            return 0;
        }
        return s.length();
    }

    @Override public int getCounter() {
        return counter;
    }

    @Override public void setCounter(int c) {
        counter = c;
    }
}
</code></pre>
<h2>DynamicMBeanClientTest (The test)</h2>
<pre><code>package org.superbiz.dynamic.mbean;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.superbiz.dynamic.mbean.simple.Simple;

import javax.ejb.EJB;
import javax.ejb.embeddable.EJBContainer;
import javax.management.Attribute;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;

import static junit.framework.Assert.assertEquals;

public class DynamicMBeanClientTest {
    private static ObjectName objectName;
    private static EJBContainer container;

    @EJB private DynamicMBeanClient localClient;
    @EJB private DynamicRemoteMBeanClient remoteClient;

    @BeforeClass public static void start() {
        container = EJBContainer.createEJBContainer();
    }

    @Before public void injectAndRegisterMBean() throws Exception {
        container.getContext().bind(&quot;inject&quot;, this);
        objectName = new ObjectName(DynamicMBeanClient.OBJECT_NAME);
        ManagementFactory.getPlatformMBeanServer().registerMBean(new Simple(), objectName);
    }

    @After public void unregisterMBean() throws Exception {
        if (objectName != null) {
            ManagementFactory.getPlatformMBeanServer().unregisterMBean(objectName);
        }
    }

    @Test public void localGet() throws Exception {
        assertEquals(0, localClient.getCounter());
        ManagementFactory.getPlatformMBeanServer().setAttribute(objectName, new Attribute(&quot;Counter&quot;, 5));
        assertEquals(5, localClient.getCounter());
    }

    @Test public void localSet() throws Exception {
        assertEquals(0, ((Integer) ManagementFactory.getPlatformMBeanServer().getAttribute(objectName, &quot;Counter&quot;)).intValue());
        localClient.setCounter(8);
        assertEquals(8, ((Integer) ManagementFactory.getPlatformMBeanServer().getAttribute(objectName, &quot;Counter&quot;)).intValue());
    }

    @Test public void localOperation() {
        assertEquals(7, localClient.length(&quot;openejb&quot;));
    }

    @Test public void remoteGet() throws Exception {
        assertEquals(0, remoteClient.getCounter());
        ManagementFactory.getPlatformMBeanServer().setAttribute(objectName, new Attribute(&quot;Counter&quot;, 5));
        assertEquals(5, remoteClient.getCounter());
    }

    @Test public void remoteSet() throws Exception {
        assertEquals(0, ((Integer) ManagementFactory.getPlatformMBeanServer().getAttribute(objectName, &quot;Counter&quot;)).intValue());
        remoteClient.setCounter(8);
        assertEquals(8, ((Integer) ManagementFactory.getPlatformMBeanServer().getAttribute(objectName, &quot;Counter&quot;)).intValue());
    }

    @Test public void remoteOperation() {
        assertEquals(7, remoteClient.length(&quot;openejb&quot;));
    }

    @AfterClass public static void close() {
        if (container != null) {
            container.close();
        }
    }
}
</code></pre>
            </div>
            
        </div>
    </div>
<div style="margin-bottom: 30px;"></div>
<footer>
		<div class="container">
			<div class="row">
				<div class="col-sm-6 text-center-mobile">
					<h3 class="white">Be simple.  Be certified. Be Tomcat.</h3>
					<h5 class="light regular light-white">"A good application in a good server"</h5>
					<ul class="social-footer">
						<li><a href="https://www.facebook.com/ApacheTomEE/"><i class="fa fa-facebook"></i></a></li>
						<li><a href="https://twitter.com/apachetomee"><i class="fa fa-twitter"></i></a></li>
					</ul>
					<h5 class="light regular light-white">
						<a href="../../privacy-policy.html" class="white">Privacy Policy</a>
					</h5>
				</div>
				<div class="col-sm-6 text-center-mobile">
					<div class="row opening-hours">
						<div class="col-sm-3 text-center-mobile">
							<h5><a href="../../latest/docs/" class="white">Documentation</a></h5>
							<ul class="list-unstyled">
								<li><a href="../../latest/docs/admin/configuration/index.html" class="regular light-white">How to configure</a></li>
								<li><a href="../../latest/docs/admin/file-layout.html" class="regular light-white">Dir. Structure</a></li>
								<li><a href="../../latest/docs/developer/testing/index.html" class="regular light-white">Testing</a></li>
								<li><a href="../../latest/docs/admin/cluster/index.html" class="regular light-white">Clustering</a></li>
							</ul>
						</div>
						<div class="col-sm-3 text-center-mobile">
							<h5><a href="../../latest/examples/" class="white">Examples</a></h5>
							<ul class="list-unstyled">
								<li><a href="../../latest/examples/simple-cdi-interceptor.html" class="regular light-white">CDI Interceptor</a></li>
								<li><a href="../../latest/examples/rest-cdi.html" class="regular light-white">REST with CDI</a></li>
								<li><a href="../../latest/examples/ejb-examples.html" class="regular light-white">EJB</a></li>
								<li><a href="../../latest/examples/jsf-managedBean-and-ejb.html" class="regular light-white">JSF</a></li>
							</ul>
						</div>
						<div class="col-sm-3 text-center-mobile">
							<h5><a href="../../community/index.html" class="white">Community</a></h5>
							<ul class="list-unstyled">
								<li><a href="../../community/contributors.html" class="regular light-white">Contributors</a></li>
								<li><a href="../../community/social.html" class="regular light-white">Social</a></li>
								<li><a href="../../community/sources.html" class="regular light-white">Sources</a></li>
							</ul>
						</div>
						<div class="col-sm-3 text-center-mobile">
							<h5><a href="../../security/index.html" class="white">Security</a></h5>
							<ul class="list-unstyled">
								<li><a href="https://apache.org/security" target="_blank" class="regular light-white">Apache Security</a></li>
								<li><a href="https://apache.org/security/projects.html" target="_blank" class="regular light-white">Security Projects</a></li>
								<li><a href="https://cve.mitre.org" target="_blank" class="regular light-white">CVE</a></li>
							</ul>
						</div>
					</div>
				</div>
			</div>
			<div class="row bottom-footer text-center-mobile">
				<div class="col-sm-12 light-white">
					<p>Copyright &copy; 1999-2022 The Apache Software Foundation, Licensed under the Apache License, Version 2.0. Apache TomEE, TomEE, Apache, the Apache feather logo, and the Apache TomEE project logo are trademarks of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners.</p>
				</div>
			</div>
		</div>
	</footer>
	<!-- Holder for mobile navigation -->
	<div class="mobile-nav">
        <ul>
          <li><a hef="../../latest/docs/admin/index.html">Administrators</a>
          <li><a hef="../../latest/docs/developer/index.html">Developers</a>
          <li><a hef="../../latest/docs/advanced/index.html">Advanced</a>
          <li><a hef="../../community/index.html">Community</a>
        </ul>
		<a href="#" class="close-link"><i class="arrow_up"></i></a>
	</div>
	<!-- Scripts -->
	<script src="../../js/jquery-1.11.1.min.js"></script>
	<script src="../../js/owl.carousel.min.js"></script>
	<script src="../../js/bootstrap.min.js"></script>
	<script src="../../js/wow.min.js"></script>
	<script src="../../js/typewriter.js"></script>
	<script src="../../js/jquery.onepagenav.js"></script>
	<script src="../../js/tree.jquery.js"></script>
	<script src="../../js/highlight.pack.js"></script>
    <script src="../../js/main.js"></script>
		</body>

</html>

