fg78nc
fg78nc

Reputation: 5232

OSGI : maven wrapped bundle throws java.lang.ClassNotFoundException if it tries to access another wrapped bundle

As below dependencies are not OSGI-ready I wrapped them as follows :

  <bundle>wrap:mvn:com.google.maps/google-maps-services/0.9.2</bundle>
  <bundle>wrap:mvn:com.squareup.okhttp3/okhttp/3.13.1</bundle>

Seems like my first bundle can't access second bundle, although I included it in my imports as follows:

<Import-Package>okhttp3,*</import-Package>

I am getting :

Caused by: java.lang.NoClassDefFoundError: okhttp3/Authenticator
    at com.google.maps.GeoApiContext$Builder.<init>(GeoApiContext.java:318)
    at com.elavon.nabsd.creditsafe.beans.GooglePlacesAPIContext.<clinit>(GooglePlacesAPIContext.java:11)
    at com.elavon.nabsd.creditsafe.beans.AddressParser.getAddress(AddressParser.java:35)
    at com.elavon.nabsd.creditsafe.beans.AddressParser.dummyResponse(AddressParser.java:76)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.camel.component.bean.MethodInfo.invoke(MethodInfo.java:408)
    at org.apache.camel.component.bean.MethodInfo$1.doProceed(MethodInfo.java:279)
    at org.apache.camel.component.bean.MethodInfo$1.proceed(MethodInfo.java:252)
    ... 13 more
Caused by: java.lang.ClassNotFoundException: okhttp3.Authenticator not found by wrap_mvn_com.google.maps_google-maps-services_0.9.2 [1180]
    at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1556)
    at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:77)
    at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1993)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 24 more

Manifest

Manifest-Version: 1.0
Bnd-LastModified: 1552097042208
Build-Jdk: 1.8.0_181
Built-By: c041356
Bundle-Blueprint: OSGI-INF/blueprint/address-parser-blueprint.xml
Bundle-Description: XXX
Bundle-DocURL: XXX
Bundle-ManifestVersion: 2
Bundle-Name: XXX
Bundle-SymbolicName: address-parser
Bundle-Vendor: XXX
Bundle-Version: 1.0.24
Created-By: Apache Maven Bundle Plugin
DynamicImport-Package: *
Export-package: com.squareup.okhttp3,okhttp3
Import-Package: okhttp3,com.fasterxml.jackson.annotation,com.google.maps
 ,com.google.maps.errors,com.google.maps.model,org.apache.camel.componen
 t.jasypt,org.jasypt.encryption.pbe.config,org.osgi.service.blueprint;ve
 rsion="[1.0.0,2.0.0)",org.slf4j,org.apache.camel.component.http4,org.ap
 ache.camel.component.jackson,com.squareup.okhttp3
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"
Tool: Bnd-3.0.0.201509101326

wrap_mvn_com.squareup.okhttp3_okhttp_3.13.1 (1202)
--------------------------------------------------
Originally-Created-By = Apache Maven 3.6.0
Created-By = 1.8.0_181 (Oracle Corporation)
Manifest-Version = 1.0
Bnd-LastModified = 1552095323499
Generated-By-Ops4j-Pax-From = wrap:mvn:com.squareup.okhttp3/okhttp/3.13.1
Build-Jdk = 1.8.0_162
Built-By = jwilson
Automatic-Module-Name = okhttp3
Tool = Bnd-2.3.0.201405100607

Bundle-ManifestVersion = 2
Bundle-SymbolicName = wrap_mvn_com.squareup.okhttp3_okhttp_3.13.1
Bundle-Version = 0
Bundle-Name = wrap_mvn_com.squareup.okhttp3_okhttp_3.13.1

Require-Capability =
        osgi.ee;filter:=(&(osgi.ee=JavaSE)(version=1.8))

Export-Package =
        okhttp3;uses:="javax.annotation,javax.net,javax.net.ssl,okio",
        okhttp3.internal;uses:="javax.annotation,javax.net.ssl,okhttp3,okhttp3.internal.cache,okhttp3.internal.connection,okhttp3.internal.http,okhttp3.internal.http2,okio",
        okhttp3.internal.annotations;uses:="javax.annotation,javax.annotation.meta",
        okhttp3.internal.cache;uses:="javax.annotation,okhttp3,okhttp3.internal.io,okio",
        okhttp3.internal.cache2,
        okhttp3.internal.connection;uses:="javax.annotation,javax.net.ssl,okhttp3,okhttp3.internal.http,okhttp3.internal.http2,okhttp3.internal.ws",
        okhttp3.internal.duplex,
        okhttp3.internal.http;uses:="javax.annotation,okhttp3,okhttp3.internal.connection,okio",
        okhttp3.internal.http1;uses:="okhttp3,okhttp3.internal.connection,okhttp3.internal.http,okio",
        okhttp3.internal.http2;uses:="okhttp3,okhttp3.internal.connection,okhttp3.internal.http,okio",
        okhttp3.internal.io;uses:=okio,
        okhttp3.internal.platform;uses:="javax.annotation,javax.net.ssl,okhttp3,okhttp3.internal.tls",
        okhttp3.internal.proxy,
        okhttp3.internal.publicsuffix,
        okhttp3.internal.tls;uses:=javax.net.ssl,
        okhttp3.internal.ws;uses:="javax.annotation,okhttp3,okio"
Import-Package =
        android.os;resolution:=optional,
        android.util;resolution:=optional,
        javax.annotation;resolution:=optional,
        javax.annotation.meta;resolution:=optional,
        javax.net;resolution:=optional,
        javax.net.ssl;resolution:=optional,
        javax.security.auth.x500;resolution:=optional,
        okio;resolution:=optional,

wrap_mvn_com.google.maps_google-maps-services_0.9.2 (1180)
----------------------------------------------------------
Created-By = 1.8.0_181 (Oracle Corporation)
Manifest-Version = 1.0
Bnd-LastModified = 1552091296783
Generated-By-Ops4j-Pax-From = wrap:mvn:com.google.maps/google-maps-services/0.9.2
Tool = Bnd-2.3.0.201405100607

Bundle-ManifestVersion = 2
Bundle-SymbolicName = wrap_mvn_com.google.maps_google-maps-services_0.9.2
Bundle-Version = 0
Bundle-Name = wrap_mvn_com.google.maps_google-maps-services_0.9.2

Require-Capability =
        osgi.ee;filter:=(&(osgi.ee=JavaSE)(version=1.8))

Export-Package =
        com.google.maps;uses:="com.google.gson,com.google.maps.errors,com.google.maps.internal,com.google.maps.model,okhttp3",
        com.google.maps.errors,
        com.google.maps.internal;uses:="com.google.appengine.api.urlfetch,com.google.gson,com.google.gson.stream,com.google.maps,com.google.maps.errors,com.google.maps.model,okhttp3",
        com.google.maps.internal.ratelimiter,
        com.google.maps.model;uses:=com.google.maps.internal
Import-Package =
        com.google.appengine.api.urlfetch;resolution:=optional,
        com.google.gson;resolution:=optional,
        com.google.gson.stream;resolution:=optional,
        javax.crypto;resolution:=optional,
        javax.crypto.spec;resolution:=optional,
        okhttp3;resolution:=optional,
        okio;resolution:=optional,
        org.slf4j;resolution:=optional

Upvotes: 3

Views: 2058

Answers (1)

Ancoron
Ancoron

Reputation: 2733

Wrapped bundles get the automatically discovered package dependencies as "optional", because there is no way to tell reliably whether some specific package will actually be required or not when using specific functionality provided by the bundle.

Hence, the existence of other bundles and their exported packages at the bundle resolving time determine, which packages are actually visible to the created class-loader of the resolved wrapped bundle.

In your case, the packages exported by bundle "okhttp3" where not available at the time the resolver searched for available package to import when resolving bundle "google-maps".

This in turn means that you need to make sure that either:

  1. the bundle "okhttp3" is visible to the resolver at the time of resolving bundle "google-maps"
  2. make sure that the required package imports are not "optional"

While the first option may seem easier, the second one is more reliable and flexible.

The wrap: protocol supports overwriting generated OSGi headers so that you can specify details to your needs. In our case, it would be:

<bundle>wrap:mvn:com.google.maps/google-maps-services/0.9.2$overwrite=merge&amp;Import-Package=okhttp3,okio,*;resolution:=optional</bundle>

(untested and only based on docs, though)

Notice

Before using the wrap protocol, please have a look whether the desired library has already been OSGi-fied by some other project. One very good start is to have a look at the Bundles made available by the Apache ServiceMix project (which provides a okhttp3 Bundle):

Upvotes: 3

Related Questions