Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multidex incompatible class change error #67

Open
andrewemery opened this issue Sep 15, 2017 · 3 comments
Open

Multidex incompatible class change error #67

andrewemery opened this issue Sep 15, 2017 · 3 comments

Comments

@andrewemery
Copy link

Hi,

I'm working on an application that uses dexmaker-mockito:2.2.0 in its instrumentation tests. I recently crossed the dex limit so I integrated multidex to continue development. After multidex was integrated I began seeing the error below when calling Mockito.spy:

java.lang.IncompatibleClassChangeError: Class 'com.android.dx.util.ByteArrayAnnotatedOutput' does not implement interface 'com.android.dex.util.ByteOutput'
in call to 'void com.android.dex.util.ByteOutput.writeByte(int)'
(declaration of 'com.android.dex.Leb128' appears in /data/app/com.example.test-2/base.apk:classes12.dex)
at com.android.dex.Leb128.writeUnsignedLeb128(Leb128.java:140)
at com.android.dx.util.ByteArrayAnnotatedOutput.writeUleb128(ByteArrayAnnotatedOutput.java:244)
at com.android.dx.dex.file.ClassDataItem.encodeSize(ClassDataItem.java:378)
at com.android.dx.dex.file.ClassDataItem.encodeOutput(ClassDataItem.java:347)
at com.android.dx.dex.file.ClassDataItem.place0(ClassDataItem.java:328)
at com.android.dx.dex.file.OffsettedItem.place(OffsettedItem.java:242)
at com.android.dx.dex.file.MixedItemSection.placeItems(MixedItemSection.java:311)
at com.android.dx.dex.file.DexFile.toDex0(DexFile.java:541)
at com.android.dx.dex.file.DexFile.toDex(DexFile.java:214)
at com.android.dx.DexMaker.generate(DexMaker.java:324)
at com.android.dx.DexMaker.generateAndLoad(DexMaker.java:422)
at com.android.dx.stock.ProxyBuilder.buildProxyClass(ProxyBuilder.java:266)
at com.android.dx.mockito.DexmakerMockMaker.createMock(DexmakerMockMaker.java:60)
at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:35)
at org.mockito.internal.MockitoCore.mock(MockitoCore.java:63)
at org.mockito.Mockito.mock(Mockito.java:1637)
at com.example.application.test.utils.MockHelper.mock(MockHelper.java:23)
at com.example.application.arch.testmodules.TestUtilsModule.providesPhoneNumberResolver(TestUtilsModule.java:72)
at com.example.application.arch.testmodules.TestUtilsModule_ProvidesPhoneNumberResolverFactory.get(TestUtilsModule_ProvidesPhoneNumberResolverFactory.java:38)
at com.example.application.arch.testmodules.TestUtilsModule_ProvidesPhoneNumberResolverFactory.get(TestUtilsModule_ProvidesPhoneNumberResolverFactory.java:11)
at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
at com.example.application.test.exampleRootModule_MembersInjector.injectMembers(exampleRootModule_MembersInjector.java:289)
at com.example.application.test.exampleRootModule_MembersInjector.injectMembers(exampleRootModule_MembersInjector.java:38)
at com.example.application.arch.DaggerTestComponent.inject(DaggerTestComponent.java:2680)
at com.example.application.test.exampleRootModule.onInitialize(exampleRootModule.java:392)
at com.example.runner.Core.start(Core.java:213)
at com.example.runner.Runner.onStart(Runner.java:53)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1879)

The errors appears to be caused by a mismatch between com.android.dex.Leb128 and com.android.dx.util.ByteArrayAnnotatedOutput. ByteArrayAnnotatedOutput isn't included from any other library and the Mockito version is the one specified by dexmaker.

Interestingly, only some instances of Mockito.mock have the above issue. The code diverges at DexMaker:190:

File result1 = new File(dexCache, this.generateFileName());

For instances where the mock is correctly loaded, result1 exists. For instances where the mock encounters the above error, result1 does not exist.

I thought the problem might have been due to the class not being packaged in the main dex file, but adding the class to the multidex keep file didn't fix the issue.

Unfortunately, I can't provide you with a minimal working example because the exact cause of the problem is hard to nail down. However, I'm interested to get some insight into how an IncompatibleClassChangeError might occur in this scenario.

Thanks,

Andrew

@alvminvm
Copy link

I met the same problem as above.

ProxyBuilder
.forClass(clazz)
.dexCache(context.getApplicationContext().getDir("dx", 0))
.handler(this.mHandler)
.build();
java.lang.IncompatibleClassChangeError: Class 'com.android.dx.util.ByteArrayAnnotatedOutput' does not implement interface 'com.android.dex.util.ByteOutput' in call to 'void com.android.dex.util.ByteOutput.writeByte(int)' (declaration of 'java.lang.reflect.ArtMethod' appears in /system/framework/core-libart.jar)
                                                       at com.android.dex.Leb128.writeUnsignedLeb128(Leb128.java:140)
                                                       at com.android.dx.util.ByteArrayAnnotatedOutput.writeUleb128(ByteArrayAnnotatedOutput.java:244)
                                                       at com.android.dx.dex.file.ClassDataItem.encodeSize(ClassDataItem.java:378)
                                                       at com.android.dx.dex.file.ClassDataItem.encodeOutput(ClassDataItem.java:347)
                                                       at com.android.dx.dex.file.ClassDataItem.place0(ClassDataItem.java:328)
                                                       at com.android.dx.dex.file.OffsettedItem.place(OffsettedItem.java:242)
                                                       at com.android.dx.dex.file.MixedItemSection.placeItems(MixedItemSection.java:311)
                                                       at com.android.dx.dex.file.DexFile.toDex0(DexFile.java:541)
                                                       at com.android.dx.dex.file.DexFile.toDex(DexFile.java:214)
                                                       at com.android.dx.DexMaker.generate(DexMaker.java:324)
                                                       at com.android.dx.DexMaker.generateAndLoad(DexMaker.java:422)
                                                       at com.android.dx.stock.ProxyBuilder.buildProxyClass(ProxyBuilder.java:266)
                                                       at com.android.dx.stock.ProxyBuilder.build(ProxyBuilder.java:213)
                                                       at me.alzz.mvp.PresenterFactory.newPresenter(PresenterFactory.java:85)
                                                       at me.alzz.mvp.Presenter.bind(Presenter.java:62)

@TimvdLippe
Copy link
Contributor

We are facing the same issues. We have consistent failures in 2 tests, while all other tests are just fine. Both tests that exhibit this behavior are using multidex.

@ed-abe
Copy link

ed-abe commented May 24, 2019

Has there been any update on this issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants