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

transformClassesWithFirebasePerformancePlugin gradle task results in ArrayIndexOutOfBoundsException #1556

Closed
gosr opened this issue May 13, 2020 · 15 comments

Comments

@gosr
Copy link

gosr commented May 13, 2020

  • Android Studio version: 3.6.3
implementation "com.google.firebase:firebase-messaging:20.1.6"
implementation("com.google.firebase:firebase-perf:19.0.7") {
    exclude group: 'com.google.protobuf', module: 'protobuf-lite' //Fixes Adform protobuf-java compile issue with R8
}
implementation 'com.google.firebase:firebase-analytics:17.4.0'
implementation 'com.google.firebase:firebase-crashlytics:17.0.0'

Steps to reproduce:

Run the gradle task 'transformClassesWithFirebasePerformancePluginForYourBuildFlavor'.

Output:

> Task :app:transformClassesWithFirebasePerformancePluginForYourBuildFlavor'
Can't instrument: io/ktor/client/request/forms/MultiPartFormDataContent.class
java.lang.ArrayIndexOutOfBoundsException: -1
	at java.util.ArrayList.elementData(ArrayList.java:422)
	at java.util.ArrayList.remove(ArrayList.java:499)
	at org.objectweb.asm.commons.AdviceAdapter.popValue(AdviceAdapter.java:604)
	at org.objectweb.asm.commons.AdviceAdapter.doVisitMethodInsn(AdviceAdapter.java:474)
	at org.objectweb.asm.commons.AdviceAdapter.visitMethodInsn(AdviceAdapter.java:468)
	at com.google.firebase.perf.plugin.instrumentation.InstrumentationVisitor$FirebasePerfMethodVisitor.visitMethodInsn(InstrumentationVisitor.java:358)
	at org.objectweb.asm.ClassReader.readCode(ClassReader.java:2209)
	at org.objectweb.asm.ClassReader.readMethod(ClassReader.java:1275)
	at org.objectweb.asm.ClassReader.accept(ClassReader.java:679)
	at com.google.firebase.perf.plugin.instrumentation.Instrument.instrument(Instrument.java:170)
	at com.google.firebase.perf.plugin.instrumentation.Instrument.instrumentClassesInJar(Instrument.java:117)
	at com.google.firebase.perf.plugin.FirebasePerfTransform.performTransformationFor(FirebasePerfTransform.java:563)
	at com.google.firebase.perf.plugin.FirebasePerfTransform.transformJarInputs(FirebasePerfTransform.java:445)
	at com.google.firebase.perf.plugin.FirebasePerfTransform.transform(FirebasePerfTransform.java:416)
	at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:284)
	at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:247)
	at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:106)
	at com.android.build.gradle.internal.pipeline.TransformTask.transform(TransformTask.java:242)
	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.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:104)
	at org.gradle.api.internal.project.taskfactory.IncrementalTaskInputsTaskAction.doExecute(IncrementalTaskInputsTaskAction.java:47)
	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:42)
	at org.gradle.api.internal.project.taskfactory.AbstractIncrementalTaskAction.execute(AbstractIncrementalTaskAction.java:25)
	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:28)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$3.run(ExecuteActionsTaskExecuter.java:568)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:402)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:394)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:92)
	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:553)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:536)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.access$300(ExecuteActionsTaskExecuter.java:109)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.executeWithPreviousOutputFiles(ExecuteActionsTaskExecuter.java:276)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.execute(ExecuteActionsTaskExecuter.java:265)
	at org.gradle.internal.execution.steps.ExecuteStep.lambda$execute$0(ExecuteStep.java:32)
	at java.util.Optional.map(Optional.java:215)
	at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:32)
	at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:26)
	at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:67)
	at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:36)
	at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:49)
	at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:34)
	at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:43)
	at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:73)
	at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:54)
	at org.gradle.internal.execution.steps.CatchExceptionStep.execute(CatchExceptionStep.java:34)
	at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:44)
	at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:54)
	at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:38)
	at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:49)
	at org.gradle.internal.execution.steps.CacheStep.executeWithoutCache(CacheStep.java:159)
	at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:72)
	at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:43)
	at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:44)
	at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:33)
	at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:38)
	at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:24)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:92)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$0(SkipUpToDateStep.java:85)
	at java.util.Optional.map(Optional.java:215)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:55)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:39)
	at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:76)
	at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:37)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:36)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:26)
	at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:94)
	at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:49)
	at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:79)
	at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:53)
	at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:74)
	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.lambda$execute$2(SkipEmptyWorkStep.java:78)
	at java.util.Optional.orElseGet(Optional.java:267)
	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:78)
	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:34)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:39)
	at org.gradle.internal.execution.steps.LoadExecutionStateStep.execute(LoadExecutionStateStep.java:40)
	at org.gradle.internal.execution.steps.LoadExecutionStateStep.execute(LoadExecutionStateStep.java:28)
	at org.gradle.internal.execution.impl.DefaultWorkExecutor.execute(DefaultWorkExecutor.java:33)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:192)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:184)
	at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:114)
	at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
	at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:62)
	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:416)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:406)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:102)
	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
	at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:41)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:372)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:359)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:352)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:338)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.lambda$run$0(DefaultPlanExecutor.java:127)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:191)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:182)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:124)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
	at java.lang.Thread.run(Thread.java:748)
java.lang.ClassNotFoundException: java.util.concurrent.Flow$Publisher
java.lang.ClassNotFoundException: java.util.concurrent.Flow$Publisher
java.lang.ClassNotFoundException: java.util.concurrent.Flow$Processor
java.lang.ClassNotFoundException: java.util.concurrent.Flow$Processor
java.lang.ClassNotFoundException: java.util.concurrent.Flow$Subscriber
java.lang.ClassNotFoundException: java.util.concurrent.Flow$Subscriber

@google-oss-bot
Copy link
Contributor

I found a few problems with this issue:

  • I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.
  • This issue does not seem to follow the issue template. Make sure you provide all the required information.

@ramanpreetSinghKhinda
Copy link
Contributor

ramanpreetSinghKhinda commented May 19, 2020

Initial Understanding

From the stack trace it looks like there was a problem when ASM (the library we use for bytecode instrumentation) trying to instrument the below class file:

io/ktor/client/request/forms/MultiPartFormDataContent.class

MultiPartFormDataContent is an API for Ktor which is an asynchronous Web framework for Kotlin.


Next Steps

I would have to reproduce the problem at my end to debug this further.

@eightx2 If you have a sample project where issue is always reproducible can you share that?

@ramanpreetSinghKhinda
Copy link
Contributor

After debugging further I figured out the factors that cause the issue are:

I have created a ticket with ASM Team for this - https://gitlab.ow2.org/asm/asm/issues/317904


@eightx2

Meanwhile please be assure that if the build is succeeding (which should be the case) and you are only getting this exception for io/ktor/client/request/forms/MultiPartFormDataContent.class the generated build will work as expected. It's just that we will skip this class during instrumentation.

Impact: If that class uses @AddTrace annotation we will not process it and if there is any Network call being made in that class we won't automatically capture it.

Regarding the exception, we log it as an error because it shouldn't be overlooked and may sometimes require an attention (like a fix from Firebase or Android Gradle Plugin or escalated to ASM if required).

@ramanpreetSinghKhinda
Copy link
Contributor

We have reverted back to the ASM Team with the information they requested for further debugging on their side.

Will keep this thread updated.

@ramanpreetSinghKhinda
Copy link
Contributor

ASM Team have a PR ready to fix this.

Once they rollout a new version (with this fix integrated), we'll upgrade our ASM dependency to that version and rollout a new version of Firebase Performance Plugin which should fix this issue.

Thanks for your patience :)

@jsilva05
Copy link

Hi!
This is only happening for release builds on my end. But, unfortunately, the build fails with that exception.
Is there any configuration that can be done to ignore this step if it fails until there is a new release?

@ramanpreetSinghKhinda
Copy link
Contributor

Hi @jsilva05 ,

Thanks for reaching out~

Can you please attach the full stack trace and all the gradle configurations (i.e all your build.gradle files removing any PII information). ASM might throw a similar kind of exception but the root cause could be different so we have to analyze first before providing any mitigation.

If you have a sample app on which you are able to reproduce this issue always (debug - pass and release - fails) than that would be great!


cc @yingdai3 and @alikn

@jsilva05
Copy link

Hi @ramanpreetSinghKhinda !
Thank you very much for your quick reply.
Unfortunately I don't think I can provide you those details. I'll wait for the next release and if the problem still persists I'll try to find a way to share what you asked for.

@ramanpreetSinghKhinda
Copy link
Contributor

That's completely fine @jsilva05. I'll make sure to keep this thread up to date as soon as I hear from ASM folks.

@ramanpreetSinghKhinda
Copy link
Contributor

As per the recent comment by the ASM Team, the fix from their side will go in ASM v9.0 beta which is to be released soon (at most a few weeks). We'll keep an eye on the ASM versions.

Once this is fixed from ASM side, we'll incorporate the changes in Fireperf plugin.

Note: We'll test the changes with the beta version of ASM (to confirm if this issue is fixed) however, we might wait for the stable version to come in before actually shipping the changes in Fireperf.

@ramanpreetSinghKhinda
Copy link
Contributor

ASM have released v9.0 beta. We'll test our plugin against it and update the thread.

@ramanpreetSinghKhinda
Copy link
Contributor

Hi @gosr

Just to keep the thread active, letting you know that I am still on it. Because of other priorities I am not yet able to spend time on validating this. But I'll keep posted on updates as we have them.

@ramanpreetSinghKhinda
Copy link
Contributor

Hi @gosr,

The fix have been merged to master. It will be available in the upcoming release of perf-plugin (will be out in ~1 week). You can keep an eye on https://firebase.google.com/support/release-notes/android.

Closing the thread for now but please don't hesitate to reopen if the issue persists with the new release as well.

Thanks :)

@trietbui85
Copy link

Hi @ramanpreetSinghKhinda Do you mean this issue would be fixed in com.google.firebase:firebase-perf:19.0.9?

@ramanpreetSinghKhinda
Copy link
Contributor

Hi @anticafe

The issue should be fixed in perf-plugin v1.3.2.

Release Notes.

@firebase firebase locked and limited conversation to collaborators Oct 30, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants