VirtualMachine.attach(pid) fails with java.io.IOException: Can not attach to current VM
Asked Answered
L

5

11

After going through this discussion, I'm led to believe the option to attach to the same VM, by default has been disabled in OpenJDK11.

I'm trying to upgrade a java agent to OpenJDK11, during the test cases when VirtualMachine.attach(pid) is called I see it failing with below error. What is the correct way to deal with this situation?

Complete stack trace:

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

at jdk.attach/sun.tools.attach.HotSpotVirtualMachine.<init>(HotSpotVirtualMachine.java:75)
at jdk.attach/sun.tools.attach.VirtualMachineImpl.<init>(VirtualMachineImpl.java:48)
at jdk.attach/sun.tools.attach.AttachProviderImpl.attachVirtualMachine(AttachProviderImpl.java:69)
at jdk.attach/com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:207)
at org.kantega.notsoserial.WithAgentIT.attachAgent(WithAgentIT.java:76)
at org.kantega.notsoserial.WithAgentIT.attackShouldBePreventedWithAgent(WithAgentIT.java:47)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Linen answered 27/6, 2019 at 9:16 Comment(7)
Where does that linked discussion say that -Djdk.attach.allowAttachSelf=true will not work anymore under JDK11?Helot
You need to setup the property on VM startup, not during runtime, otherwise it is ignored. Otherwise, have a look at byte-buddy-agent which can work around the restriction.Violist
@Helot It doesn't. But how can I set the parameter during one of the test cases run which is trying to attach the agent to a JVM, IIUC, which was created by Maven.Linen
@RafaelWinterhalter I'm not sure I follow, how can I set the property from a test case before the VM startup? And yes, I am looking at byte-buddy-agent code and trying to do the attach from a helper process. Being the rookie that I am, haven't managed to get it working yet.Linen
You cannot, you need to boot up the VM with that property set, otherwise, the restriction would be pointless. byte-buddy-agent only requires you to call install to get hold of the instrumentation instance. If it's not working, let me know where you are stuck.Violist
Also an option: Start a new process that does the attach to the current VM.Verduzco
@JohannesKuhn yeah, you're right that's how bytebuddy did it.Linen
L
3

I'm not sure if this would help everyone, but in my case, it was a test case that tested whether the agent attaches to the JDK correctly(it won't be a self attach when the agent actually attaches to a JDK, i.e., actual runtime not a testcase).

Based on the suggestion by @Holger, in the comments, I modified my maven-failsafe-plugin to allow self attach.

        <plugin>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>2.22.2</version>
            <executions>
                <execution>
                    <goals>
                        <goal>integration-test</goal>
                        <goal>verify</goal>
                    </goals>
                    <configuration>
                        <argLine>-Djdk.attach.allowAttachSelf=true</argLine>
                        <forkMode>once</forkMode>
                    </configuration>
                </execution>
            </executions>
        </plugin>
Linen answered 3/1, 2020 at 6:46 Comment(6)
It did not help in my case.Collings
This fix is not working for me, any help would be appreciated! I am facing same issue with OpenJDK11Priscella
@MansinghPatel I'll try to help but you'll need to share more details about what you're trying to do if it's extensive and different from my scenario perhaps post a new question.Linen
Thanks @Shanky, fortunately I got the fix by adding javaagentPriscella
@MansinghPatel can you please provide more details how it was resolved by adding javaagent ?Juggle
@Juggle Just check his answer below - https://mcmap.net/q/1001875/-virtualmachine-attach-pid-fails-with-java-io-ioexception-can-not-attach-to-current-vmLinen
S
5

See JDK-8180425 : Release Note: Attach API cannot be used to attach to the current VM by default:

The implementation of Attach API has changed in JDK 9 to disallow attaching to the current VM by default. This change should have no impact on tools that use the Attach API to attach to a running VM. It may impact libraries that mis-use this API as a way to get at the java.lang.instrument API. The system property jdk.attach.allowAttachSelf may be set on the command line to mitigate any compatibility with this change.

Shluh answered 18/7, 2020 at 2:18 Comment(2)
We launch a VM from within our application. I can attest that adding -Djdk.attach.allowAttachSelf=true to the VM args does allow it to attach and I can get a remote data dump. We use this to find the OS thread ids for each of our java threads so we can tell what thread is running away.Malchy
The OpenJDK issue "JDK-8180425 : Release Note: Attach API cannot be used to attach to the current VM by default" has been moved to bugs.openjdk.org/browse/JDK-8180425Shopwindow
L
3

I'm not sure if this would help everyone, but in my case, it was a test case that tested whether the agent attaches to the JDK correctly(it won't be a self attach when the agent actually attaches to a JDK, i.e., actual runtime not a testcase).

Based on the suggestion by @Holger, in the comments, I modified my maven-failsafe-plugin to allow self attach.

        <plugin>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>2.22.2</version>
            <executions>
                <execution>
                    <goals>
                        <goal>integration-test</goal>
                        <goal>verify</goal>
                    </goals>
                    <configuration>
                        <argLine>-Djdk.attach.allowAttachSelf=true</argLine>
                        <forkMode>once</forkMode>
                    </configuration>
                </execution>
            </executions>
        </plugin>
Linen answered 3/1, 2020 at 6:46 Comment(6)
It did not help in my case.Collings
This fix is not working for me, any help would be appreciated! I am facing same issue with OpenJDK11Priscella
@MansinghPatel I'll try to help but you'll need to share more details about what you're trying to do if it's extensive and different from my scenario perhaps post a new question.Linen
Thanks @Shanky, fortunately I got the fix by adding javaagentPriscella
@MansinghPatel can you please provide more details how it was resolved by adding javaagent ?Juggle
@Juggle Just check his answer below - https://mcmap.net/q/1001875/-virtualmachine-attach-pid-fails-with-java-io-ioexception-can-not-attach-to-current-vmLinen
B
2

@SolarisNeko

use JVM args: -Djdk.attach.allowAttachSelf=true

you can resolve it.

Bringingup answered 10/11, 2022 at 15:51 Comment(1)
Worked for me when I got this error with clj-async-profiler, thanks!Chamberlin
P
0

This worked for me by adding javaagent in maven-surefire-plugin

<plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${maven-surefire-plugin.version}</version>
        <configuration>
          <!-- Centralize test reports in parent project -->
          <reportsDirectory>${basedir}/../target/surefire-reports</reportsDirectory>
          <!-- Sets the VM argument line used for Jacoco when unit tests are run. -->
          <argLine>
             -javaagent:${settings.localRepository}/org/jmockit/jmockit/${jmockit.version}/jmockit-${jmockit.version}.jar ${surefireArgLine}
          </argLine>
        </configuration> 
</plugin>
Priscella answered 3/9, 2020 at 10:28 Comment(0)
C
0

In my case, I was compiling my android project with below setting while the compiler is set to Jdk11 (azul zulu). Changing the JDK to jdk1.8 fixed the issue.

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}

enter image description here

Cedrickceevah answered 27/2, 2023 at 17:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.