我希望能够改变一个系统属性,而Java应用程序是在应用服务器内运行。我知道这可以通过java.lang.System.setProperty或添加-DpropertyName=value作为JVM标志来完成。但是我想在运行时完成这项工作,而不修改应用程序代码。有没有一种工具可以在运行时更改JVM中的系统属性,而不必更新应用程序代码(例如,仅仅通过在运行的进程中附加一个工具或使用JMX)?
java.lang.System.setProperty
-DpropertyName=value
qoefvg9y1#
其想法是将调用System.setProperty的代理附加到正在运行的应用程序。
System.setProperty
**注意:**不需要修改应用代码。
下面是代理代码:
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)); } }
1.编译源代码:
javac -source 8 -taraget 8 SetProperty.java
1.创建包含以下内容的MANIFEST.MF文件:
MANIFEST.MF
Main-Class: SetProperty Agent-Class: SetProperty
1.从编译的源代码和清单构建.jar文件:
jar cfm setproperty.jar MANIFEST.MF SetProperty.class
1.启动代理,传递目标进程ID和要设置的属性(JDK 9+):
java -jar setproperty.jar 1234 MyProperty=SomeValue
如果使用JDK 8,则需要将tools.jar添加到类路径:
tools.jar
java -cp setproperty.jar:$JAVA_HOME/lib/tools.jar SetProperty 1234 MyProperty=SomeValue
我准备了setproperty.jar,这样你就可以跳过步骤1-3,直接执行最后一个命令。
1条答案
按热度按时间qoefvg9y1#
其想法是将调用
System.setProperty
的代理附加到正在运行的应用程序。**注意:**不需要修改应用代码。
下面是代理代码:
1.编译源代码:
1.创建包含以下内容的
MANIFEST.MF
文件:1.从编译的源代码和清单构建.jar文件:
1.启动代理,传递目标进程ID和要设置的属性(JDK 9+):
如果使用JDK 8,则需要将
tools.jar
添加到类路径:我准备了setproperty.jar,这样你就可以跳过步骤1-3,直接执行最后一个命令。