/* * Copyright (C) 2011 Laurent Caillette * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation, either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.novelang.outfit.shell; import java.io.IOException; import java.net.MalformedURLException; import java.util.concurrent.TimeUnit; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; import javax.naming.ServiceUnavailableException; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import org.novelang.logger.Logger; import org.novelang.logger.LoggerFactory; import org.novelang.outfit.shell.insider.Insider; /** * Default implementation with no authentication nor SSL. * * @author Laurent Caillette */ public class DefaultJmxKit implements BootstrappingJmxKit { private static final Logger LOGGER = LoggerFactory.getLogger( DefaultJmxKit.class ) ; private static final Object lock = new Object() ; private final ImmutableMap< String, ? > environment ; /** * Constructor. * * @param environment a possibly null object. */ public DefaultJmxKit( final ImmutableMap< String, ? > environment ) { this.environment = environment ; } public DefaultJmxKit() { this( null ) ; } @Override public JMXConnector createJmxConnector( final String host, final int port ) throws InterruptedException, IOException { synchronized( lock ) { final JMXServiceURL url ; try { url = new JMXServiceURL( "service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi" ); } catch( MalformedURLException e ) { throw new Error( e ) ; } LOGGER.info( "Connecting to ", url, " ..." ) ; int attemptCount = 0 ; while( true ) { try { final JMXConnector jmxConnector = JMXConnectorFactory.connect( url, environment ) ; LOGGER.debug( "Successfully connected to ", url ) ; return jmxConnector ; } catch( IOException e ) { final Throwable cause = e.getCause() ; if( cause instanceof ServiceUnavailableException || cause instanceof java.rmi.ConnectException ) { if( attemptCount ++ < 10 ) { LOGGER.debug( "Couldn't connect to ", url, ", waiting a bit before another attempt..." ) ; TimeUnit.MILLISECONDS.sleep( 200L ) ; } else { throw e ; } } } } } } @Override public ImmutableSet<String> getJvmProperties( final int jmxPortForJvmProperty, final Integer heartbeatMaximumPeriod ) { final ImmutableSet.Builder< String > argumentList = ImmutableSet.builder() ; argumentList.add( "-Dcom.sun.management.jmxremote.port=" + jmxPortForJvmProperty ) ; // No security here. argumentList.add( "-Dcom.sun.management.jmxremote.authenticate=false" ) ; argumentList.add( "-Dcom.sun.management.jmxremote.ssl=false" ) ; argumentList.add( "-javaagent:" + AgentFileInstaller.getInstance().getJarFile().getAbsolutePath() + ( heartbeatMaximumPeriod == null ? "" : "=" + Insider.MAXIMUM_HEARTBEATDELAY_PARAMETERNAME + heartbeatMaximumPeriod ) ) ; return argumentList.build() ; } }