Osgi 环境中的 NoClassDefFoundError

Posted

技术标签:

【中文标题】Osgi 环境中的 NoClassDefFoundError【英文标题】:NoClassDefFoundError in Osgi environment 【发布时间】:2017-04-20 13:32:35 【问题描述】:

我在 apache karaf 上使用 osgi,我正在尝试使用 kafkadebezium 来运行 osgi 环境。 p>

kafkadebezium 还没有 osgi 准备好(karaf 不会将它们视为捆绑包),所以我确实使用 eclipse "Plug -在项目中”。我对它们进行 osgified 的 jar 如下:debezium-embedded、debezium-core、kafka connect-api、kafka connect-runtime。

一开始,当我尝试运行 debezium 时,我得到了很多“找不到类的异常”。

为了解决这个问题,我更改了两个捆绑包的清单。我向调用者添加了一个导入包,向被调用包添加了一个导出包。使用它我可以解决 classNotFound 问题。

解决所有 classNotfound 问题后,我得到 NoClassDefFoundError

NoClassDefFoundError 意味着类加载器在尝试加载它们时找不到 .class ......但我确实导入了所有包并导出它们。

任何想法如何在 osgi 环境中处理 NoClassDefFoundError

[编辑添加代码]

这是监视器类:

public class Monitor 
    private Consumer<SourceRecord> consumer = new Consumer<SourceRecord>() 

        public void accept(SourceRecord t) 
            System.out.println("Change Detected !");
        

    ;

    public void connect() 

        System.out.println("Engine Starting");
        Configuration config = Configuration.create()
                /* begin engine properties */
                .with("connector.class", "io.debezium.connector.mysql.MySqlConnector")
                .with("offset.storage", "org.apache.kafka.connect.storage.FileOffsetBackingStore")
                .with("offset.storage.file.filename", "d:/pathTooffset.dat")
                .with("offset.flush.interval.ms", 60000)
                /* begin connector properties */
                .with("name", "my-sql-connector").with("database.hostname", "localhost").with("database.port", 3306)
                .with("database.user", "root").with("database.password", "apassword").with("server.id", 10692)
                .with("database.server.name", "localhost")
                .with("database.history", "io.debezium.relational.history.FileDatabaseHistory")
                .with("database.history.file.filename", "d:/pathTOdbhistory.dat")
                .build();
        try 
            // Create the engine with this configuration ...
            EmbeddedEngine engine = EmbeddedEngine.create().using(config).notifying(consumer).build();
            Executor executor = Executors.newFixedThreadPool(1);

            executor.execute(() -> 
                engine.run();
            );
         catch (Exception e) 
            e.printStackTrace();
        

    

还有我的激活器:

public class Activator implements BundleActivator 

public void start(BundleContext context) throws Exception 
    Monitor monitor = new Monitor();
    monitor.connect();


public void stop(BundleContext context) throws Exception 

【问题讨论】:

如果您使用错误的类加载器,可能会发生错误。看起来异常发生在类监视器中。能发一下相关内容吗? @ChristianSchneider 我在上面添加了代码 @ChristianSchneider 上面的代码在我作为独立 jar 运行时有效,但是当我尝试在 osgi karaf 上运行时出现错误 【参考方案1】:

问题必须在EmbeddedEngine 内部。错误无法初始化类意味着该类的某些静态初始化不起作用。请参阅此相关问题noclassdeffounderror-could-not-initialize-class-error。

我建议在debug模式下运行karaf,通过这个类的初始化来调试。

【讨论】:

感谢您的回答,但您能回答这些问题吗?为什么静态初始化错误仅在我在 karaf 上运行时发生,而在我使用 java 独立应用程序运行时没有发生?这是否意味着debezium与osgi环境不兼容? 是的。我认为 debezium 目前与 OSGi 不兼容。我猜他们对在 OSGi 中不起作用的类加载有假设。我认为你应该在他们的问题跟踪器中打开一个关于该问题的问题。 Debezium JAR 没有 OSGi 清单,因为 IIRC 我们的第 3 方库依赖项也没有它们。随时记录问题以将 OSGi 清单添加到 JAR,但您可能需要考虑通过拉取请求来贡献更改以加快速度。

以上是关于Osgi 环境中的 NoClassDefFoundError的主要内容,如果未能解决你的问题,请参考以下文章

OSGI 环境中的依赖注入

osgi+camel+karaf运行环境搭建

XML 代码运行正常,但 junit 因 NoClassDefFound 而失败

关于运行osgi插件时和运行环境相关的问题

在 OSGi 环境中,类路径和类加载器是如何设置的?

基于OSGi的Virgo环境搭建——环境篇