Search in sources :

Example 1 with VirtualMachineDescriptor

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);
    }
}
Also used : VirtualMachineDescriptor(com.sun.tools.attach.VirtualMachineDescriptor) IOException(java.io.IOException) AttachNotSupportedException(com.sun.tools.attach.AttachNotSupportedException) VirtualMachine(com.sun.tools.attach.VirtualMachine)

Example 2 with VirtualMachineDescriptor

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;
}
Also used : ArrayList(java.util.ArrayList) VirtualMachineDescriptor(com.sun.tools.attach.VirtualMachineDescriptor) IOException(java.io.IOException) File(java.io.File)

Example 3 with VirtualMachineDescriptor

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;
    }
}
Also used : FileLock(com.ibm.tools.attach.target.FileLock) VirtualMachineDescriptor(com.sun.tools.attach.VirtualMachineDescriptor) Msg.getString(com.ibm.oti.util.Msg.getString) IOException(java.io.IOException)

Example 4 with VirtualMachineDescriptor

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();
        }
    }
}
Also used : SocketTimeoutException(java.net.SocketTimeoutException) Reply(com.ibm.tools.attach.target.Reply) ServerSocket(java.net.ServerSocket) VirtualMachineDescriptor(com.sun.tools.attach.VirtualMachineDescriptor) Msg.getString(com.ibm.oti.util.Msg.getString) IOException(java.io.IOException) AttachNotSupportedException(com.sun.tools.attach.AttachNotSupportedException)

Example 5 with VirtualMachineDescriptor

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()]);
}
Also used : ArrayList(java.util.ArrayList) VirtualMachineDescriptor(com.sun.tools.attach.VirtualMachineDescriptor) AttachProvider(com.sun.tools.attach.spi.AttachProvider)

Aggregations

VirtualMachineDescriptor (com.sun.tools.attach.VirtualMachineDescriptor)26 IOException (java.io.IOException)16 AttachNotSupportedException (com.sun.tools.attach.AttachNotSupportedException)13 AttachProvider (com.sun.tools.attach.spi.AttachProvider)12 VirtualMachine (com.sun.tools.attach.VirtualMachine)11 Test (org.testng.annotations.Test)7 ArrayList (java.util.ArrayList)5 Msg.getString (com.ibm.oti.util.Msg.getString)2 AgentLoadException (com.sun.tools.attach.AgentLoadException)2 File (java.io.File)2 URISyntaxException (java.net.URISyntaxException)2 JMXServiceURL (javax.management.remote.JMXServiceURL)2 MonitorException (sun.jvmstat.monitor.MonitorException)2 ImmutableMap (com.google.common.collect.ImmutableMap)1 FileLock (com.ibm.tools.attach.target.FileLock)1 Reply (com.ibm.tools.attach.target.Reply)1 AgentInitializationException (com.sun.tools.attach.AgentInitializationException)1 AttachOperationFailedException (com.sun.tools.attach.AttachOperationFailedException)1 CommonContext (io.aeron.CommonContext)1 AeronCluster (io.aeron.cluster.client.AeronCluster)1