1

I have a simple Hello World type Karaf Bundle running inside Apache ServiceMix 6.1.0 using Jackson's Afterburner Module. The activator code looks like below:-

public class HelloWorldActivator implements BundleActivator {
        @Override
        public void start(BundleContext bundleContext) throws Exception {
            System.out.println("STARTING DEMO: hello, world\n");
            System.out.println(getJsonDataAsString());
        }

        @Override
        public void stop(BundleContext bundleContext) throws Exception {
            System.out.println("STOPPING DEMO");
        }   

        private String getJsonDataAsString() {
            JsonDataBlob jsonDataBlob = new JsonDataBlob();
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.registerModule(new AfterburnerModule());
            try {
                return objectMapper.writeValueAsString(jsonDataBlob);
            } catch(Exception e) {
                e.printStackTrace();
            }
            return "";          
        }               
}

The pom.xml looks like below:-

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.hello</groupId>
    <artifactId>world</artifactId>
    <version>0.0.1</version>
    <packaging>bundle</packaging>
    <name>Hello World</name>
    <dependencies>
        <!-- OSGi -->
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>org.osgi.core</artifactId>
            <version>4.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>org.osgi.compendium</artifactId>
            <version>4.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20160212</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.6.2</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.6.2</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.6.2</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-afterburner</artifactId>
            <version>2.7.1</version>
        </dependency>



    </dependencies>
    <build>
        <sourceDirectory>src</sourceDirectory>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <excludes>
                        <exclude>**/com/hello/main/*</exclude>
                    </excludes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <version>2.4.0</version>
                <inherited>true</inherited>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
                        <Bundle-Version>${project.version}</Bundle-Version>
                        <Bundle-Activator>com.hello.world.HelloWorldActivator</Bundle-Activator>
                        <Import-Package>*;resolution:=optional</Import-Package>
                    </instructions>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

The java object which I am trying to convert to json is a simple object as shown below:-

package com.hello.world;

public class JsonDataBlob {
    private String add1 = "JP Naagar";
    private String add2 = "";
    private int shippartagent = 1;

    public String getAdd1() {
        return add1;
    }

    public void setAdd1(String add1) {
        this.add1 = add1;
    }

    public String getAdd2() {
        return add2;
    }

    public void setAdd2(String add2) {
        this.add2 = add2;
    }

    public int getShippartagent() {
        return shippartagent;
    }

    public void setShippartagent(int shippartagent) {
        this.shippartagent = shippartagent;
    }
}

But whenever I am trying to install the bundle I am getting the below exception and the bundle gets stuck in the Resolved state:-

2016-05-07 15:36:48,986 | WARN  | x-6.1-2.0/deploy | fileinstall                      | 7 - org.apache.felix.fileinstall - 3.5.0 | Error while starting bundle: file:/Users/debraj/Downloads/apache-servicemix-6.1-2.0/deploy/world-0.0.1.jar
org.osgi.framework.BundleException: Activator start error in bundle world [239].
        at org.apache.felix.framework.Felix.activateBundle(Felix.java:2196)[org.apache.felix.framework-4.2.1.jar:]
        at org.apache.felix.framework.Felix.startBundle(Felix.java:2064)[org.apache.felix.framework-4.2.1.jar:]
        at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:955)[org.apache.felix.framework-4.2.1.jar:]
        at org.apache.felix.fileinstall.internal.DirectoryWatcher.startBundle(DirectoryWatcher.java:1245)[7:org.apache.felix.fileinstall:3.5.0]
        at org.apache.felix.fileinstall.internal.DirectoryWatcher.startBundles(DirectoryWatcher.java:1217)[7:org.apache.felix.fileinstall:3.5.0]
        at org.apache.felix.fileinstall.internal.DirectoryWatcher.doProcess(DirectoryWatcher.java:509)[7:org.apache.felix.fileinstall:3.5.0]
        at org.apache.felix.fileinstall.internal.DirectoryWatcher.process(DirectoryWatcher.java:358)[7:org.apache.felix.fileinstall:3.5.0]
        at org.apache.felix.fileinstall.internal.DirectoryWatcher.run(DirectoryWatcher.java:310)[7:org.apache.felix.fileinstall:3.5.0]
Caused by: java.lang.NoClassDefFoundError: com/fasterxml/jackson/module/afterburner/AfterburnerModule
        at java.lang.Class.getDeclaredConstructors0(Native Method)[:1.8.0_77]
        at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671)[:1.8.0_77]
        at java.lang.Class.getConstructor0(Class.java:3075)[:1.8.0_77]
        at java.lang.Class.newInstance(Class.java:412)[:1.8.0_77]
        at org.apache.felix.framework.Felix.createBundleActivator(Felix.java:4336)
        at org.apache.felix.framework.Felix.activateBundle(Felix.java:2141)
        ... 7 more
Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.module.afterburner.AfterburnerModule not found by world [239]
        at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1532)[org.apache.felix.framework-4.2.1.jar:]
        at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:75)[org.apache.felix.framework-4.2.1.jar:]
        at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1955)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)[:1.8.0_77]
        ... 13 more

All the required Jackson bundles are installed in Karaf:-

karaf@root>bundle:list | grep Jackson
123 | Active    |  50 | 2.6.2                              | Jackson-core                                   
125 | Active    |  50 | 2.6.2                              | Jackson-annotations                            
238 | Installed |  80 | 2.7.1                              | Jackson-module-Afterburner                     
karaf@root>bundle:list | grep jackson
124 | Active    |  50 | 2.6.2                              | jackson-databind  

Everything works fine if I comment out the below line:-

objectMapper.registerModule(new AfterburnerModule());

Can some one let me know what I am doing wrong?

All the code I have placed in the github.

tuk
  • 5,941
  • 14
  • 79
  • 162

2 Answers2

4

You already asked this at the karaf mailing list. It's still the same thing, as long as the package isn't imported in your own application it won't work. Since you do an import for *;optional=true you won't get a wiring exception as your imports are all optional. Therefore the ClassNotFound Exeception. First of all check the headers for the right imports with

bundle:header [bundle-id]

second, since you are doing an * import it might happen as you don't explicitly ask for a certain class in a certain package that some packages aren't imported. And a sub-package import doesn't help on the package, so if you have an import for

com.fasterxml.jackson.module.afterburner.subPackage

this won't help on resolving classes in

com.fasterxml.jackson.module.afterburner

So it's actually best to declare all imports and use the * only on sub-packages.

In your case add the following to your pom:

       <plugin>
            <groupId>org.apache.felix</groupId>
            <artifactId>maven-bundle-plugin</artifactId>
            <version>2.4.0</version>
            <inherited>true</inherited>
            <extensions>true</extensions>
            <configuration>
                <instructions>
                    <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
                    <Bundle-Version>${project.version}</Bundle-Version>
                    <Bundle-Activator>com.hello.world.HelloWorldActivator</Bundle-Activator>
                    <Import-Package>
                         com.fasterxml.jackson.module.afterburner.*,
                         *;resolution:=optional
                    </Import-Package>
                </instructions>
            </configuration>
        </plugin>
Achim Nierbeck
  • 5,265
  • 2
  • 14
  • 22
  • If I add `com.fasterxml.jackson.module.afterburner.*,*;resolution:=optional` then in the generated `MANIFEST` I was not seeing the `com.fasterxml.jackson.module.afterburner` nor the subpackage `ser` or `deser` in the `Import-Package` But if I specify the subpackage explicitly as shown below. I was getting both the `ser` & `deser` in the `Import-Package` `com.fasterxml.jackson.module.afterburner.ser,com.fasterxml.jackson.module.afterburner.deser,*;resolution:=optional`. Can you let me know what could be the reason for this? – tuk May 08 '16 at 19:43
  • 2
    The inspected bytecode doesn't seem to use those packages, therefore not imported. This usually happens if Classes of those packages are used via Reflection or such. In such cases it's crucial to actually add those dependencies yourself. The tools can only help to a certain degree, in the end you need define the dependencies which you know of. – Achim Nierbeck May 08 '16 at 19:50
  • I am facing a problem again. I have posted it here http://karaf.922171.n3.nabble.com/Jackson-Module-Afterburner-not-working-in-Karaf-3-0-5-td4046536.html#a4046579. Can you please help me what could be going wrong? – tuk May 12 '16 at 05:57
-1

Along with upgrading to Jackson 2.7.4. Modifying my Import-Package in pom.xml as shown below solved the issue:-

<Import-Package>com.fasterxml.jackson.module.afterburner.ser;resolution:=optional,*</Import-Package>

tuk
  • 5,941
  • 14
  • 79
  • 162