org.postgresql.jdbc.PgPreparedStatement Class versions V1_5 or less must use F_NEW frames when using kanela agent
Closed this issue · 3 comments
I'm trying to implement kamon tracing for an akka application written in Scala. The application is backed by a postgres database. and I'm running into issues with asm from what i can tell.
as far as I can tell I'm on the latest possible versions of the relevant libraries while maintaining compatibility but maybe I'm making a mistake somewhere. it seems like the failure is occurring in a transitive dependency on ASM
relevant library versions:
kamon version 2.7.0
kanela-agent: 1.0.18
akka: 2.6.19
jdbc adatpter: net.postgis:postgis-jdbc:2.5.0
doobie 0.13.4
hikariCP 5.0.3
typesafe slick 3.3.2
my code is extremely simply and based on the kamon docs for installing on a plain application calling
import kamon.Kamon
// this is a mixing for my main App
class App extends Init {
// start app
}
trait Init {
Kamon.init()
// start up akka server
// start up grpc server
// ... etc
}
build tool is bazel 5.4.0
If I remove Kamon.init()
the application runs perfectly normal.
error stack trace.
[slick.db-1] ERROR 2024-01-18 14:33:00 Logger : Error => org.postgresql.jdbc.PgPreparedStatement with message Class versions V1_5 or less must use F_NEW frames.. Class loader: jdk.internal.loader.ClassLoaders$AppClassLoader@67424e82: java.lang.IllegalArgumentException: Class versions V1_5 or less must use F_NEW frames.
at kanela.agent.libs.net.bytebuddy.jar.asm.MethodWriter.visitFrame(MethodWriter.java:780)
at kanela.agent.libs.net.bytebuddy.jar.asm.MethodVisitor.visitFrame(MethodVisitor.java:312)
at kanela.agent.libs.net.bytebuddy.utility.visitor.ExceptionTableSensitiveMethodVisitor.onVisitFrame(ExceptionTableSensitiveMethodVisitor.java:76)
at kanela.agent.libs.net.bytebuddy.utility.visitor.ExceptionTableSensitiveMethodVisitor.visitFrame(ExceptionTableSensitiveMethodVisitor.java:63)
at kanela.agent.libs.net.bytebuddy.jar.asm.MethodVisitor.visitFrame(MethodVisitor.java:312)
at kanela.agent.libs.net.bytebuddy.utility.visitor.StackAwareMethodVisitor.visitFrame(StackAwareMethodVisitor.java:478)
at kanela.agent.api.advisor.AdviceExceptionHandler$1.apply(AdviceExceptionHandler.java:72)
at kanela.agent.libs.net.bytebuddy.asm.Advice$Dispatcher$SuppressionHandler$Suppressing$Bound.onEnd(Advice.java:8014)
at kanela.agent.libs.net.bytebuddy.asm.Advice$Dispatcher$Inlining$CodeTranslationVisitor.visitEnd(Advice.java:10287)
at kanela.agent.libs.net.bytebuddy.jar.asm.MethodVisitor.visitEnd(MethodVisitor.java:796)
at kanela.agent.libs.net.bytebuddy.jar.asm.ClassReader.readMethod(ClassReader.java:1518)
at kanela.agent.libs.net.bytebuddy.jar.asm.ClassReader.accept(ClassReader.java:744)
at kanela.agent.libs.net.bytebuddy.jar.asm.ClassReader.accept(ClassReader.java:424)
at kanela.agent.libs.net.bytebuddy.asm.Advice$Dispatcher$Inlining$Resolved$AdviceMethodInliner.apply(Advice.java:9225)
at kanela.agent.libs.net.bytebuddy.asm.Advice$AdviceVisitor.onAfterExceptionTable(Advice.java:11514)
at kanela.agent.libs.net.bytebuddy.utility.visitor.ExceptionTableSensitiveMethodVisitor.considerEndOfExceptionTable(ExceptionTableSensitiveMethodVisitor.java:49)
at kanela.agent.libs.net.bytebuddy.utility.visitor.ExceptionTableSensitiveMethodVisitor.visitLabel(ExceptionTableSensitiveMethodVisitor.java:81)
at kanela.agent.libs.net.bytebuddy.jar.asm.MethodVisitor.visitLabel(MethodVisitor.java:501)
at kanela.agent.libs.net.bytebuddy.utility.visitor.ExceptionTableSensitiveMethodVisitor.onVisitLabel(ExceptionTableSensitiveMethodVisitor.java:92)
at kanela.agent.libs.net.bytebuddy.utility.visitor.ExceptionTableSensitiveMethodVisitor.visitLabel(ExceptionTableSensitiveMethodVisitor.java:82)
at kanela.agent.libs.net.bytebuddy.utility.visitor.LineNumberPrependingMethodVisitor.onAfterExceptionTable(LineNumberPrependingMethodVisitor.java:50)
at kanela.agent.libs.net.bytebuddy.utility.visitor.ExceptionTableSensitiveMethodVisitor.considerEndOfExceptionTable(ExceptionTableSensitiveMethodVisitor.java:49)
at kanela.agent.libs.net.bytebuddy.utility.visitor.ExceptionTableSensitiveMethodVisitor.visitLabel(ExceptionTableSensitiveMethodVisitor.java:81)
at kanela.agent.libs.net.bytebuddy.jar.asm.MethodVisitor.visitLabel(MethodVisitor.java:501)
at kanela.agent.libs.net.bytebuddy.utility.visitor.StackAwareMethodVisitor.visitLabel(StackAwareMethodVisitor.java:411)
at kanela.agent.libs.net.bytebuddy.asm.Advice$Dispatcher$SuppressionHandler$Suppressing$Bound.onStart(Advice.java:8001)
at kanela.agent.libs.net.bytebuddy.asm.Advice$Dispatcher$Inlining$CodeTranslationVisitor.visitCode(Advice.java:10204)
at kanela.agent.libs.net.bytebuddy.jar.asm.MethodVisitor.visitCode(MethodVisitor.java:242)
at kanela.agent.libs.net.bytebuddy.jar.asm.ClassReader.readMethod(ClassReader.java:1513)
at kanela.agent.libs.net.bytebuddy.jar.asm.ClassReader.accept(ClassReader.java:744)
at kanela.agent.libs.net.bytebuddy.jar.asm.ClassReader.accept(ClassReader.java:424)
at kanela.agent.libs.net.bytebuddy.asm.Advice$Dispatcher$Inlining$Resolved$AdviceMethodInliner.apply(Advice.java:9225)
at kanela.agent.libs.net.bytebuddy.asm.Advice$AdviceVisitor.onAfterExceptionTable(Advice.java:11514)
at kanela.agent.libs.net.bytebuddy.utility.visitor.ExceptionTableSensitiveMethodVisitor.considerEndOfExceptionTable(ExceptionTableSensitiveMethodVisitor.java:49)
at kanela.agent.libs.net.bytebuddy.utility.visitor.ExceptionTableSensitiveMethodVisitor.visitLabel(ExceptionTableSensitiveMethodVisitor.java:81)
at kanela.agent.libs.net.bytebuddy.jar.asm.Label.accept(Label.java:362)
at kanela.agent.libs.net.bytebuddy.jar.asm.ClassReader.readCode(ClassReader.java:2058)
at kanela.agent.libs.net.bytebuddy.jar.asm.ClassReader.readMethod(ClassReader.java:1514)
at kanela.agent.libs.net.bytebuddy.jar.asm.ClassReader.accept(ClassReader.java:744)
at kanela.agent.libs.net.bytebuddy.jar.asm.ClassReader.accept(ClassReader.java:424)
at kanela.agent.libs.net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForInlining.create(TypeWriter.java:4014)
at kanela.agent.libs.net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:2224)
at kanela.agent.libs.net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$UsingTypeWriter.make(DynamicType.java:4057)
at kanela.agent.libs.net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.doTransform(AgentBuilder.java:12225)
at kanela.agent.libs.net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.transform(AgentBuilder.java:12160)
at kanela.agent.libs.net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.access$1800(AgentBuilder.java:11869)
at kanela.agent.libs.net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer$Java9CapableVmDispatcher.run(AgentBuilder.java:12647)
at kanela.agent.libs.net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer$Java9CapableVmDispatcher.run(AgentBuilder.java:12579)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at kanela.agent.libs.net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.doPrivileged(AgentBuilder.java)
at kanela.agent.libs.net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.transform(AgentBuilder.java:12103)
at kanela.agent.libs.net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer$ByteBuddy$ModuleSupport.transform(Unknown Source)
at java.instrument/sun.instrument.TransformerManager.transform(TransformerManager.java:188)
at java.instrument/sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:563)
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1017)
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:800)
at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:698)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:621)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:579)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
at org.postgresql.jdbc.PgConnection.prepareStatement(PgConnection.java:1240)
at org.postgresql.jdbc.PgConnection.prepareStatement(PgConnection.java:1605)
at org.postgresql.jdbc.PgConnection.prepareStatement(PgConnection.java:410)
at com.zaxxer.hikari.pool.ProxyConnection.prepareStatement(ProxyConnection.java:337)
at com.zaxxer.hikari.pool.HikariProxyConnection.prepareStatement(HikariProxyConnection.java)
at slick.jdbc.JdbcBackend$SessionDef.prepareStatement(JdbcBackend.scala:375)
at slick.jdbc.JdbcBackend$SessionDef.prepareStatement$(JdbcBackend.scala:365)
at slick.jdbc.JdbcBackend$BaseSession.prepareStatement(JdbcBackend.scala:489)
at slick.jdbc.StatementInvoker.results(StatementInvoker.scala:33)
at slick.jdbc.StatementInvoker.iteratorTo(StatementInvoker.scala:22)
at slick.jdbc.Invoker.foreach(Invoker.scala:47)
at slick.jdbc.Invoker.foreach$(Invoker.scala:46)
at slick.jdbc.StatementInvoker.foreach(StatementInvoker.scala:16)
at slick.jdbc.StreamingInvokerAction.run(StreamingInvokerAction.scala:22)
at slick.jdbc.StreamingInvokerAction.run$(StreamingInvokerAction.scala:20)
at slick.jdbc.JdbcActionComponent$QueryActionExtensionMethodsImpl$$anon$2.run(JdbcActionComponent.scala:214)
at slick.jdbc.JdbcActionComponent$QueryActionExtensionMethodsImpl$$anon$2.run(JdbcActionComponent.scala:214)
at slick.basic.BasicBackend$DatabaseDef$$anon$3.liftedTree1$1(BasicBackend.scala:276)
at slick.basic.BasicBackend$DatabaseDef$$anon$3.run(BasicBackend.scala:276)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
I am a novice when it comes to the low level realm of JVM bytecode but I noticed that the asm
code compiles to byte code major version 49
javap -v -cp ~/kanela-agent-1.0.18.jar kanela.agent.libs.net.bytebuddy.jar.asm.MethodWriter
...
Classfile jar:file:///Users/travis.perdue/Downloads/kanela-agent-1.0.18.jar!/kanela/agent/libs/net/bytebuddy/jar/asm/MethodWriter.class
Last modified Feb 1, 1980; size 35153 bytes
MD5 checksum 09a2ccbb914420266563caded17ede51
Compiled from "MethodWriter.java"
final class kanela.agent.libs.net.bytebuddy.jar.asm.MethodWriter extends kanela.agent.libs.net.bytebuddy.jar.asm.MethodVisitor
minor version: 0
major version: 49
the hikariCP code compiles to major version 52 of the bytecode
javap -v -cp ~/HikariCP-5.0.1.jar com.zaxxer.hikari.pool.HikariProxyConnection
Classfile jar:file:///Users/travis.perdue/Downloads/HikariCP-5.0.1.jar!/com/zaxxer/hikari/pool/HikariProxyConnection.class
Last modified Jan 9, 2022; size 7706 bytes
MD5 checksum d3ba403b863a2284b165d785193b5821
Compiled from "HikariProxyConnection.java"
public final class com.zaxxer.hikari.pool.HikariProxyConnection extends com.zaxxer.hikari.pool.ProxyConnection implements java.sql.Wrapper,java.lang.AutoCloseable,java.sql.Connection
minor version: 0
major version: 52
Is this a red herring or could there be an issue with the asm code that compiles down to version 49 trying to manipulate version 52 byecode cause this sort of error?
I've traced the error code back to this block of code
I am going to close this as I discovered the source of the problem. I'll post the answer here as an artifact in case anyone else runs into the problem.
The org I was working with labeled the base docker image as jdk_slim
but it was actually a jre image. The kanela agent requires access to JVM modules that are only present in the full JDK (note that I haven't tested this with the slim JDK). The module in question for this error was jdk.attach
. This dependency is found in the java docs on the byte-buddy install()
method. When I switched the base image to the full jdk the errors went away.