/*
* Copyright 2014 - 2020 Rafael Winterhalter
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.bytebuddy.agent;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.lang.reflect.InvocationTargetException;
A Java program that attaches a Java agent to an external process.
/**
* A Java program that attaches a Java agent to an external process.
*/
public class Attacher {
Base for access to a reflective member to make the code more readable.
/**
* Base for access to a reflective member to make the code more readable.
*/
private static final Object STATIC_MEMBER = null;
The name of the attach
method of the VirtualMachine
class. /**
* The name of the {@code attach} method of the {@code VirtualMachine} class.
*/
private static final String ATTACH_METHOD_NAME = "attach";
The name of the loadAgent
method of the VirtualMachine
class. /**
* The name of the {@code loadAgent} method of the {@code VirtualMachine} class.
*/
private static final String LOAD_AGENT_METHOD_NAME = "loadAgent";
The name of the loadAgentPath
method of the VirtualMachine
class. /**
* The name of the {@code loadAgentPath} method of the {@code VirtualMachine} class.
*/
private static final String LOAD_AGENT_PATH_METHOD_NAME = "loadAgentPath";
The name of the detach
method of the VirtualMachine
class. /**
* The name of the {@code detach} method of the {@code VirtualMachine} class.
*/
private static final String DETACH_METHOD_NAME = "detach";
The attacher provides only static
utility methods and should not be instantiated. /**
* The attacher provides only {@code static} utility methods and should not be instantiated.
*/
private Attacher() {
throw new UnsupportedOperationException("This class is a utility class and not supposed to be instantiated");
}
Runs the attacher as a Java application.
Params: - args – A list containing the fully qualified name of the virtual machine type, the process id, the fully qualified name of the Java agent jar followed by an empty string if the argument to the agent is
null
or any number of strings where the first argument is proceeded by any single character which is stripped off.
/**
* Runs the attacher as a Java application.
*
* @param args A list containing the fully qualified name of the virtual machine type,
* the process id, the fully qualified name of the Java agent jar followed by
* an empty string if the argument to the agent is {@code null} or any number
* of strings where the first argument is proceeded by any single character
* which is stripped off.
*/
@SuppressFBWarnings(value = "REC_CATCH_EXCEPTION", justification = "Exception should not be rethrown but trigger a fallback")
public static void main(String[] args) {
try {
String argument;
if (args.length < 5 || args[4].length() == 0) {
argument = null;
} else {
StringBuilder stringBuilder = new StringBuilder(args[4].substring(1));
for (int index = 5; index < args.length; index++) {
stringBuilder.append(' ').append(args[index]);
}
argument = stringBuilder.toString();
}
install(Class.forName(args[0]), args[1], args[2], Boolean.parseBoolean(args[3]), argument);
} catch (Throwable ignored) {
System.exit(1);
}
}
Installs a Java agent on a target VM.
Params: - virtualMachineType – The virtual machine type to use for the external attachment.
- processId – The id of the process being target of the external attachment.
- agent – The Java agent to attach.
- isNative –
true
if the agent is native. - argument – The argument to provide or
null
if no argument is provided.
Throws: - NoSuchMethodException – If the virtual machine type does not define an expected method.
- InvocationTargetException – If the virtual machine type raises an error.
- IllegalAccessException – If a method of the virtual machine type cannot be accessed.
/**
* Installs a Java agent on a target VM.
*
* @param virtualMachineType The virtual machine type to use for the external attachment.
* @param processId The id of the process being target of the external attachment.
* @param agent The Java agent to attach.
* @param isNative {@code true} if the agent is native.
* @param argument The argument to provide or {@code null} if no argument is provided.
* @throws NoSuchMethodException If the virtual machine type does not define an expected method.
* @throws InvocationTargetException If the virtual machine type raises an error.
* @throws IllegalAccessException If a method of the virtual machine type cannot be accessed.
*/
protected static void install(Class<?> virtualMachineType,
String processId,
String agent,
boolean isNative,
String argument) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Object virtualMachineInstance = virtualMachineType
.getMethod(ATTACH_METHOD_NAME, String.class)
.invoke(STATIC_MEMBER, processId);
try {
virtualMachineType
.getMethod(isNative ? LOAD_AGENT_PATH_METHOD_NAME : LOAD_AGENT_METHOD_NAME, String.class, String.class)
.invoke(virtualMachineInstance, agent, argument);
} finally {
virtualMachineType
.getMethod(DETACH_METHOD_NAME)
.invoke(virtualMachineInstance);
}
}
}