org.opendaylight.yangtools 9.0.7中NoClassDefFoundError问题求助
问题描述
我使用org.opendaylight.yangtools 9.0.7版本,依赖配置如下:
<dependencies> <dependency> <groupId>org.opendaylight.yangtools</groupId> <artifactId>yang-common</artifactId> <version>9.0.7</version> </dependency> <dependency> <groupId>org.opendaylight.yangtools</groupId> <artifactId>yang-model-api</artifactId> <version>9.0.7</version> </dependency> <dependency> <groupId>org.opendaylight.yangtools</groupId> <artifactId>yang-data-codec-gson</artifactId> <version>9.0.7</version> </dependency> <dependency> <groupId>org.opendaylight.yangtools</groupId> <artifactId>yang-parser-api</artifactId> <version>9.0.7</version> </dependency> <dependency> <groupId>org.opendaylight.yangtools</groupId> <artifactId>yang-parser-impl</artifactId> <version>9.0.7</version> </dependency> </dependencies>
按照官方文档描述创建reactor构建SchemaContext,代码如下:
import org.opendaylight.yangtools.yang.parser.rfc7950.reactor.RFC7950Reactors; import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor; public class MyFactory { protected CrossSourceStatementReactor.BuildAction getDefaultBuildAction() { CrossSourceStatementReactor reactor = RFC7950Reactors.vanillaReactorBuilder() .build(); return reactor.newBuild(); } }
系统偶发启动时抛出如下异常,重新部署后通常可恢复:
Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.opendaylight.yangtools.yang.parser.rfc7950.reactor.ServiceLoaderState$XPath at org.opendaylight.yangtools.yang.parser.rfc7950.reactor.RFC7950Reactors.vanillaReactorBuilder(RFC7950Reactors.java:320) ~[yang-parser-rfc7950-9.0.7.jar!/:na] at org.opendaylight.yangtools.yang.parser.rfc7950.reactor.RFC7950Reactors.vanillaReactorBuilder(RFC7950Reactors.java:315) ~[yang-parser-rfc7950-9.0.7.jar!/:na] at com.package.MyFactory.getDefaultBuildAction(MyFactory.java:9) ~[my-component-1.1.1.jar!/:na]
请问是否有获取模型的替代方法?或者该如何避免这个错误?
解决方案
一、补全缺失的显式依赖
从异常栈可以看到,出错的类属于yang-parser-rfc7950包,但你当前的依赖里只声明了yang-parser-impl,虽然它可能间接依赖前者,但偶发的类初始化失败大概率是类加载顺序混乱或依赖传递不稳定导致的。直接把这个依赖显式加到pom中:
<dependency> <groupId>org.opendaylight.yangtools</groupId> <artifactId>yang-parser-rfc7950</artifactId> <version>9.0.7</version> </dependency>
显式声明能确保该包在类加载阶段被优先解析,消除间接依赖带来的不确定性。
二、优化Reactor初始化逻辑
偶发问题常和并发初始化、类加载时机冲突有关,把Reactor改成线程安全的单例懒加载模式,确保只初始化一次:
import org.opendaylight.yangtools.yang.parser.rfc7950.reactor.RFC7950Reactors; import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor; public class MyFactory { // 用静态内部类实现JVM级别的线程安全单例 private static class ReactorHolder { private static final CrossSourceStatementReactor REACTOR = RFC7950Reactors.vanillaReactorBuilder() .build(); } protected CrossSourceStatementReactor.BuildAction getDefaultBuildAction() { return ReactorHolder.REACTOR.newBuild(); } }
这种方式会在第一次调用getDefaultBuildAction时才初始化Reactor,JVM会自动保证静态内部类的初始化线程安全,避免启动阶段的并发类加载冲突。
三、替代方案:使用SchemaContextProvider封装
如果上述方法仍无法解决问题,可以尝试使用YangTools提供的SchemaContextProvider上层封装,它内部已经处理了Reactor初始化和类加载的细节:
import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider; import org.opendaylight.yangtools.yang.parser.impl.DefaultSchemaContextProvider; import org.opendaylight.yangtools.yang.parser.repo.YangTextSchemaSource; import java.util.Collection; public class MyAlternativeFactory { public SchemaContext loadSchema(Collection<YangTextSchemaSource> sources) { SchemaContextProvider provider = new DefaultSchemaContextProvider(); return provider.getSchemaContext(sources); } }
这个封装类能简化模型加载流程,减少手动初始化Reactor带来的潜在问题。
四、额外建议
- 检查应用的类加载器配置,避免自定义类加载器导致的类加载顺序异常;
- 尝试升级到YangTools 9.x系列的最新稳定版,这类偶发的类初始化问题可能在后续小版本中已被修复。
内容的提问来源于stack exchange,提问作者Kirill Golovkin
相关产品推荐
相关产品推荐

