Skip to content

how to fix java.lang.UnsatisfiedLinkError: sun.tools.attach.BsdVirtualMachine.createAttachFile(Ljava/lang/String;)

everyone.

I was trying to execute ” mvn clean test ” to verify a simple maven project which was generated by “mvn archetype:generate”.I just to want learning how to write unit test.But I got a exception , after a long time debug and trying , I don’t know how to continue,please give me some advice. Because I don’t know what’s wrong, so I will try to give as much info as I can.

os:

    mac os 11.2.3(big sur with m1 chip)

jdk:

openjdk version "1.8.0_282"
OpenJDK Runtime Environment (Zulu 8.52.0.23-CA-macos-aarch64) (build 1.8.0_282-b08)
OpenJDK 64-Bit Server VM (Zulu 8.52.0.23-CA-macos-aarch64) (build 25.282-b08, mixed mode)

maven: apache-maven-3.8.1(I also tried 3.6.3)

pom.xml:

<properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
    <dependency>
        <groupId>org.jmockit</groupId>
        <artifactId>jmockit</artifactId>
        <version>1.36</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
</dependencies>

main java code :

package com.juexi.learning;

/**
 * Hello world!
 *
 */
public class App {

    public int getId() {
        return 333;
    }
}

test java code:

package com.juexi.learning;

import org.junit.Assert;
import org.junit.Test;

import mockit.Mocked;

/**
 * Unit test for simple App.
 */
public class AppTest {
    @Mocked
    App app;

    @Test
    public void testApp() {
        Assert.assertSame(1, app.getId());
    }
}

stack trace info:

Running com.juexi.learning.AppTest
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
        at mockit.internal.startup.AgentLoader.getVirtualMachineImplementationFromEmbeddedOnes(AgentLoader.java:80)
        at mockit.internal.startup.AgentLoader.loadAgent(AgentLoader.java:52)
        at mockit.internal.startup.Startup.initializeIfPossible(Startup.java:147)
        at org.junit.runner.Runner.<clinit>(Runner.java:22)
        at org.junit.internal.builders.JUnit4Builder.runnerForClass(JUnit4Builder.java:10)
        at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
        at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
        at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
        at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:33)
        at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:250)
        at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
        at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
        at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
        at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Caused by: java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at mockit.internal.startup.AgentLoader.getVirtualMachineImplementationFromEmbeddedOnes(AgentLoader.java:76)
        ... 20 more
Caused by: java.lang.UnsatisfiedLinkError: sun.tools.attach.BsdVirtualMachine.createAttachFile(Ljava/lang/String;)V
        at sun.tools.attach.BsdVirtualMachine.createAttachFile(Native Method)
        at sun.tools.attach.BsdVirtualMachine.<init>(BsdVirtualMachine.java:74)
        ... 25 more
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.047 sec <<< FAILURE!
testApp(com.juexi.learning.AppTest)  Time elapsed: 0.003 sec  <<< ERROR!
java.lang.NullPointerException
        at com.juexi.learning.AppTest.testApp(AppTest.java:17)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        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.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
        at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
        at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
        at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
        at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)


Results :

Tests in error: 
  testApp(com.juexi.learning.AppTest)

what I have tried: I tried to debug and I got this in class BsdVirtualMachine.class

public BsdVirtualMachine(AttachProvider provider, String vmid)
        throws AttachNotSupportedException, IOException
    {
        super(provider, vmid);

        // This provider only understands pids
        int pid;
        try {
            pid = Integer.parseInt(vmid);
        } catch (NumberFormatException x) {
            throw new AttachNotSupportedException("Invalid process identifier");
        }

        // Find the socket file. If not found then we attempt to start the
        // attach mechanism in the target VM by sending it a QUIT signal.
        // Then we attempt to find the socket file again.
        path = findSocketFile(pid);
        if (path == null) {
            File f = new File(tmpdir, ".attach_pid" + pid);


            createAttachFile(f.getPath());  // this line is where the exception comes from


            try {
                sendQuitTo(pid);
            ....

and it invoke in ClassLoader.class :

    static long findNative(ClassLoader loader, String name) {
        Vector<NativeLibrary> libs =
            loader != null ? loader.nativeLibraries : systemNativeLibraries;
        synchronized (libs) {
            int size = libs.size();
            for (int i = 0; i < size; i++) {
                NativeLibrary lib = libs.elementAt(i);
                long entry = lib.find(name);
                if (entry != 0)
                    return entry;
            }
        }
        return 0;
    }

It seems a native method createAttachFile(String path) tried to create a file ,and the ClassLoader was trying to load this native method from local, but it can not find this method in /Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/libattach.dylib ( I find this by debuging). so, what can I do to fix this problem?and I don’t know how to do next.could someone help me?

Answer

With @Mells ‘s help,I post this issue to the developers of jmockit .for more please check github

And,the developer told me that this was because zulujdk8 remove the native method.

-JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_createAttachFile(JNIEnv *env, jclass cls, jstring path)
+JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_createAttachFile0(JNIEnv *env, jclass cls, jstring path)