I would like to be able to change a system property while a java application is running inside an application server. I know that this can be done with java.lang.System.setProperty
or by adding the -DpropertyName=value
as a JVM flag.
But I want to do this at runtime and without modifying the application code.
Is there a tool that can change system properties in the JVM at runtime without having to update the application-code ( e.g. just by attaching a tool the running process or by using JMX ) ?
The idea is to attach an agent that calls System.setProperty
to a running application.
Note: this does not require modifying application code.
Here is the agent code:
import com.sun.tools.attach.VirtualMachine;
public class SetProperty {
public static void main(String[] args) throws Exception {
String url = SetProperty.class.getProtectionDomain().getCodeSource().getLocation().toString();
if (args.length < 2 || !url.startsWith("file:")) {
System.out.println("Usage: java -jar setproperty.jar pid property=value");
System.exit(1);
}
VirtualMachine vm = VirtualMachine.attach(args[0]);
try {
int startIndex = "\\".equals(System.getProperty("file.separator")) ? 6 : 5;
vm.loadAgent(url.substring(startIndex), args[1]);
} finally {
vm.detach();
}
}
public static void agentmain(String args) {
int eq = args.indexOf('=');
System.setProperty(args.substring(0, eq), args.substring(eq + 1));
}
}
javac -source 8 -target 8 SetProperty.java
MANIFEST.MF
file with the following contents:Main-Class: SetProperty
Agent-Class: SetProperty
jar cfm setproperty.jar MANIFEST.MF SetProperty.class
java -jar setproperty.jar 1234 MyProperty=SomeValue
If you are using JDK 8, you'll need to add tools.jar
to the class path:
java -cp setproperty.jar:$JAVA_HOME/lib/tools.jar SetProperty 1234 MyProperty=SomeValue
I prepared setproperty.jar so you can skip steps 1-3 and proceed directly to the final command.