如何全局设置jdk.attach.allowAttachSelf=true

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

我正在尝试将我们的一个系统从 java 8 迁移到 java 9,在 java 8 中运行正常的大约三分之一的单元测试失败,并出现以下错误:

java.io.IOException: Can not attach to current VM

Google 带我看了几页,我很快就明白了,在 java 9 中,默认行为已更改,以防止附加到当前 VM,并返回到旧的方式,您需要将系统属性

jdk.attach.allowAttachSelf
设置为 true。

在 IntelliJ 中设置此项时,测试工作正常。更改 build.gradle 以包含此内容时,效果相同:

test {
    jvmArgs '-Djdk.attach.allowAttachSelf=true'
}

但是,我宁愿在全局范围内进行此设置,这样我就不需要破解我的 build.gradle 和 IntelliJ。

我在 ubuntu 上运行 java 9,我更改了

/etc/profile.d/jdk.sh
以包含此内容:

export JDK_JAVA_OPTIONS="-Djdk.attach.allowAttachSelf=true"

运行 Gradle 构建时,我可以看到设置被选取,因为我在构建输出中看到了以下内容:

NOTE: Picked up JDK_JAVA_OPTIONS: -Djdk.attach.allowAttachSelf=true

但是,测试不断失败并出现相同的 IOException。

那么我做错了什么,我应该如何解决它?

提前感谢您的投入。

java java-9
3个回答
3
投票

我的测试是使用 Surefire 插件运行的, 如果在 argline 中添加了所述 vm 参数,则测试开始工作。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-surefire-plugin</artifactId>
     <version>2.14.1</version>
     <configuration>
       <argLine>-Djdk.attach.allowAttachSelf=true </argLine>
     </configuration>
</plugin>

1
投票

我在构建 gradle 项目时也遇到了同样的问题。很多虚拟机绑定问题。添加

JDK_JAVA_OPTIONS=-Djdk.attach.allowAttachSelf=true

在“修改配置”窗格中的环境变量确实解决了这个问题。但是,向“VM 选项”添加任何内容都没有任何作用。


0
投票

我认为你可以使用 Unsafe。

try {
    Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
    theUnsafe.setAccessible(true);
    Unsafe unsafe = (Unsafe) theUnsafe.get(null);
    Field ALLOW_ATTACH_SELF = Class.forName("sun.tools.attach.HotSpotVirtualMachine").getDeclaredField("ALLOW_ATTACH_SELF");
    Object allowAttachSelfBase = unsafe.staticFieldBase(ALLOW_ATTACH_SELF);
    long allowAttachSelfOffset = unsafe.staticFieldOffset(ALLOW_ATTACH_SELF);
    boolean defaultValue = unsafe.getBooleanVolatile(allowAttachSelfBase, allowAttachSelfOffset);
    unsafe.putBooleanVolatile(allowAttachSelfBase, allowAttachSelfOffset, true);
    // Do your agent
    unsafe.putBooleanVolatile(allowAttachSelfBase, allowAttachSelfOffset, defaultValue);
} catch (NoSuchFieldException | IllegalAccessException | ClassNotFoundException e) {
    throw new RuntimeException(e);
}
© www.soinside.com 2019 - 2024. All rights reserved.