OpenTelemetry Java手动埋点报错:Marshaler类NoClassDefFoundError
问题描述
按照OpenTelemetry官方Java手动埋点手册创建SdkTracerProvider时,始终触发NoClassDefFoundError异常,提示缺失io.opentelemetry.exporter.internal.marshal.Marshaler类,该类属于opentelemetry-exporter-otlp-common包。
代码示例
Resource resource = Resource.getDefault() .merge(Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, "logical-service-name"))); SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder() .addSpanProcessor(BatchSpanProcessor.builder(OtlpGrpcSpanExporter.builder().build()).build()) .setResource(resource) .build();
异常触发位置
OtlpGrpcSpanExporter.builder()
已在项目中配置包含源码和类文件的新库,目标模块也添加了依赖,且能正常使用其他OpenTelemetry类(如io.opentelemetry.sdk.resources.Resource),但仍出现该异常。
堆栈信息
java.lang.NoClassDefFoundError: io/opentelemetry/exporter/internal/marshal/Marshaler at ---Calling class--- at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124) at org.testng.internal.Invoker.invokeMethod(Invoker.java:583) at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:719) at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:989) at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125) at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109) at org.testng.TestRunner.privateRun(TestRunner.java:648) at org.testng.TestRunner.run(TestRunner.java:505) at org.testng.SuiteRunner.runTest(SuiteRunner.java:455) at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450) at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415) at org.testng.SuiteRunner.run(SuiteRunner.java:364) at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84) at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208) at org.testng.TestNG.runSuitesLocally(TestNG.java:1137) at org.testng.TestNG.runSuites(TestNG.java:1049) at org.testng.TestNG.run(TestNG.java:1017) at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66) at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:109) Caused by: java.lang.ClassNotFoundException: io.opentelemetry.exporter.internal.marshal.Marshaler at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ... 25 more
解决方案
1. 确保依赖版本一致且完整
Marshaler是opentelemetry-exporter-otlp-common的内部类,必须确保该依赖与项目中其他OpenTelemetry组件(如opentelemetry-sdk、opentelemetry-exporter-otlp-grpc)版本完全一致。通过依赖管理工具(Maven/Gradle)显式引入该包:
Maven 配置
<dependency> <groupId>io.opentelemetry</groupId> <artifactId>opentelemetry-exporter-otlp-common</artifactId> <version><!-- 替换为你的OpenTelemetry版本 --></version> </dependency>
Gradle 配置
implementation 'io.opentelemetry:opentelemetry-exporter-otlp-common:${your-otel-version}'
2. 排查依赖冲突
项目中若存在不同版本的OpenTelemetry依赖,会导致类加载异常。用以下命令检查依赖树,找出版本不一致的依赖并排除:
- Maven 查看依赖树:
mvn dependency:tree
- Gradle 查看依赖树:
./gradlew dependencies
找到冲突的依赖后,在依赖声明中添加排除规则,例如Maven:
<dependency> <groupId>xxx</groupId> <artifactId>xxx</artifactId> <exclusions> <exclusion> <groupId>io.opentelemetry</groupId> <artifactId>opentelemetry-exporter-otlp-common</artifactId> </exclusion> </exclusions> </dependency>
3. 清理缓存并重新构建
清理本地依赖缓存,确保拉取最新的依赖文件:
- Maven:
mvn clean install -U
- Gradle:
./gradlew clean build --refresh-dependencies
同时重启IDE,让IDE重新加载最新的类文件,避免缓存导致的问题。
4. 放弃手动添加库文件
手动添加库文件容易遗漏依赖或导致版本不匹配,建议完全通过依赖管理工具引入所有OpenTelemetry组件,不要混合手动添加和自动化依赖管理。
内容的提问来源于stack exchange,提问作者AKH
相关产品推荐
相关产品推荐

