Search code examples
osgiapache-kafkakarafdebezium

NoClassDefFoundError in Osgi environment


I am working with osgi on apache karaf and I am trying to use kafka and debezium to run into an osgi environment.

kafka and debezium were not osgi ready (karaf will not consider them as bundles), so I did osgified them using eclipse "Plug-in project". The jars that I osgified them are the following : debezium-embedded, debezium-core, kafka connect-api, kafka connect-runtime.

At the begining I get alot of "Class not found exception" when I try to run debezium..

enter image description here

In order to resolve this problem, I changed the manifest of the two bundles. I added an import package to the caller and an export package to the called bundle. Using this I can solve the classNotFound issue.

After solving all the classNotfound issues, I get NoClassDefFoundError

enter image description here

NoClassDefFoundError means that the class loader could not find the .class when it tries to load them ... But I did import all the packages and export them as well.

Any thoughts how to deal with NoClassDefFoundError in an osgi environement

[EDIT Added code]

This is the class Monitor :

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();
        }

    }

And my activator :

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 {
}}

Solution

  • The problem must be inside EmbeddedEngine. The error could not initialize class means that some static initialization of the class did not work. See this related question noclassdeffounderror-could-not-initialize-class-error.

    I propose to run karaf in debug mode and debug through the initialization of this class.