newrelic / newrelic-java-agent

The New Relic Java agent
Apache License 2.0
202 stars 143 forks source link

Agent compatibility issue with Scala 2.13x and Java 11+ #1219

Closed tbradellis closed 1 year ago

tbradellis commented 1 year ago

Description

The agent throws exceptions when running on Java 11+ and Scala 2.13x.
Some customers report interference with reporting Transactions and custom attributes.

From local reproduction test:

2023-04-24T10:35:58,265-0700 [27147 146] com.newrelic FINE: Unable to transform class scala/concurrent/impl/Promise$Transformation
java.lang.TypeNotPresentException: Type scala/util/Try not present
    at com.newrelic.agent.deps.org.objectweb.asm.ClassWriter.getCommonSuperClass(ClassWriter.java:1041) ~[newrelic.jar:8.0.1]
    at com.newrelic.agent.deps.org.objectweb.asm.SymbolTable.addMergedType(SymbolTable.java:1202) ~[newrelic.jar:8.0.1]
    at com.newrelic.agent.deps.org.objectweb.asm.Frame.merge(Frame.java:1299) ~[newrelic.jar:8.0.1]
    at com.newrelic.agent.deps.org.objectweb.asm.Frame.merge(Frame.java:1244) ~[newrelic.jar:8.0.1]
    at com.newrelic.agent.deps.org.objectweb.asm.MethodWriter.computeAllFrames(MethodWriter.java:1611) ~[newrelic.jar:8.0.1]
    at com.newrelic.agent.deps.org.objectweb.asm.MethodWriter.visitMaxs(MethodWriter.java:1547) ~[newrelic.jar:8.0.1]
    at com.newrelic.agent.deps.org.objectweb.asm.ClassReader.readCode(ClassReader.java:2665) ~[newrelic.jar:8.0.1]
    at com.newrelic.agent.deps.org.objectweb.asm.ClassReader.readMethod(ClassReader.java:1514) ~[newrelic.jar:8.0.1]
    at com.newrelic.agent.deps.org.objectweb.asm.ClassReader.accept(ClassReader.java:744) ~[newrelic.jar:8.0.1]
    at com.newrelic.agent.deps.org.objectweb.asm.ClassReader.accept(ClassReader.java:424) ~[newrelic.jar:8.0.1]
    at com.newrelic.agent.instrumentation.custom.ScalaTraitFinalFieldTransformer.doTransform(ScalaTraitFinalFieldTransformer.java:40) ~[newrelic.jar:8.0.1]
    at com.newrelic.agent.instrumentation.custom.ScalaTraitFinalFieldTransformer.transform(ScalaTraitFinalFieldTransformer.java:20) ~[newrelic.jar:8.0.1]
    at com.newrelic.agent.instrumentation.context.InstrumentationClassTransformer.transform(InstrumentationClassTransformer.java:144) ~[newrelic.jar:8.0.1]
    at java.lang.instrument.ClassFileTransformer.transform(ClassFileTransformer.java:246) ~[?:?]
    at sun.instrument.TransformerManager.transform(TransformerManager.java:188) ~[?:?]
    at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:563) ~[?:?]
    at java.lang.ClassLoader.defineClass1(Native Method) ~[?:?]
    at java.lang.ClassLoader.defineClass(ClassLoader.java:1017) ~[?:?]
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174) ~[?:?]
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:555) ~[?:?]
    at java.net.URLClassLoader$1.run(URLClassLoader.java:458) ~[?:?]
    at java.net.URLClassLoader$1.run(URLClassLoader.java:452) ~[?:?]
    at java.security.AccessController.doPrivileged(Native Method) ~[?:?]
    at java.net.URLClassLoader.findClass(URLClassLoader.java:451) ~[?:?]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:589) ~[?:?]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:522) ~[?:?]
    at scala.concurrent.impl.Promise$.<clinit>(Promise.scala:403) ~[scala-library.jar:?]
    at scala.concurrent.impl.Promise$DefaultPromise.<init>(Promise.scala:108) ~[scala-library.jar:?]
    at scala.concurrent.Future$.fromTry(Future.scala:658) ~[scala-library.jar:?]
    at scala.concurrent.Future$.<clinit>(Future.scala:552) ~[scala-library.jar:?]
    at scala.tools.nsc.backend.jvm.GeneratedClassHandler$WritingClassHandler.postProcessUnit(GeneratedClassHandler.scala:126) ~[?:?]
    at scala.tools.nsc.backend.jvm.GeneratedClassHandler$WritingClassHandler.process(GeneratedClassHandler.scala:119) ~[?:?]
    at scala.tools.nsc.backend.jvm.CodeGen.genUnit(CodeGen.scala:68) ~[?:?]
    at scala.tools.nsc.backend.jvm.GenBCode$BCodePhase.apply(GenBCode.scala:74) ~[?:?]
    at scala.tools.nsc.Global$GlobalPhase.applyPhase(Global.scala:467) ~[?:?]
    at scala.tools.nsc.Global$GlobalPhase.run(Global.scala:414) ~[?:?]
    at scala.tools.nsc.backend.jvm.GenBCode$BCodePhase.super$run(GenBCode.scala:80) ~[?:?]
    at scala.tools.nsc.backend.jvm.GenBCode$BCodePhase.$anonfun$run$1(GenBCode.scala:80) ~[?:?]
    at scala.tools.nsc.backend.jvm.GenBCode$BCodePhase.run(GenBCode.scala:78) ~[?:?]
    at scala.tools.nsc.Global$Run.compileUnitsInternal(Global.scala:1530) ~[?:?]
    at scala.tools.nsc.Global$Run.compileUnits(Global.scala:1514) ~[?:?]
    at scala.tools.nsc.Global$Run.compileSources(Global.scala:1506) ~[?:?]
    at scala.tools.nsc.Global$Run.compile(Global.scala:1640) ~[?:?]
    at scala.tools.nsc.Driver.doCompile(Driver.scala:48) ~[?:?]
    at scala.tools.nsc.MainClass.doCompile(Main.scala:30) ~[?:?]
    at scala.tools.nsc.Driver.process(Driver.scala:68) ~[?:?]
    at scala.tools.nsc.Main.process(Main.scala) ~[?:?]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
    at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
    at sbt.internal.inc.RawCompiler.getReporter$1(RawCompiler.scala:56) ~[?:?]
    at sbt.internal.inc.RawCompiler.apply(RawCompiler.scala:77) ~[?:?]
    at sbt.internal.inc.AnalyzingCompiler$.$anonfun$compileSources$7(AnalyzingCompiler.scala:457) ~[?:?]
    at sbt.internal.inc.AnalyzingCompiler$.handleCompilationError$1(AnalyzingCompiler.scala:432) ~[?:?]
    at sbt.internal.inc.AnalyzingCompiler$.$anonfun$compileSources$5(AnalyzingCompiler.scala:453) ~[?:?]
    at sbt.internal.inc.AnalyzingCompiler$.$anonfun$compileSources$5$adapted(AnalyzingCompiler.scala:448) ~[?:?]
    at sbt.io.IO$.withTemporaryDirectory(IO.scala:490) ~[?:?]
    at sbt.io.IO$.withTemporaryDirectory(IO.scala:500) ~[?:?]
    at sbt.internal.inc.AnalyzingCompiler$.$anonfun$compileSources$2(AnalyzingCompiler.scala:448) ~[?:?]
    at sbt.internal.inc.AnalyzingCompiler$.$anonfun$compileSources$2$adapted(AnalyzingCompiler.scala:440) ~[?:?]
    at sbt.io.IO$.withTemporaryDirectory(IO.scala:490) ~[?:?]
    at sbt.io.IO$.withTemporaryDirectory(IO.scala:500) ~[?:?]
    at sbt.internal.inc.AnalyzingCompiler$.compileSources(AnalyzingCompiler.scala:440) ~[?:?]
    at sbt.internal.inc.ZincComponentCompiler.$anonfun$compileAndInstall$3(ZincComponentCompiler.scala:275) ~[?:?]
    at sbt.internal.inc.ZincComponentCompiler.$anonfun$compileAndInstall$3$adapted(ZincComponentCompiler.scala:257) ~[?:?]
    at sbt.io.IO$.withTemporaryDirectory(IO.scala:490) ~[?:?]
    at sbt.io.IO$.withTemporaryDirectory(IO.scala:500) ~[?:?]
    at sbt.internal.inc.ZincComponentCompiler.$anonfun$compileAndInstall$2(ZincComponentCompiler.scala:257) ~[?:?]
    at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23) ~[scala-library.jar:?]
    at sbt.internal.util.BufferedLogger.bufferQuietly(BufferedLogger.scala:159) ~[?:?]
    at sbt.internal.inc.ZincComponentCompiler.$anonfun$compileAndInstall$1(ZincComponentCompiler.scala:257) ~[?:?]
    at sbt.internal.inc.ZincComponentCompiler.$anonfun$compileAndInstall$1$adapted(ZincComponentCompiler.scala:254) ~[?:?]
    at sbt.io.IO$.withTemporaryDirectory(IO.scala:490) ~[?:?]
    at sbt.io.IO$.withTemporaryDirectory(IO.scala:500) ~[?:?]
    at sbt.internal.inc.ZincComponentCompiler.compileAndInstall(ZincComponentCompiler.scala:254) ~[?:?]
    at sbt.internal.inc.ZincComponentCompiler.$anonfun$compiledBridgeJar$1(ZincComponentCompiler.scala:222) ~[?:?]
    at sbt.internal.inc.IfMissing$Define.run(IfMissing.scala:19) ~[?:?]
    at sbt.internal.inc.ZincComponentManager.createAndCache$1(ZincComponentManager.scala:51) ~[?:?]
    at sbt.internal.inc.ZincComponentManager.$anonfun$files$3(ZincComponentManager.scala:62) ~[?:?]
    at sbt.internal.inc.ZincComponentManager.getOrElse$1(ZincComponentManager.scala:43) ~[?:?]
    at sbt.internal.inc.ZincComponentManager.$anonfun$files$2(ZincComponentManager.scala:62) ~[?:?]
    at sbt.internal.inc.ZincComponentManager$$anon$1.call(ZincComponentManager.scala:91) ~[?:?]
    at xsbt.boot.Locks$GlobalLock.withChannel$1(Locks.scala:113) ~[?:?]
    at xsbt.boot.Locks$GlobalLock.withChannelRetries$1(Locks.scala:91) ~[?:?]
    at xsbt.boot.Locks$GlobalLock.$anonfun$withFileLock$1(Locks.scala:119) ~[?:?]
    at xsbt.boot.Using$.withResource(Using.scala:12) ~[?:?]
    at xsbt.boot.Using$.apply(Using.scala:9) ~[?:?]
    at xsbt.boot.Locks$GlobalLock.withFileLock(Locks.scala:119) ~[?:?]
    at xsbt.boot.Locks$GlobalLock.ignoringDeadlockAvoided(Locks.scala:71) ~[?:?]
    at xsbt.boot.Locks$GlobalLock.withLock(Locks.scala:59) ~[?:?]
    at xsbt.boot.Locks$.apply0(Locks.scala:47) ~[?:?]
    at xsbt.boot.Locks$.apply(Locks.scala:36) ~[?:?]
    at sbt.internal.inc.ZincComponentManager.lock(ZincComponentManager.scala:91) ~[?:?]
    at sbt.internal.inc.ZincComponentManager.$anonfun$lockSecondaryCache$1(ZincComponentManager.scala:88) ~[?:?]
    at scala.Option.map(Option.scala:230) ~[scala-library.jar:?]
    at sbt.internal.inc.ZincComponentManager.lockSecondaryCache(ZincComponentManager.scala:88) ~[?:?]
    at sbt.internal.inc.ZincComponentManager.fromSecondary$1(ZincComponentManager.scala:60) ~[?:?]
    at sbt.internal.inc.ZincComponentManager.$anonfun$files$6(ZincComponentManager.scala:66) ~[?:?]
    at sbt.internal.inc.ZincComponentManager.getOrElse$1(ZincComponentManager.scala:43) ~[?:?]
    at sbt.internal.inc.ZincComponentManager.$anonfun$files$5(ZincComponentManager.scala:66) ~[?:?]
    at sbt.internal.inc.ZincComponentManager$$anon$1.call(ZincComponentManager.scala:91) ~[?:?]
    at xsbt.boot.Locks$GlobalLock.withChannel$1(Locks.scala:113) ~[?:?]
    at xsbt.boot.Locks$GlobalLock.withChannelRetries$1(Locks.scala:91) ~[?:?]
    at xsbt.boot.Locks$GlobalLock.$anonfun$withFileLock$1(Locks.scala:119) ~[?:?]
    at xsbt.boot.Using$.withResource(Using.scala:12) ~[?:?]
    at xsbt.boot.Using$.apply(Using.scala:9) ~[?:?]
    at xsbt.boot.Locks$GlobalLock.withFileLock(Locks.scala:119) ~[?:?]
    at xsbt.boot.Locks$GlobalLock.ignoringDeadlockAvoided(Locks.scala:71) ~[?:?]
    at xsbt.boot.Locks$GlobalLock.withLock(Locks.scala:59) ~[?:?]
    at xsbt.boot.Locks$.apply0(Locks.scala:47) ~[?:?]
    at xsbt.boot.Locks$.apply(Locks.scala:36) ~[?:?]
    at sbt.internal.inc.ZincComponentManager.lock(ZincComponentManager.scala:91) ~[?:?]
    at sbt.internal.inc.ZincComponentManager.lockLocalCache(ZincComponentManager.scala:84) ~[?:?]
    at sbt.internal.inc.ZincComponentManager.files(ZincComponentManager.scala:66) ~[?:?]
    at sbt.internal.inc.ZincComponentManager.file(ZincComponentManager.scala:72) ~[?:?]
    at sbt.internal.inc.ZincComponentCompiler.compiledBridgeJar(ZincComponentCompiler.scala:222) ~[?:?]
    at sbt.internal.inc.ZincComponentCompiler$ZincCompilerBridgeProvider.compiledBridge(ZincComponentCompiler.scala:63) ~[?:?]
    at sbt.internal.inc.ZincComponentCompiler$ZincCompilerBridgeProvider.fetchCompiledBridge(ZincComponentCompiler.scala:70) ~[?:?]
    at sbt.internal.inc.AnalyzingCompiler.getDualLoader(AnalyzingCompiler.scala:354) ~[?:?]
    at sbt.internal.inc.AnalyzingCompiler.getCompilerLoader(AnalyzingCompiler.scala:343) ~[?:?]
    at sbt.internal.inc.AnalyzingCompiler.compile(AnalyzingCompiler.scala:87) ~[?:?]
    at sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$7(MixedAnalyzingCompiler.scala:193) ~[?:?]
    at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23) ~[scala-library.jar:?]
    at sbt.internal.inc.MixedAnalyzingCompiler.timed(MixedAnalyzingCompiler.scala:248) ~[?:?]
    at sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$4(MixedAnalyzingCompiler.scala:183) ~[?:?]
    at sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$4$adapted(MixedAnalyzingCompiler.scala:163) ~[?:?]
    at sbt.internal.inc.JarUtils$.withPreviousJar(JarUtils.scala:239) ~[?:?]
    at sbt.internal.inc.MixedAnalyzingCompiler.compileScala$1(MixedAnalyzingCompiler.scala:163) ~[?:?]
    at sbt.internal.inc.MixedAnalyzingCompiler.compile(MixedAnalyzingCompiler.scala:211) ~[?:?]
    at sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileInternal$1(IncrementalCompilerImpl.scala:534) ~[?:?]
    at sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileInternal$1$adapted(IncrementalCompilerImpl.scala:534) ~[?:?]
    at sbt.internal.inc.Incremental$.$anonfun$apply$5(Incremental.scala:179) ~[?:?]
    at sbt.internal.inc.Incremental$.$anonfun$apply$5$adapted(Incremental.scala:177) ~[?:?]
    at sbt.internal.inc.Incremental$$anon$2.run(Incremental.scala:463) ~[?:?]
    at sbt.internal.inc.IncrementalCommon$CycleState.next(IncrementalCommon.scala:116) ~[?:?]
    at sbt.internal.inc.IncrementalCommon$$anon$1.next(IncrementalCommon.scala:56) ~[?:?]
    at sbt.internal.inc.IncrementalCommon$$anon$1.next(IncrementalCommon.scala:52) ~[?:?]
    at sbt.internal.inc.IncrementalCommon.cycle(IncrementalCommon.scala:263) ~[?:?]
    at sbt.internal.inc.Incremental$.$anonfun$incrementalCompile$8(Incremental.scala:418) ~[?:?]
    at sbt.internal.inc.Incremental$.withClassfileManager(Incremental.scala:506) ~[?:?]
    at sbt.internal.inc.Incremental$.incrementalCompile(Incremental.scala:405) ~[?:?]
    at sbt.internal.inc.Incremental$.apply(Incremental.scala:171) ~[?:?]
    at sbt.internal.inc.IncrementalCompilerImpl.compileInternal(IncrementalCompilerImpl.scala:534) ~[?:?]
    at sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileIncrementally$1(IncrementalCompilerImpl.scala:488) ~[?:?]
    at sbt.internal.inc.IncrementalCompilerImpl.handleCompilationError(IncrementalCompilerImpl.scala:332) ~[?:?]
    at sbt.internal.inc.IncrementalCompilerImpl.compileIncrementally(IncrementalCompilerImpl.scala:425) ~[?:?]
    at sbt.internal.inc.IncrementalCompilerImpl.compile(IncrementalCompilerImpl.scala:137) ~[?:?]
    at sbt.Defaults$.compileIncrementalTaskImpl(Defaults.scala:2363) ~[?:?]
    at sbt.Defaults$.$anonfun$compileIncrementalTask$2(Defaults.scala:2313) ~[?:?]
    at sbt.internal.server.BspCompileTask$.$anonfun$compute$1(BspCompileTask.scala:30) ~[?:?]
    at sbt.internal.io.Retry$.apply(Retry.scala:46) ~[?:?]
    at sbt.internal.io.Retry$.apply(Retry.scala:28) ~[?:?]
    at sbt.internal.io.Retry$.apply(Retry.scala:23) ~[?:?]
    at sbt.internal.server.BspCompileTask$.compute(BspCompileTask.scala:30) ~[?:?]
    at sbt.Defaults$.$anonfun$compileIncrementalTask$1(Defaults.scala:2311) ~[?:?]
    at scala.Function1.$anonfun$compose$1(Function1.scala:49) ~[scala-library.jar:?]
    at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:62) ~[collections_2.12-1.7.2.jar:1.7.2]
    at sbt.std.Transform$$anon$4.work(Transform.scala:68) ~[task-system_2.12-1.7.2.jar:1.7.2]
    at sbt.Execute.$anonfun$submit$2(Execute.scala:282) ~[tasks_2.12-1.7.2.jar:1.7.2]
    at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:23) ~[util-control_2.12-1.7.2.jar:1.7.2]
    at sbt.Execute.work(Execute.scala:291) ~[tasks_2.12-1.7.2.jar:1.7.2]
    at sbt.Execute.$anonfun$submit$1(Execute.scala:282) ~[tasks_2.12-1.7.2.jar:1.7.2]
    at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:265) ~[tasks_2.12-1.7.2.jar:1.7.2]
    at sbt.CompletionService$$anon$2.call(CompletionService.scala:64) [tasks_2.12-1.7.2.jar:1.7.2]
    at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
    at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
    at java.lang.Thread.run(Thread.java:829) [?:?]
Caused by: java.lang.ClassNotFoundException: scala.util.Try
    at java.net.URLClassLoader.findClass(URLClassLoader.java:476) ~[?:?]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:589) ~[?:?]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:522) ~[?:?]
    at java.lang.Class.forName0(Native Method) ~[?:?]
    at java.lang.Class.forName(Class.java:398) ~[?:?]
    at com.newrelic.agent.deps.org.objectweb.asm.ClassWriter.getCommonSuperClass(ClassWriter.java:1039) ~[newrelic.jar:8.0.1]
    ... 170 more

Expected Behavior

No exceptions thrown and agent otherwise reports all expected transactions and attributes.

Steps to Reproduce

This can be reproduced: Quick and easy: pull this app down and setup to run with the agent as described in the readme. https://github.com/newrelic/newrelic-java-examples/tree/main/newrelic-java-agent/scala/segment-api-synchronous Update sbt build and .jvmoptions to the versions given below. Run the app.

This app uses the scala api (which essentially just calls the java agent api). However, you can change the example app to use the direct Java API calls like so:


  @Trace
  def trace1: Unit ={
    val i = 1
    val j = 2
    println(i + j)
  }

  @Trace
  def trace2: Unit ={
    NewRelic.addCustomParameter("key", "value")
    val i = 1
    val j = 2
    println(i + j)
  }

  @Trace(dispatcher=true)
  def startTransaction: Unit ={
    trace1
    trace2
  }

  startTransaction

(then update the libraryDependencies to accomodate)

Your Environment

Java 11 zulu hotspot. Scala 2.13.10.

workato-integration[bot] commented 1 year ago

https://issues.newrelic.com/browse/NEWRELIC-8253

workato-integration[bot] commented 1 year ago

Jira CommentId: 210443 Commented by csanchezfabres:

Scala; [1000 accounts|https://onenr.io/0KQXpP8E0Qa] , and only [261 |https://docs.google.com/spreadsheets/d/17JbsubO5x5MGXNQaY9vzVrMFyKneJMlAXAXxipETX7g/edit#gid=0]are using scala 2.13 and java 11+

Potentially, upgrading to Java 17 solves this problem

workato-integration[bot] commented 1 year ago

Jira CommentId: 210443 Commented by csanchezfabres:

Scala; [1000 accounts|https://onenr.io/0KQXpP8E0Qa] , and only [261 |https://docs.google.com/spreadsheets/d/17JbsubO5x5MGXNQaY9vzVrMFyKneJMlAXAXxipETX7g/edit#gid=0]are using scala 2.13 and java 11+

Potentially, upgrading to Java 17 solves this problem (to be confirmed). Decision pending unless there's clarity on path forward

workato-integration[bot] commented 1 year ago

Jira CommentId: 213835 Commented by bellis:

Can confirm that we still see this exception on Java 17 and 20.

kford-newrelic commented 1 year ago

Will not be able to take this up in the coming Jul-Sep quarter; will consider this issue for the following quarter.

jbedell-newrelic commented 1 year ago

PR: https://github.com/newrelic/newrelic-java-agent/pull/1528