运行 Android jUnit Test 时出现 java.lang.VerifyError
我一直在尝试找出为什么我不断收到 java.lang.VerifyError
每当我尝试在任何 jUnit 测试中实例化我的一个类时,我都会完全陷入困境。
我创建了一个简单、最小的测试用例来展示这种行为:
package com.example;
public class Foo {
private int bar;
public Foo(int b) {
bar = b;
}
public int getBar() {
return bar;
}
}
以及单元测试:
package com.example.tests;
import com.example.Foo;
import junit.framework.TestCase;
public class FooTest extends TestCase {
private Foo foo;
protected void setUp() throws Exception {
super.setUp();
}
public void testSanity() {
foo = new Foo(1);
assertTrue(true);
}
}
当单元测试尝试实例化 Foo 对象时,例如 testSanity
方法的第一行,我得到一个 java.lang.VerifyError
。
该项目是针对 Android 1.6 构建的。 Eclipse 中 DDMS 的堆栈跟踪如下所示:
05-16 23:40:01.543: ERROR/AndroidRuntime(934): Uncaught handler: thread main exiting due to uncaught exception
05-16 23:40:01.563: ERROR/AndroidRuntime(934): java.lang.VerifyError: com.example.tests.FooTest
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at java.lang.Class.getDeclaredConstructors(Native Method)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at java.lang.Class.getConstructor(Class.java:484)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at junit.framework.TestSuite.getTestConstructor(TestSuite.java:177)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at junit.framework.TestSuite.<init>(TestSuite.java:59)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at junit.runner.BaseTestRunner.getTest(BaseTestRunner.java:103)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at android.test.AndroidTestRunner.getTest(AndroidTestRunner.java:124)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at android.test.AndroidTestRunner.setTestClassName(AndroidTestRunner.java:52)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at android.test.suitebuilder.TestSuiteBuilder.addTestClassByName(TestSuiteBuilder.java:81)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at android.test.InstrumentationTestRunner.parseTestClass(InstrumentationTestRunner.java:375)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at android.test.InstrumentationTestRunner.parseTestClasses(InstrumentationTestRunner.java:357)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at android.test.InstrumentationTestRunner.onCreate(InstrumentationTestRunner.java:325)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at android.app.ActivityThread.handleBindApplication(ActivityThread.java:3848)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at android.app.ActivityThread.access$2800(ActivityThread.java:116)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1831)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at android.os.Handler.dispatchMessage(Handler.java:99)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at android.os.Looper.loop(Looper.java:123)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at android.app.ActivityThread.main(ActivityThread.java:4203)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at java.lang.reflect.Method.invokeNative(Native Method)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at java.lang.reflect.Method.invoke(Method.java:521)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at dalvik.system.NativeStart.main(Native Met
任何有关修复此问题和运行测试的帮助将不胜感激。
更新
根据 fadden 的回答,VFY logcat 输出如下:
05-18 20:33:04.052: ERROR/dalvikvm(234): Could not find class 'com.example.Foo', referenced from method com.example.tests.FooTest.testSanity
05-18 20:33:04.052: WARN/dalvikvm(234): VFY: unable to resolve new-instance 5 (Lcom/example/Foo;) in Lcom/example/tests/FooTest;
05-18 20:33:04.052: WARN/dalvikvm(234): VFY: rejecting opcode 0x22 at 0x0001
05-18 20:33:04.052: WARN/dalvikvm(234): VFY: rejected Lcom/example/tests/FooTest;.testSanity ()V
05-18 20:33:04.052: WARN/dalvikvm(234): Verifier rejected class Lcom/example/tests/FooTest;
I've been trying to work out why I keep getting a java.lang.VerifyError
every time I try to instantiate one of my classes in any of my jUnit tests, but am completely stumped.
I created a simple, minimal test case that exhibits this behaviour:
package com.example;
public class Foo {
private int bar;
public Foo(int b) {
bar = b;
}
public int getBar() {
return bar;
}
}
And the unit tests:
package com.example.tests;
import com.example.Foo;
import junit.framework.TestCase;
public class FooTest extends TestCase {
private Foo foo;
protected void setUp() throws Exception {
super.setUp();
}
public void testSanity() {
foo = new Foo(1);
assertTrue(true);
}
}
When the unit tests attempts to instantiate a Foo object e.g. the first line of the testSanity
method, I get a java.lang.VerifyError
.
The project is being built against Android 1.6. The stack trace from DDMS in Eclipse looks like this:
05-16 23:40:01.543: ERROR/AndroidRuntime(934): Uncaught handler: thread main exiting due to uncaught exception
05-16 23:40:01.563: ERROR/AndroidRuntime(934): java.lang.VerifyError: com.example.tests.FooTest
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at java.lang.Class.getDeclaredConstructors(Native Method)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at java.lang.Class.getConstructor(Class.java:484)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at junit.framework.TestSuite.getTestConstructor(TestSuite.java:177)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at junit.framework.TestSuite.<init>(TestSuite.java:59)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at junit.runner.BaseTestRunner.getTest(BaseTestRunner.java:103)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at android.test.AndroidTestRunner.getTest(AndroidTestRunner.java:124)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at android.test.AndroidTestRunner.setTestClassName(AndroidTestRunner.java:52)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at android.test.suitebuilder.TestSuiteBuilder.addTestClassByName(TestSuiteBuilder.java:81)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at android.test.InstrumentationTestRunner.parseTestClass(InstrumentationTestRunner.java:375)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at android.test.InstrumentationTestRunner.parseTestClasses(InstrumentationTestRunner.java:357)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at android.test.InstrumentationTestRunner.onCreate(InstrumentationTestRunner.java:325)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at android.app.ActivityThread.handleBindApplication(ActivityThread.java:3848)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at android.app.ActivityThread.access$2800(ActivityThread.java:116)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1831)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at android.os.Handler.dispatchMessage(Handler.java:99)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at android.os.Looper.loop(Looper.java:123)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at android.app.ActivityThread.main(ActivityThread.java:4203)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at java.lang.reflect.Method.invokeNative(Native Method)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at java.lang.reflect.Method.invoke(Method.java:521)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
05-16 23:40:01.563: ERROR/AndroidRuntime(934): at dalvik.system.NativeStart.main(Native Met
Any help in fixing this and getting the tests running would be much appreciated.
UPDATE
Further to fadden's answer, the VFY logcat output is as follows:
05-18 20:33:04.052: ERROR/dalvikvm(234): Could not find class 'com.example.Foo', referenced from method com.example.tests.FooTest.testSanity
05-18 20:33:04.052: WARN/dalvikvm(234): VFY: unable to resolve new-instance 5 (Lcom/example/Foo;) in Lcom/example/tests/FooTest;
05-18 20:33:04.052: WARN/dalvikvm(234): VFY: rejecting opcode 0x22 at 0x0001
05-18 20:33:04.052: WARN/dalvikvm(234): VFY: rejected Lcom/example/tests/FooTest;.testSanity ()V
05-18 20:33:04.052: WARN/dalvikvm(234): Verifier rejected class Lcom/example/tests/FooTest;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
1.5/1.6 中的验证器相当严格。问题的详细解释位于异常上方的行(在 logcat 输出中查找“VFY”)。
更新:查看 logcat 输出,com.example.tests.FooTest 中的代码无法找到 com.example.Foo。在 Android >= 2.0 中,这将导致 ClassNotFoundException,但在 1.6 中,验证程序会变得暴躁并拒绝整个类。
那么问题来了:为什么找不到呢?我要检查的第一件事是确保 com.example.Foo 和 com.example.tests.FooTest 出现在同一个 APK/classes.dex 文件中。您可以通过使用“dexdump”检查它们来检查这一点。
The verifier in 1.5/1.6 was pretty severe. The detailed explanation of the problem is on the lines above the exception (look for "VFY" in the logcat output).
UPDATE: looking at the logcat output, code in com.example.tests.FooTest is not able to find com.example.Foo. In Android >= 2.0 this would result in a ClassNotFoundException, but in 1.6 the verifier gets cranky and just rejects the whole class.
So the question is: why can't it find it? The first thing I'd check is to make sure both com.example.Foo and com.example.tests.FooTest appear in the same APK / classes.dex file. You can check this by examining them with "dexdump".