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

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

大家。

我试图执行“mvn clean test”来验证一个由“mvn archetype:generate”生成的简单 maven 项目。我只是想学习如何编写单元 test.But 我得到了一个例外,经过长时间的调试和尝试,我不知道如何继续,请给我一些建议。 因为我不知道哪里出了问题,所以我会尽量提供更多信息。

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(我也试过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>

主要java代码:

package com.juexi.learning;

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

    public int getId() {
        return 333;
    }
}

测试java代码:

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());
    }
}

堆栈跟踪信息:

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.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.run(ParentRunner.java:290)
        at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
        at org.junit.runners.ParentRunner.access[=15=]0(ParentRunner.java:58)
        at org.junit.runners.ParentRunner.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)

我试过的: 我尝试调试并在 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);
            ....

并在 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;
    }

似乎本地方法 createAttachFile(String path) 试图创建一个文件,并且 ClassLoader 试图从本地加载此本地方法,但在 /Library/Java/JavaVirtualMachines/zulu-8 中找不到此方法。jdk/Contents/Home/jre/lib/libattach.dylib(我通过调试找到这个)。 那么,我该怎么做才能解决这个问题?我不知道该怎么做next.could有人帮我吗?

这看起来类似于 https://github.com/raphw/byte-buddy/issues/1001。请仔细检查应用程序类路径

中是否有任何不同的tools.jar

在@Mells 的帮助下,我post将这个问题发给了 jmockit 的开发者。更多信息请查看github

而且,开发人员告诉我,这是因为 zulujdk8 删除了本地方法。

-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)

我解决了这个问题。 jUnit 编译和构建选择:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home(这是您的 java_home 路径)而不是其他版本。 并且 运行,有效!!!