You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OSGi应用配置Logback DBAppender时出现ClassNotFoundException问题求助

在OSGi应用中配置DBAppender时遇到ClassNotFoundException错误

尝试在OSGi应用中配置DBAppender,但持续遇到以下错误:

10:12:59,285 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [DB]
10:12:59,285 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.classic.db.DBAppender]
10:12:59,285 |-ERROR in ch.qos.logback.core.model.processor.AppenderModelHandler - Could not create an Appender of type [ch.qos.logback.classic.db.DBAppender]. ch.qos.logback.core.util.DynamicClassLoadingException: Failed to instantiate type ch.qos.logback.classic.db.DBAppender
        at ch.qos.logback.core.util.DynamicClassLoadingException: Failed to instantiate type ch.qos.logback.classic.db.DBAppender
        at      at ch.qos.logback.core.util.OptionHelper.instantiateByClassNameAndParameter(OptionHelper.java:69)
        at      at ch.qos.logback.core.util.OptionHelper.instantiateByClassName(OptionHelper.java:44)
        at      at ch.qos.logback.core.util.OptionHelper.instantiateByClassName(OptionHelper.java:33)
        at      at ch.qos.logback.core.model.processor.AppenderModelHandler.handle(AppenderModelHandler.java:67)
        at      at ch.qos.logback.core.model.processor.DefaultProcessor.secondPhaseTraverse(DefaultProcessor.java:241)
        at      at ch.qos.logback.core.model.processor.DefaultProcessor.secondPhaseTraverse(DefaultProcessor.java:253)
        at      at ch.qos.logback.core.model.processor.DefaultProcessor.traversalLoop(DefaultProcessor.java:90)
        at      at ch.qos.logback.core.model.processor.DefaultProcessor.process(DefaultProcessor.java:106)
        at      at ch.qos.logback.core.joran.GenericXMLConfigurator.processModel(GenericXMLConfigurator.java:200)
        at      at ch.qos.logback.core.joran.GenericXMLConfigurator.doConfigure(GenericXMLConfigurator.java:166)
        at      at ch.qos.logback.core.joran.GenericXMLConfigurator.doConfigure(GenericXMLConfigurator.java:122)
        at      at ch.qos.logback.core.joran.GenericXMLConfigurator.doConfigure(GenericXMLConfigurator.java:65)
        at      at ch.qos.logback.classic.util.DefaultJoranConfigurator.configureByResource(DefaultJoranConfigurator.java:53)
        at      at ch.qos.logback.classic.util.DefaultJoranConfigurator.configure(DefaultJoranConfigurator.java:34)
        at      at ch.qos.logback.classic.util.ContextInitializer.autoConfig(ContextInitializer.java:98)
        at      at ch.qos.logback.classic.util.ContextInitializer.autoConfig(ContextInitializer.java:77)
        at      at ch.qos.logback.classic.spi.LogbackServiceProvider.initializeLoggerContext(LogbackServiceProvider.java:50)
        at      at ch.qos.logback.classic.spi.LogbackServiceProvider.initialize(LogbackServiceProvider.java:41)
        at      at org.slf4j.LoggerFactory.bind(LoggerFactory.java:183)
        at      at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:170)
        at      at org.slf4j.LoggerFactory.getProvider(LoggerFactory.java:453)
        at      at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:439)
        at      at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:388)
        at      at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:414)
        at      at prodist.robot.equinox.Application.<clinit>(Application.java:37)
        at      at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at      at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at      at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at      at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at      at java.lang.Class.newInstance(Class.java:442)
        at      at org.eclipse.equinox.internal.ds.model.ServiceComponent.createInstance(ServiceComponent.java:493)
        at      at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.createInstance(ServiceComponentProp.java:270)
        at      at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.build(ServiceComponentProp.java:331)
        at      at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponent(InstanceProcess.java:620)
        at      at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponents(InstanceProcess.java:197)
        at      at org.eclipse.equinox.internal.ds.Resolver.buildNewlySatisfied(Resolver.java:473)
        at      at org.eclipse.equinox.internal.ds.Resolver.enableComponents(Resolver.java:217)
        at      at org.eclipse.equinox.internal.ds.SCRManager.performWork(SCRManager.java:816)
        at      at org.eclipse.equinox.internal.ds.SCRManager$QueuedJob.dispatch(SCRManager.java:783)
        at      at org.eclipse.equinox.internal.ds.WorkThread.run(WorkThread.java:89)
        at      at org.eclipse.equinox.internal.util.impl.tpt.threadpool.Executor.run(Executor.java:70)
Caused by: java.lang.ClassNotFoundException: ch.qos.logback.classic.db.DBAppender cannot be found by ch.qos.logback.classic_1.3.5
        at      at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:461)
        at      at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:372)
        at      at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:364)
        at      at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:161)
        at      at java.lang.ClassLoader.loadClass(ClassLoader.java:352)
        at      at ch.qos.logback.core.util.OptionHelper.instantiateByClassNameAndParameter(OptionHelper.java:56)
        at      ... 40 common frames omitted

我实现了一个Gradle模块osgi-log专门处理日志,其配置如下:

group 'project'
version '1.0.0'

dependencies {
    api group: 'org.slf4j', name: 'slf4j-api', version: '2.0.5'

    implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.3.5'
    implementation group: 'ch.qos.logback', name: 'logback-core', version: '1.3.5'
    implementation group: 'ch.qos.logback.db', name: 'logback-classic-db', version: '1.2.11.1'
    implementation group: 'mysql', name: 'mysql-connector-java', version: '8.0.33'
    implementation group: 'org.ow2.asm', name: 'asm', version: '5.2'
    implementation group: 'org.ow2.asm', name: 'asm-commons', version: '5.2'
    implementation group: 'org.ow2.asm', name: 'asm-util', version: '5.2'
    implementation group: 'org.apache.aries.spifly', name: 'org.apache.aries.spifly.dynamic.bundle', version: '1.3.5'
}

其他bundle通过如下依赖使用日志功能:

dependencies {
    implementation group: 'project', name: 'osgi-log'
}

补充说明:本地环境操作,应用和数据库均运行在localhost,使用mysql v.8.0.33。

logback配置如下:

<appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
    <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
      <driverClass>com.mysql.jdbc.Driver</driverClass>
      <url>jdbc:mysql://127.0.0.1:3306/osgi_app</url>
      <user>osgi_app</user>
      <password>osgi_app</password>
    </connectionSource>
  </appender>

无法理解为什么BundleLoader找不到DBAppender类,本人对OSGi、bundle以及基于slf4j的logback-classic环境并不完全了解。


解决方案

1. 修复版本不匹配问题

你使用的logback-classic是1.3.5版本,但logback-classic-db是1.2.11.1版本,两者版本不一致。Logback 1.3.x版本对DBAppender的包结构、依赖逻辑做了调整,低版本的logback-classic-db无法被高版本的logback-classic正确识别加载。

修改Gradle依赖:将logback-classic-db版本升级到与logback-classic、logback-core一致的1.3.5:

implementation group: 'ch.qos.logback', name: 'logback-classic-db', version: '1.3.5'

2. 解决OSGi类可见性限制

OSGi环境中,bundle之间的类访问受严格限制。当前logback-classic bundle尝试加载DBAppender,但logback-classic-db的类未被导出,或者logback-classic未导入对应的包。

修复方式:

  • 使用Gradle的OSGi插件(如biz.aQute.bnd.gradle)生成正确的bundle元数据,确保osgi-log模块导出ch.qos.logback.classic.db包,同时让logback-classic导入该包。
  • 若使用bnd插件,可在bnd.bnd文件中添加:
Import-Package: ch.qos.logback.classic.db, *
Export-Package: ch.qos.logback.classic.db, *

3. 调整MySQL驱动类

MySQL 8.0+的官方驱动类已更新为com.mysql.cj.jdbc.Driver,你配置的旧类名com.mysql.jdbc.Driver虽兼容,但可能引发潜在类加载问题,建议修改logback配置:

<driverClass>com.mysql.cj.jdbc.Driver</driverClass>

总结

优先解决版本不匹配问题,这是导致当前错误的核心原因。之后检查OSGi bundle的元数据配置,确保类可见性符合要求,最后更新MySQL驱动类名以适配新版本。

内容的提问来源于stack exchange,提问作者skrenato

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 02:08:11