如何在 JVM 启动后动态设置系统属性,而不修改我的程序代码?

问题描述 投票:0回答:1

我希望能够在 Java 应用程序在应用程序服务器内运行时更改系统属性。我知道这可以通过

java.lang.System.setProperty
或添加
-DpropertyName=value
作为 JVM 标志来完成。

但我想在运行时执行此操作,而不修改应用程序代码。

是否有一种工具可以在运行时更改 JVM 中的系统属性,而无需更新应用程序代码(例如,只需将工具附加到正在运行的进程或使用 JMX)?

java jvm jmx
1个回答
0
投票

这个想法是将一个调用

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
    文件:
Main-Class: SetProperty
Agent-Class: SetProperty
  1. 从编译的源代码和清单构建 .jar 文件:
jar cfm setproperty.jar MANIFEST.MF SetProperty.class 
  1. 启动代理并传递目标进程 ID 和要设置的属性:
java -jar setproperty.jar 1234 MyProperty=SomeValue

我准备了 setproperty.jar,这样您就可以跳过步骤 1-3 并直接执行最终命令。

© www.soinside.com 2019 - 2024. All rights reserved.