jmockit / jmockit1

Advanced Java library for integration testing, mocking, faking, and code coverage
Other
465 stars 240 forks source link

get java.lang.RuntimeException: java.lang.reflect.InvocationTargetException while run the test #710

Open ghost opened 3 years ago

ghost commented 3 years ago

Hi,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 an 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).

with zulujdk's official engineer's help, I found maybe jmockit-1.36.jar is not compatible with m1 chip? or am I wrong? I tried the same os, same chip ,only difference is jdk is native oracle jdk-1.8.0,and this jdk was transferred from my old Mac.Because some jmp bugs, I quit it and try the zulujdk.

I will paste the log file of command (mvn -X clean test )below: test1.log

VladimirKempik commented 3 years ago

difference between zulu8 and openjdk8: zulu8 has backport of 8157236 ( from ojdk9) and this is the main cause of the isssues here. perhaps it's not a best idea to use jdk's internal api

http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/f754ada66386


-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)
ghost commented 3 years ago

Thanks @VladimirKempik . It seems only if I change my jdk to native oracle jdk or another jdk which doesn't delete the Java_sun_tools_attach_VirtualMachineImpl_createAttachFile, or I will not run the unit test successfully.

glf2046 commented 3 years ago

did you find another way to fix it pls? I met the same issue, but our prod use openjdk8, so can't switch to use ojdk.

VladimirKempik commented 3 years ago

there is no evidence that 8157236 was backported into openjdk8, it's strange you have the same issue

ghost commented 3 years ago

did you find another way to fix it pls? I met the same issue, but our prod use openjdk8, so can't switch to use ojdk.

Actually,I did find a way to solve this issue. Maybe it is useful for you. When I uninstalled the jdk and tried to reinstall it(just use the package from oracle) , maven noticed me that no jre/jdk was found .I inputed 'echo $JAVA_HOME' in the terminal and no variable was found.And I declared that in my .zsh file and it works

So,what I did is :

  1. uninstall the jdk
  2. reinstall the jdk
  3. declare the variable $JAVA_HOME in you .zsh file

Further more,i used the .dmg package , but I don't know why it didn't create $JAVA_HOME automatically.

ruiruige commented 2 years ago

Actually,I did find a way to solve this issue. Maybe it is useful for you. When I uninstalled the jdk and tried to reinstall it(just use the package from oracle) , maven noticed me that no jre/jdk was found .I inputed 'echo $JAVA_HOME' in the terminal and no variable was found.And I declared that in my .zsh file and it works

I have encountered the same problem. oracle seems provide no support for JKD8-m1 version. So which version did you use? X86_64 or arm64 ?

ghost commented 2 years ago

Actually,I did find a way to solve this issue. Maybe it is useful for you. When I uninstalled the jdk and tried to reinstall it(just use the package from oracle) , maven noticed me that no jre/jdk was found .I inputed 'echo $JAVA_HOME' in the terminal and no variable was found.And I declared that in my .zsh file and it works

I have encountered the same problem. oracle seems provide no support for JKD8-m1 version. So which version did you use? X86_64 or arm64 ?

There was just one install file. plz just download the .dmg file and install it manually.And then, declare the variable $JAVA_HOME in your .zsh config file.

I see the latest version is jdk-8u321-macosx-x64.dmg

teacherLaoWang commented 2 years ago

I solved this problem. jUnit compile and build chose :/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home(this is your java_home path) not other version. and run , it work!!!