jmockit / jmockit1

Advanced Java library for integration testing, mocking, faking, and code coverage

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

yangjuexi opened this issue · comments

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

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)

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.

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.

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

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.

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 ?

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

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