8048710: Use ServiceLoader for the jvmstat protocols

Reviewed-by: alanb
This commit is contained in:
Staffan Larsen 2014-07-01 16:08:45 +02:00
parent e614cf24ef
commit 829524e7d6
8 changed files with 216 additions and 84 deletions

View File

@ -23,7 +23,7 @@
* questions.
*/
package sun.jvmstat.monitor.remote;
package sun.jvmstat.monitor;
import sun.jvmstat.monitor.*;

View File

@ -0,0 +1,3 @@
sun.jvmstat.perfdata.monitor.protocol.file.MonitoredHostFileService
sun.jvmstat.perfdata.monitor.protocol.local.MonitoredHostLocalService
sun.jvmstat.perfdata.monitor.protocol.rmi.MonitoredHostRmiService

View File

@ -25,9 +25,11 @@
package sun.jvmstat.monitor;
import java.util.*;
import java.net.*;
import java.lang.reflect.*;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.Set;
import sun.jvmstat.monitor.event.HostListener;
@ -51,31 +53,6 @@ public abstract class MonitoredHost {
private static Map<HostIdentifier, MonitoredHost> monitoredHosts =
new HashMap<HostIdentifier, MonitoredHost>();
/*
* The monitoring implementation override mechanism. The value of
* this property is used as the class name for the concrete MonitoredHost
* subclass that implements the monitoring APIs. Setting this property
* will cause the remaining override mechanisms to be ignored. When
* this mechanism is used, the HostIdentifier scheme name, which
* indicates the communications protocol, is not used to locate a
* the protocol specific package. However, the HostIdentifier is
* still passed to the corresponding single arg constructor.
* This property is not expected to be set in normal circumstances.
*/
private static final String IMPL_OVERRIDE_PROP_NAME =
"sun.jvmstat.monitor.MonitoredHost";
/*
* The monitoring package name override mechanism. The value
* the this property is used as base package name for the
* monitoring implementation package. This property is not
* expected to be set under normal circumstances.
*/
private static final String IMPL_PKG_PROP_NAME =
"sun.jvmstat.monitor.package";
private static final String IMPL_PACKAGE =
System.getProperty(IMPL_PKG_PROP_NAME, "sun.jvmstat.perfdata");
/*
* The default optimized local protocol override mechanism. The value
* of this property is used to construct the default package name
@ -100,15 +77,6 @@ public abstract class MonitoredHost {
private static final String REMOTE_PROTOCOL =
System.getProperty(REMOTE_PROTOCOL_PROP_NAME, "rmi");
/*
* The default class name of the MonitoredHost implementation subclass.
* There is no override mechanism for this variable, other than the
* IMPL_OVERRIDE_PROP_NAME override, which is larger in scope. A concrete
* instance of this class is expected to be found in:
* <IMPL_PACKAGE>.monitor.protocol.<protocol>.<MONITORED_HOST_CLASS>
*/
private static final String MONITORED_HOST_CLASS = "MonitoredHostProvider";
/**
* The HostIdentifier for this MonitoredHost instance.
*/
@ -165,6 +133,13 @@ public abstract class MonitoredHost {
return getMonitoredHost(hostId);
}
/*
* Load the MonitoredHostServices
*/
private static ServiceLoader<MonitoredHostService> monitoredHostServiceLoader =
ServiceLoader.load(MonitoredHostService.class, MonitoredHostService.class.getClassLoader());
/**
* Factory method to construct a MonitoredHost instance to manage the
* connection to the host indicated by <tt>hostId</tt>.
@ -177,11 +152,6 @@ public abstract class MonitoredHost {
*/
public static MonitoredHost getMonitoredHost(HostIdentifier hostId)
throws MonitorException {
/*
* determine the class name to load. If the system property is set,
* use the indicated class. otherwise, use the default class.
*/
String classname = System.getProperty(IMPL_OVERRIDE_PROP_NAME);
MonitoredHost mh = null;
synchronized(monitoredHosts) {
@ -197,50 +167,21 @@ public abstract class MonitoredHost {
hostId = resolveHostId(hostId);
if (classname == null) {
// construct the class name
classname = IMPL_PACKAGE + ".monitor.protocol."
+ hostId.getScheme() + "." + MONITORED_HOST_CLASS;
for (MonitoredHostService mhs : monitoredHostServiceLoader) {
if (mhs.getScheme().equals(hostId.getScheme())) {
mh = mhs.getMonitoredHost(hostId);
}
}
try {
// run the constructor taking a single String parameter.
Class<?> c = Class.forName(classname);
Constructor cons = c.getConstructor(
new Class[] { hostId.getClass() }
);
mh = (MonitoredHost)cons.newInstance(new Object[] { hostId } );
synchronized(monitoredHosts) {
monitoredHosts.put(mh.hostId, mh);
}
return mh;
} catch (ClassNotFoundException e) {
// from Class.forName();
throw new IllegalArgumentException("Could not find " + classname
+ ": " + e.getMessage(), e);
} catch (NoSuchMethodException e) {
// from Class.getConstructor();
throw new IllegalArgumentException(
"Expected constructor missing in " + classname + ": "
+ e.getMessage(), e);
} catch (IllegalAccessException e) {
// from Constructor.newInstance()
throw new IllegalArgumentException(
"Unexpected constructor access in " + classname + ": "
+ e.getMessage(), e);
} catch (InstantiationException e) {
throw new IllegalArgumentException(classname + "is abstract: "
+ e.getMessage(), e);
} catch (InvocationTargetException e) {
Throwable cause = e.getCause();
if (cause instanceof MonitorException) {
throw (MonitorException)cause;
}
throw new RuntimeException("Unexpected exception", e);
if (mh == null) {
throw new IllegalArgumentException("Could not find MonitoredHost for scheme: " + hostId.getScheme());
}
synchronized(monitoredHosts) {
monitoredHosts.put(mh.hostId, mh);
}
return mh;
}
/**

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.jvmstat.monitor;
public interface MonitoredHostService {
/**
* Construct a MonitoredHost instance to manage the
* connection to the host indicated by <tt>hostId</tt>.
*
* @param hostId the identifier for the target host.
* @return MonitoredHost - The MonitoredHost object needed to attach to
* the target host.
*
* @throws MonitorException Thrown if monitoring errors occur.
*/
public MonitoredHost getMonitoredHost(HostIdentifier hostId) throws MonitorException;
/**
* Get the scheme that this service supports.
*
* @return scheme name
*/
public String getScheme();
}

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.jvmstat.perfdata.monitor.protocol.file;
import sun.jvmstat.monitor.HostIdentifier;
import sun.jvmstat.monitor.MonitorException;
import sun.jvmstat.monitor.MonitoredHost;
import sun.jvmstat.monitor.MonitoredHostService;
public final class MonitoredHostFileService implements MonitoredHostService {
@Override
public MonitoredHost getMonitoredHost(HostIdentifier hostId)
throws MonitorException {
return new MonitoredHostProvider(hostId);
}
@Override
public String getScheme() {
return "file";
}
}

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.jvmstat.perfdata.monitor.protocol.local;
import sun.jvmstat.monitor.HostIdentifier;
import sun.jvmstat.monitor.MonitorException;
import sun.jvmstat.monitor.MonitoredHost;
import sun.jvmstat.monitor.MonitoredHostService;
public final class MonitoredHostLocalService implements MonitoredHostService {
@Override
public MonitoredHost getMonitoredHost(HostIdentifier hostId)
throws MonitorException {
return new MonitoredHostProvider(hostId);
}
@Override
public String getScheme() {
return "local";
}
}

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.jvmstat.perfdata.monitor.protocol.rmi;
import sun.jvmstat.monitor.HostIdentifier;
import sun.jvmstat.monitor.MonitorException;
import sun.jvmstat.monitor.MonitoredHost;
import sun.jvmstat.monitor.MonitoredHostService;
public final class MonitoredHostRmiService implements MonitoredHostService {
@Override
public MonitoredHost getMonitoredHost(HostIdentifier hostId) throws MonitorException {
return new MonitoredHostProvider(hostId);
}
@Override
public String getScheme() {
return "rmi";
}
}

View File

@ -41,6 +41,8 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Predicate;
import java.util.function.Consumer;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import sun.management.VMManagement;
@ -135,6 +137,7 @@ public final class ProcessTools {
long timeout,
TimeUnit unit)
throws IOException, InterruptedException, TimeoutException {
System.out.println("["+name+"]:" + processBuilder.command().stream().collect(Collectors.joining(" ")));
Process p = processBuilder.start();
StreamPumper stdout = new StreamPumper(p.getInputStream());
StreamPumper stderr = new StreamPumper(p.getErrorStream());