use of com.sun.tools.attach.VirtualMachineDescriptor in project opennms by OpenNMS.
the class Controller method getJmxUrl.
/**
* This method uses the Java Attach API to connect to a running OpenNMS JVM
* and fetch the dynamically assigned local JMX agent URL.
*
* @see https://docs.oracle.com/javase/8/docs/jdk/api/attach/spec/index.html
* @see https://docs.oracle.com/javase/8/docs/technotes/guides/management/agent.html
*
* @return a {@link java.lang.String} object.
*/
public String getJmxUrl() {
try {
// Check to see if the com.sun.tools.attach classes are loadable in
// this JVM
Class<?> clazz;
clazz = Class.forName("com.sun.tools.attach.VirtualMachine");
clazz = Class.forName("com.sun.tools.attach.VirtualMachineDescriptor");
clazz = Class.forName("com.sun.tools.attach.AttachNotSupportedException");
} catch (ClassNotFoundException e) {
LOG.info("The Attach API is not available in this JVM, falling back to JMX over RMI");
return m_jmxUrl;
}
VirtualMachine vm = null;
final StringBuilder vmNames = new StringBuilder();
boolean first = true;
// Use the Attach API to enumerate all of the JVMs that are running as the same
// user on this machine
VirtualMachineDescriptor foundVm = null;
for (VirtualMachineDescriptor vmDescr : VirtualMachine.list()) {
if (!first) {
vmNames.append(", ");
}
vmNames.append("\"" + vmDescr.displayName() + "\"");
first = false;
if (vmDescr.displayName().contains(OPENNMS_JVM_DISPLAY_NAME_SUBSTRING)) {
foundVm = vmDescr;
}
}
if (foundVm == null) {
LOG.debug("Could not find OpenNMS JVM (\"" + OPENNMS_JVM_DISPLAY_NAME_SUBSTRING + "\") among JVMs (" + vmNames + ")");
} else {
try {
vm = VirtualMachine.attach(foundVm);
LOG.debug("Attached to OpenNMS JVM: " + foundVm.id() + " (" + foundVm.displayName() + ")");
} catch (AttachNotSupportedException e) {
// This exception is unexpected so log a warning
LOG.warn("Cannot attach to OpenNMS JVM", e);
} catch (IOException e) {
// This exception is unexpected so log a warning
LOG.warn("IOException when attaching to OpenNMS JVM", e);
}
}
if (vm == null) {
if (m_pid == null) {
LOG.debug("No PID specified for OpenNMS JVM");
} else {
try {
vm = VirtualMachine.attach(m_pid);
LOG.debug("Attached to OpenNMS JVM with PID: " + m_pid);
} catch (AttachNotSupportedException e) {
// This exception is unexpected so log a warning
LOG.warn("Cannot attach to OpenNMS JVM at PID: " + m_pid, e);
} catch (IOException e) {
// This exception will occur if the PID cannot be found
// because the process has been terminated
LOG.debug("IOException when attaching to OpenNMS JVM at PID: " + m_pid + ": " + e.getMessage());
}
}
}
if (vm == null) {
LOG.debug("Could not attach to JVM, falling back to JMX over RMI");
return m_jmxUrl;
} else {
return getJmxUriFromVirtualMachine(vm);
}
}
use of com.sun.tools.attach.VirtualMachineDescriptor in project openj9 by eclipse.
the class OpenJ9AttachProvider method listVirtualMachines.
@Override
public List<VirtualMachineDescriptor> listVirtualMachines() {
AttachHandler.waitForAttachApiInitialization();
/* ignore result: we can list targets if API is disabled */
/* Figure out where the IPC metadata lives and validate */
File commonDir = CommonDirectory.getCommonDirFileObject();
ArrayList<VirtualMachineDescriptor> descriptors = new ArrayList<>();
if (null == commonDir) {
// $NON-NLS-1$
IPC.logMessage("listVirtualMachines() error getting common directory");
return null;
/* indicate an error */
} else if (!commonDir.exists()) {
// $NON-NLS-1$
IPC.logMessage("listVirtualMachines() common directory is absent");
return descriptors;
/*[PR 103332 - common dir will not exist if attach API is disabled */
} else if (!commonDir.isDirectory()) {
/* Cleanup. handle case where couldn't open common dir. */
// $NON-NLS-1$
IPC.logMessage("listVirtualMachines() common directory is mis-configured");
return null;
/* Configuration error */
}
try {
CommonDirectory.obtainMasterLock();
/*[PR 164751 avoid scanning the directory when an attach API is launching ]*/
} catch (IOException e) {
/*[PR 164751 avoid scanning the directory when an attach API is launching ]*/
/*
* IOException is thrown if we already have the lock. The only other cases where we lock this file are during startup and shutdown.
* The attach API startup is complete, thanks to waitForAttachApiInitialization() and threads using this method terminate before shutdown.
*/
// $NON-NLS-1$
IPC.logMessage("listVirtualMachines() IOError on master lock : ", e.toString());
return descriptors;
/* An error has occurred. Since the attach API is not working correctly, be conservative and don't list and targets */
}
try {
File[] vmDirs = commonDir.listFiles();
if (vmDirs == null) {
/* an IOException on listFiles will cause vmDirs to be null */
return descriptors;
}
long myUid = IPC.getUid();
/* Iterate through the files in the directory */
for (File f : vmDirs) {
/* skip files */
if (!f.isDirectory() || !CommonDirectory.isFileOwnedByUid(f, myUid)) {
continue;
}
boolean staleDirectory = true;
File advertisment = new File(f, Advertisement.getFilename());
long uid = 0;
if (advertisment.exists()) {
OpenJ9VirtualMachineDescriptor descriptor = OpenJ9VirtualMachineDescriptor.fromAdvertisement(this, advertisment);
if (null != descriptor) {
long pid = descriptor.getProcessId();
uid = descriptor.getUid();
if ((0 == pid) || IPC.processExists(pid)) {
descriptors.add(descriptor);
staleDirectory = false;
}
}
/*[PR Jazz 30110 advertisement is from an older version or is corrupt. get the owner via file stat ]*/
if ((myUid != 0) && (0 == uid)) {
/*
* If this process's UID is 0, then it is root and should ignore file ownership and clean up everyone's files.
* If getFileOwner fails, the uid will appear to be -1, and non-root users will ignore it.
* CommonDirectory.deleteStaleDirectories() will handle the case of a target directory which does not have an advertisement directory.
*/
uid = CommonDirectory.getFileOwner(advertisment.getAbsolutePath());
}
}
/*[PR Jazz 22292 do not delete files the process does not own, unless the process is running as root ]*/
if (staleDirectory && ((myUid == 0) || (uid == myUid))) {
// $NON-NLS-1$
IPC.logMessage("listVirtualMachines() removing stale directory : ", f.getName());
TargetDirectory.deleteTargetDirectory(f.getName());
}
}
} finally {
CommonDirectory.releaseMasterLock();
/* guarantee that we unlock the file */
}
return descriptors;
}
use of com.sun.tools.attach.VirtualMachineDescriptor in project openj9 by eclipse.
the class OpenJ9VirtualMachine method lockAllAttachNotificationSyncFiles.
private void lockAllAttachNotificationSyncFiles(List<VirtualMachineDescriptor> vmds) {
int vmdIndex = 0;
targetLocks = new FileLock[vmds.size()];
for (VirtualMachineDescriptor i : vmds) {
OpenJ9VirtualMachineDescriptor vmd;
try {
vmd = (OpenJ9VirtualMachineDescriptor) i;
} catch (ClassCastException e) {
continue;
}
if (!vmd.id().equalsIgnoreCase(AttachHandler.getVmId())) {
/*
* avoid
* overlapping
* locks
*/
String attachSyncFile = vmd.getAttachSyncFileValue();
if (null != attachSyncFile) {
/*
* in case of a malformed advert
* file
*/
// $NON-NLS-1$ //$NON-NLS-2$
IPC.logMessage("lockAllAttachNotificationSyncFiles locking targetLocks[", vmdIndex, "] ", attachSyncFile);
targetLocks[vmdIndex] = new FileLock(attachSyncFile, TargetDirectory.SYNC_FILE_PERMISSIONS);
try {
targetLocks[vmdIndex].lockFile(true);
} catch (IOException e) {
targetLocks[vmdIndex] = null;
// $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
IPC.logMessage("lockAllAttachNotificationSyncFiles locking targetLocks[", vmdIndex, "] ", "already locked");
}
}
} else {
targetLocks[vmdIndex] = null;
}
++vmdIndex;
}
}
use of com.sun.tools.attach.VirtualMachineDescriptor in project openj9 by eclipse.
the class OpenJ9VirtualMachine method tryAttachTarget.
private void tryAttachTarget(int timeout) throws IOException, AttachNotSupportedException {
Reply replyFile = null;
AttachHandler.waitForAttachApiInitialization();
/* ignore result: we can still attach to another target if API is disabled */
// $NON-NLS-1$
IPC.logMessage("VirtualMachineImpl.tryAttachtarget");
Object myIn = AttachHandler.getMainHandler().getIgnoreNotification();
synchronized (myIn) {
int numberOfTargets = 0;
try {
CommonDirectory.obtainAttachLock();
List<VirtualMachineDescriptor> vmds = myProvider.listVirtualMachines();
if (null == vmds) {
return;
}
targetServer = new ServerSocket(0);
/* select a free port */
portNumber = Integer.valueOf(targetServer.getLocalPort());
String key = Integer.toHexString((IPC.getRandomNumber()));
replyFile = new Reply(portNumber, key, TargetDirectory.getTargetDirectoryPath(descriptor.id()), descriptor.getUid());
try {
replyFile.writeReply();
} catch (IOException e) {
/*
* target shut down while we were trying
* to attach
*/
/*[MSG "K0457", "Target no longer available"]*/
// $NON-NLS-1$
AttachNotSupportedException exc = new AttachNotSupportedException(getString("K0457"));
exc.initCause(e);
throw exc;
}
if (descriptor.id().equals(AttachHandler.getVmId())) {
String allowAttachSelf_Value = AttachHandler.allowAttachSelf;
// $NON-NLS-1$
boolean selfAttachAllowed = "".equals(allowAttachSelf_Value) || Boolean.parseBoolean(allowAttachSelf_Value);
if (!selfAttachAllowed) {
// $NON-NLS-1$
throw new IOException(getString("K0646"));
}
/* I am connecting to myself: bypass the notification and launch the attachment thread directly */
if (AttachHandler.isAttachApiInitialized()) {
AttachHandler.getMainHandler().connectToAttacher();
} else {
// $NON-NLS-1$
throw new AttachNotSupportedException(getString("K0558"));
}
} else {
lockAllAttachNotificationSyncFiles(vmds);
numberOfTargets = CommonDirectory.countTargetDirectories();
int status = CommonDirectory.notifyVm(numberOfTargets);
/*[MSG "K0532", "status={0}"]*/
if ((IPC.JNI_OK != status) && (CommonDirectory.J9PORT_INFO_SHSEM_OPENED_STALE != status)) {
// $NON-NLS-1$
throw new AttachNotSupportedException(getString("K0532", status));
}
}
try {
// $NON-NLS-1$ //$NON-NLS-2$
IPC.logMessage("attachTarget " + targetId + " on port " + portNumber);
targetServer.setSoTimeout(timeout);
targetSocket = targetServer.accept();
} catch (SocketTimeoutException e) {
targetServer.close();
// $NON-NLS-1$ //$NON-NLS-2$
IPC.logMessage("attachTarget SocketTimeoutException on " + portNumber + " to " + targetId);
/*[MSG "K0539","acknowledgement timeout from {0} on port {1}"]*/
// $NON-NLS-1$
AttachNotSupportedException exc = new AttachNotSupportedException(getString("K0539", targetId, portNumber));
exc.initCause(e);
throw exc;
}
commandStream = targetSocket.getOutputStream();
targetSocket.setSoTimeout(COMMAND_TIMEOUT);
responseStream = targetSocket.getInputStream();
/*
* Limit data until the target is verified.
*/
String response = AttachmentConnection.streamReceiveString(responseStream, ATTACH_CONNECTED_MESSAGE_LENGTH_LIMIT);
/*[MSG "K0533", "key error: {0}"]*/
if (!response.contains(' ' + key + ' ')) {
// $NON-NLS-1$
throw new AttachNotSupportedException(getString("K0533", response));
}
// $NON-NLS-1$
IPC.logMessage("attachTarget connected on ", portNumber.toString());
targetAttached = true;
} finally {
if (null != replyFile) {
replyFile.deleteReply();
}
if (numberOfTargets > 0) {
/*[PR 48044] if number of targets is 0, then the VM is attaching to itself and the semaphore was not involved */
unlockAllAttachNotificationSyncFiles();
CommonDirectory.cancelNotify(numberOfTargets);
if (numberOfTargets > 2) {
try {
int delayTime = 100 * ((numberOfTargets > 10) ? 10 : numberOfTargets);
// $NON-NLS-1$
IPC.logMessage("attachTarget sleep for ", delayTime);
Thread.sleep(delayTime);
} catch (InterruptedException e) {
// $NON-NLS-1$
IPC.logMessage("attachTarget sleep interrupted");
}
}
}
CommonDirectory.releaseAttachLock();
}
}
}
use of com.sun.tools.attach.VirtualMachineDescriptor in project openj9 by eclipse.
the class Props method listVms.
private static String[] listVms() {
List<AttachProvider> providers = AttachProvider.providers();
AttachProvider ap = providers.get(0);
if (null == ap) {
System.err.println("no attach providers available");
return (null);
}
List<VirtualMachineDescriptor> vmds = ap.listVirtualMachines();
ArrayList<String> vmidBuffer = new ArrayList<String>();
for (VirtualMachineDescriptor vmd : vmds) {
vmidBuffer.add(vmd.id());
}
return vmidBuffer.toArray(new String[vmidBuffer.size()]);
}
Aggregations