java.lang.illegalaccesserror从SBT运行Mockito时



看起来像是sbt classload和mockito。

project/build.scala

import sbt._
import Keys._
import sbtassembly.Plugin._
import AssemblyKeys._
object Build extends Build {
  lazy val root = project.in(file("."))
    .settings(
      name := "so-mockito",
      compileOrder := CompileOrder.JavaThenScala,
      libraryDependencies += "org.mockito" % "mockito-core" % "1.9.5"
    )
    .settings(buildSettings: _*)
    .settings(assemblySettings: _*)
    .settings(mainClass in assembly := Some("com.example.JavaMain"))
}

project/plugins.sbt

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.10.2")

src/main/java/com/example/consumer.java

package com.example;
class Consumer {
    interface Input {
        String get();
    }
    private final Input input;
    static Consumer create(Input input) {
        return new Consumer(input);
    }
    private Consumer(Input input) {
        this.input = input;
    }
}

src/main/java/com/example/javamain.java

package com.example;
import static org.mockito.Mockito.*;
import static com.example.Consumer.*;
public class JavaMain {
    public static void main(String[] args) {
        final Input input = mock(Input.class);
        System.out.println(String.format("[JavaMain] Created mock: '%s'", input));
    }
}

sbt run产生以下例外:

[info] Running com.example.JavaMain 
[error] (run-main-0) org.mockito.exceptions.base.MockitoException: 
[error] Mockito cannot mock this class: interface com.example.Consumer$Input
[error] Mockito can only mock visible & non-final classes.
[error] If you're not sure why you're getting this error, please report to the mailing list.
org.mockito.exceptions.base.MockitoException: 
Mockito cannot mock this class: interface com.example.Consumer$Input
Mockito can only mock visible & non-final classes.
If you're not sure why you're getting this error, please report to the mailing list.
    at com.example.JavaMain.main(JavaMain.java:8)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
Caused by: org.mockito.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
    at org.mockito.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:238)
    at org.mockito.cglib.proxy.Enhancer.createHelper(Enhancer.java:378)
    at org.mockito.cglib.proxy.Enhancer.createClass(Enhancer.java:318)
    at org.mockito.internal.creation.jmock.ClassImposterizer.createProxyClass(ClassImposterizer.java:110)
    at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:62)
    at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:56)
    at org.mockito.internal.creation.CglibMockMaker.createMock(CglibMockMaker.java:23)
    at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:26)
    at org.mockito.internal.MockitoCore.mock(MockitoCore.java:51)
    at org.mockito.Mockito.mock(Mockito.java:1243)
    at org.mockito.Mockito.mock(Mockito.java:1120)
    at com.example.JavaMain.main(JavaMain.java:8)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.mockito.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:385)
    at org.mockito.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:220)
    at org.mockito.cglib.proxy.Enhancer.createHelper(Enhancer.java:378)
    at org.mockito.cglib.proxy.Enhancer.createClass(Enhancer.java:318)
    at org.mockito.internal.creation.jmock.ClassImposterizer.createProxyClass(ClassImposterizer.java:110)
    at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:62)
    at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:56)
    at org.mockito.internal.creation.CglibMockMaker.createMock(CglibMockMaker.java:23)
    at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:26)
    at org.mockito.internal.MockitoCore.mock(MockitoCore.java:51)
    at org.mockito.Mockito.mock(Mockito.java:1243)
    at org.mockito.Mockito.mock(Mockito.java:1120)
    at com.example.JavaMain.main(JavaMain.java:8)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
Caused by: java.lang.IllegalAccessError: class com.example.Consumer$Input$$EnhancerByMockitoWithCGLIB$$5997e3ec cannot access its superinterface com.example.Consumer$Input
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.mockito.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:385)
    at org.mockito.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:220)
    at org.mockito.cglib.proxy.Enhancer.createHelper(Enhancer.java:378)
    at org.mockito.cglib.proxy.Enhancer.createClass(Enhancer.java:318)
    at org.mockito.internal.creation.jmock.ClassImposterizer.createProxyClass(ClassImposterizer.java:110)
    at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:62)
    at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:56)
    at org.mockito.internal.creation.CglibMockMaker.createMock(CglibMockMaker.java:23)
    at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:26)
    at org.mockito.internal.MockitoCore.mock(MockitoCore.java:51)
    at org.mockito.Mockito.mock(Mockito.java:1243)
    at org.mockito.Mockito.mock(Mockito.java:1120)
    at com.example.JavaMain.main(JavaMain.java:8)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)

但是,使用javascala运行,按预期运行:

> sbt assembly && java -jar target/scala-2.10/so-mockito-assembly-0.1-SNAPSHOT.jar
[JavaMain] Created mock: 'Mock for Input, hashCode: 1317029026'
> sbt assembly && scala -cp target/scala-2.10/so-mockito-assembly-0.1-SNAPSHOT.jar 'com.example.JavaMain'
[JavaMain] Created mock: 'Mock for Input, hashCode: 1035091326'

任何人都可以确认(SBT 0.13.1)?

当内部com.example.Consumer.Input接口的访问修改器变为 public时,它可以正常工作(注意接口的public关键字):

package com.example;
class Consumer {
    public interface Input {
        String get();
    }
    private final Input input;
    static Consumer create(Input input) {
        return new Consumer(input);
    }
    private Consumer(Input input) {
        this.input = input;
    }
}

以前使用about的示例sbt run,以了解版本,插件等。

$ sbt about run
[info] Loading global plugins from /Users/jacek/.sbt/0.13/plugins
[info] Loading project definition from /Users/jacek/sandbox/so/mockito/project
[info] Set current project to so-mockito (in build file:/Users/jacek/sandbox/so/mockito/)
[info] This is sbt 0.13.1
[info] The current project is {file:/Users/jacek/sandbox/so/mockito/}root 0.1-SNAPSHOT
[info] The current project is built against Scala 2.10.3
[info] Available Plugins: com.typesafe.sbt.SbtGit, com.typesafe.sbt.SbtProguard, growl.GrowlingTests, np.Plugin, com.timushev.sbt.updates.UpdatesPlugin, sbtassembly.Plugin
[info] sbt, sbt plugins, and build definitions are using Scala 2.10.3
[info] Running com.example.JavaMain
[JavaMain] Created mock: 'Mock for Input, hashCode: 256995217'
[success] Total time: 0 s, completed Jan 29, 2014 10:00:13 PM

btw,在这种特定的构建配置中,使用build.sbt可能是一个更好的选择,因为它会变得更加清晰。

build.sbt

import AssemblyKeys._
name := "so-mockito"
compileOrder := CompileOrder.JavaThenScala
libraryDependencies += "org.mockito" % "mockito-core" % "1.9.5"
sbtassembly.Plugin.buildSettings
sbtassembly.Plugin.assemblySettings
mainClass in assembly := Some("com.example.JavaMain")

我在嘲笑Scala代码mock[org.flywaydb.core.Flyway]的飞行时被类似错误击败,测试通过Intellij很好地进行,但是通过它提出的SBT测试: java.lang.IllegalAccessError: tried to access class org.flywaydb.core.Flyway 对于其他Googles,我的解决方案只是升级Mockito Core:

```````` - " org.mockito"%" Mockito-Core"%" 2.7.22", " org.mockito"%" Mockito-Core"%" 2.15.0",

````

相关内容

  • 没有找到相关文章