在IBM JRE上运行jMockit测试时AttachNotSupportedException

时间:2012-08-30 20:54:22

标签: unit-testing junit jmockit

当我尝试使用IBM JDK运行简单的jMockit / JUnit测试时,我得到以下异常。有人遇到过这个问题吗?我尝试将-Dcom.ibm.tools.attach.enable=yes作为VM参数,但没有运气。相同的代码在Sun JDK中运行良好。

java.lang.RuntimeException: com.sun.tools.attach.AttachNotSupportedException: Unable to enqueue operation: the target VM does not support attach mechanism
    at mockit.internal.startup.JDK6AgentLoader.getVirtualMachineImplementationFromEmbeddedOnes(JDK6AgentLoader.java:89)
    at mockit.internal.startup.JDK6AgentLoader.loadAgent(JDK6AgentLoader.java:54)
    at mockit.internal.startup.AgentInitialization.initializeAccordingToJDKVersion(AgentInitialization.java:21)
    at mockit.internal.startup.Startup.initializeIfNeeded(Startup.java:98)
    at mockit.internal.startup.Startup.initializeIfPossible(Startup.java:112)
    at org.junit.runner.Runner.<clinit>(Runner.java:22)
    at java.lang.J9VMInternals.initializeImpl(Native Method)
    at java.lang.J9VMInternals.initialize(J9VMInternals.java:200)
    at java.lang.J9VMInternals.initialize(J9VMInternals.java:167)
    at java.lang.J9VMInternals.initialize(J9VMInternals.java:167)
    at org.junit.internal.builders.JUnit4Builder.runnerForClass(JUnit4Builder.java:13)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
    at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
    at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:24)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.<init>(JUnit4TestReference.java:33)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.<init>(JUnit4TestClassReference.java:25)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:48)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: com.sun.tools.attach.AttachNotSupportedException: Unable to enqueue operation: the target VM does not support attach mechanism
    at sun.tools.attach.WindowsVirtualMachine.<init>(WindowsVirtualMachine.java:64)
    at mockit.internal.startup.JDK6AgentLoader.getVirtualMachineImplementationFromEmbeddedOnes(JDK6AgentLoader.java:73)
    ... 22 more
java.lang.NoClassDefFoundError: org.junit.internal.runners.ErrorReportingRunner (initialization failure)
    at java.lang.J9VMInternals.initialize(J9VMInternals.java:140)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
    at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:24)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.<init>(JUnit4TestReference.java:33)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.<init>(JUnit4TestClassReference.java:25)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:48)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.NoClassDefFoundError: org.junit.runner.Runner (initialization failure)
    at java.lang.J9VMInternals.initialize(J9VMInternals.java:140)
    at java.lang.J9VMInternals.initialize(J9VMInternals.java:167)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
    at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
    ... 9 more
Caused by: java.lang.RuntimeException: com.sun.tools.attach.AttachNotSupportedException: Unable to enqueue operation: the target VM does not support attach mechanism
    at mockit.internal.startup.JDK6AgentLoader.getVirtualMachineImplementationFromEmbeddedOnes(JDK6AgentLoader.java:89)
    at mockit.internal.startup.JDK6AgentLoader.loadAgent(JDK6AgentLoader.java:54)
    at mockit.internal.startup.AgentInitialization.initializeAccordingToJDKVersion(AgentInitialization.java:21)
    at mockit.internal.startup.Startup.initializeIfNeeded(Startup.java:98)
    at mockit.internal.startup.Startup.initializeIfPossible(Startup.java:112)
    at org.junit.runner.Runner.<clinit>(Runner.java:22)
    at java.lang.J9VMInternals.initializeImpl(Native Method)
    at java.lang.J9VMInternals.initialize(J9VMInternals.java:200)
    at java.lang.J9VMInternals.initialize(J9VMInternals.java:167)
    at java.lang.J9VMInternals.initialize(J9VMInternals.java:167)
    at org.junit.internal.builders.JUnit4Builder.runnerForClass(JUnit4Builder.java:13)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
    ... 11 more
Caused by: com.sun.tools.attach.AttachNotSupportedException: Unable to enqueue operation: the target VM does not support attach mechanism
    at sun.tools.attach.WindowsVirtualMachine.<init>(WindowsVirtualMachine.java:64)
    at mockit.internal.startup.JDK6AgentLoader.getVirtualMachineImplementationFromEmbeddedOnes(JDK6AgentLoader.java:73)
    ... 22 more

我尝试按照Kevin Welker的建议给出VM参数-javaagent:jmockit.jar,我得到了以下异常。

Exception in thread "main" java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:48)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
    at java.lang.reflect.Method.invoke(Method.java:600)
    at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:335)
    at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:350)
Caused by: java.lang.NullPointerException
    at mockit.internal.annotations.MockClassSetup.validateRealClass(MockClassSetup.java:59)
    at mockit.internal.annotations.MockClassSetup.<init>(MockClassSetup.java:38)
    at mockit.internal.annotations.MockClassSetup.<init>(MockClassSetup.java:77)
    at mockit.internal.annotations.MockClassSetup.<init>(MockClassSetup.java:99)
    at mockit.internal.startup.JMockitInitialization.setUpInternalStartupMock(JMockitInitialization.java:56)
    at mockit.internal.startup.JMockitInitialization.initialize(JMockitInitialization.java:29)
    at mockit.internal.startup.Startup.initialize(Startup.java:68)
    at mockit.internal.startup.Startup.premain(Startup.java:56)
    ... 6 more

Fatal error: processing of -javaagent failed

6 个答案:

答案 0 :(得分:9)

Attach API在IBM JDK 6.0中不起作用,至少在Windows上是这样。因此,有必要使用-javaagent:jmockit.jar参数。

使用NullPointerExceptionMockClassSetup.java:59发生的-javaagent是由IBM JDK中的错误引起的。当类路径中不存在注释属性(在本例中为@MockClass)中引用的类型时,JDK应该抛出TypeNotPresentException。 Oracle JDK按预期执行此操作,但IBM JDK返回null而不是属性值。

我刚刚在类MockClassSetup中为此实现了一种解决方法,该解决方案将在9月底的下一个JMockit版本中提供。现在,您可以通过将TestNG添加到类路径来避免此问题(因为“未找到类型”是org.testng.TestNG类)。

答案 1 :(得分:2)

使用-javaagent的上述答案是正确的。如果你正在使用maven,这有点棘手,所以我就是这样做的:

  1. 添加maven-dependency-plugin,以便生成依赖项的绝对路径:
  2. <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-dependency-plugin</artifactId>
      <version>2.5.1</version>
      <executions>
        <execution>
          <id>getClasspathFilenames</id>
          <goals>
             <goal>properties</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
    

    2。将-javaagent添加到surefire插件

    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-plugin</artifactId>
      <version>2.13</version>
      <configuration>
        <argLine>-javaagent:${com.googlecode.jmockit:jmockit:jar} -XX:-UseSplitVerifier</argLine>
      </configuration>
    </plugin>
    

    3。此外,您不必,但我建议使用相对较新版本的jmockit。这个问题在1.1中被检测到(在2012年9月由@Rogério修复之前,但添加-javaagent无论如何修复它。作为参考,我使用maven central(2.5)中提供的最新版本,截至此评论:

    <dependency>
      <groupId>com.googlecode.jmockit</groupId>
      <artifactId>jmockit</artifactId>
      <!-- Use latest version. 1.1 gives AttachNotSupportedException -->
      <version>1.5</version>
      <scope>test</scope>
    </dependency>
    

答案 2 :(得分:1)

某些版本的IBM JDK不能正确支持附加机制。您可以尝试使用-javaagent:jmockit.jar参数运行。以下信息有点旧,但它可能仍然适用,因为其他JDK不一定完全支持附加机制。

请参阅:http://code.google.com/p/jmockit/issues/detail?id=18

答案 3 :(得分:0)

我还尝试使用JMockit覆盖第三方库中类的最终方法。我遇到了上面讨论的相同问题,并再次添加VM arg -javaagent:C:/<Path-to-jar>/jmockit.jar只给了我一个不同类型的错误。我也在使用Websphere附带的IBM JDK 6.0。这是一种耻辱,但看起来它实际上是不可能覆盖最终方法:我找不到任何其他可以做到的测试框架。

答案 4 :(得分:0)

您只需将JDK更新为1.8即可。我测试了这个版本的JDK,这个问题已经解决了。

答案 5 :(得分:0)

使用maven设置针对surefire的javagent看起来像这样:

 <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.18.1</version>
    <configuration>
        ....
        <argLine>-javaagent:"${settings.localRepository}"/org/jmockit/jmockit/1.11/jmockit-1.11.jar</argLine>
    </configuration>
  </plugin>

以上假设您使用以下依赖项:

 <dependency>
    <groupId>org.jmockit</groupId>
    <artifactId>jmockit</artifactId>
    <version>1.11</version>
    <scope>test</scope>
  </dependency>

如果您使用的是其他版本,请相应地修改argLine值。

来源:http://jmockit.googlecode.com/svn-history/r1166/trunk/www/installation.html