Karaf missing classes in bundles - osgi

I am deploying httpclient-4.3.4.jar in deploy folder of karaf. In terminal when I use command find-class HttpClients, nothing is getting listed. When use keyword find-class HttpClient, I get only follwing classes loaded for httpclient bundle. Since some of the classes are missing I am getting java.lang.NoClassDefFoundError: org/apache/http/impl/client/HttpClients in one of my dependent bundles.
I need to know whey some classes are not available. If it is our own bundle, we can specify imports and exports to control the classes which we need to expose. But for external jars, why this is happening?
httpclient (202)
org/apache/http/HttpClientConnection.class
org/apache/http/client/HttpClient.class
org/apache/http/client/params/HttpClientParams.class
org/apache/http/client/utils/HttpClientUtils.class
org/apache/http/impl/AbstractHttpClientConnection.class
org/apache/http/impl/DefaultHttpClientConnection.class
org/apache/http/impl/SocketHttpClientConnection.class
org/apache/http/impl/client/AbstractHttpClient.class
org/apache/http/impl/client/AutoRetryHttpClient.class
org/apache/http/impl/client/ContentEncodingHttpClient.class
org/apache/http/impl/client/DecompressingHttpClient.class
org/apache/http/impl/client/DefaultHttpClient.class
org/apache/http/impl/client/SystemDefaultHttpClient.class

First, is it a valid OSGi bundle, without the required manifest entries and the right Package-Exports/Imports this won't work.
If you just drop it in the deploy folder it might get autowrapped, but this isn't always working. It's better to either take an existing Bundle or do install with:
osgi:install wrap:mvn:groupID/artifactID/version
All of this is also documented in the Karaf User Manual.
The installed bundle can be started with
start ID
where ID is the ID of the bundle just installed.
EDIT:
You definitely need to wrap the bundle in question, since it isn't a OSGi bundle yet.
So in your case do:
install wrap:mvn:org.apache.httpcomponents/httpclient/4.3.4
after the bundle is installed:
start ID
If you do a bundle:header after that you'll get a nice header definition.
The find class does show the HttpClient class in this bundle:
karaf#root()> find-class HttpClients
wrap_mvn_org.apache.httpcomponents_httpclient_4.3.4 (78)
org/apache/http/impl/client/HttpClients.class

Related

bundle will not start when bouncy castle is imported

I am trying to add bouncy castle as a service provider to my java product running on apache karaf.
When I am trying to start the bundle which imports bouncy castle I get an error message
java.lang.Exception: Could not start bundle mvn:com.xxx.yyy.zzz/docsservice/1.0.0-SNAPSHOT/war in feature(s) server-docs-1.0.0-SNAPSHOT: Unresolved constraint in bundle docs [245]: Unable to resolve 245.0: missing requirement [245.0] osgi.wiring.package; (&(osgi.wiring.package=org.bouncycastle.jce.provider)(version>=1.51.0))
at org.apache.karaf.features.internal.FeaturesServiceImpl.startBundle(FeaturesServiceImpl.java:472)
In the pom file I imported the package org.bouncycastle.jce.provider and I added bouncycastle as a dependency.
Also, i made all the changes described on this page,
http://karaf.apache.org/manual/latest/users-guide/security.html, see below
I put provider jar in lib/ext
I Modified the etc/config.properties configuration file to add the following property
org.apache.karaf.security.providers = xxx,yyy
org.apache.karaf.security.providers = org.bouncycastle.jce.provider.BouncyCastleProvider
I provided access to the classes from those providers from the system bundle so that all bundles can access those. I did this by modifying the org.osgi.framework.bootdelegation property in the same configuration file:
org.osgi.framework.bootdelegation = ...,org.bouncycastle*
On some forum I found another suggestion so I modified
*org.osgi.framework.system.packages.extra = * in the config.properties as well and I added here packages exported from bouncycastle
Nonetheless I wasn't able to load the bundle successfully. I looked at all the bundles loaded by karaf and none of them was exporting bouncy castle package.
What am I missing here? How can I make the bundles to start?
By adding the package to the boot delegation you made it available like java.* packages. For these you do not need an Import-Package. So one way would be to remove the Import-Package for it in your bundle. You should rather explore though if you can work without boot delegation.
Please try to remove the boot delegation and add the package to
org.osgi.framework.system.packages.extra = org.bouncycastle.jce.provider
This adds the package to the packages the system bundle exports. It should then be wired to your bundle.

Unable to wire proper bundle with my own bundle in wso2 app server

I am using wso2 Application Server 5.1.0.
I have deployed my own bundle having name demo-service which contains import-package definition in its manifest as below:
>Bundle-SymbolicName = demo-service
Import-Package = javax.sql,org.apache.commons.dbcp;version="[1.4,2)"
I tried to diagnose the most popular "uses conflict" in OSGi world for my case and I found that commons-dbcp_1.4.0.wso2v1.jar and commons-dbcp-1.4.jar both were converted to OSGi bundle by container and exported their packages with version "0.0.0" which can be observed from the output below:
>osgi> packages org.apache.commons.dbcp
org.apache.commons.dbcp; version="0.0.0"<commons-dbcp_1.4.0.wso2v1 [49]>
compass_2.0.1.wso2v2 [60] imports
org.wso2.carbon.core_4.1.0 [256] imports
org.wso2.carbon.registry.core_4.1.0 [377] imports
org.wso2.carbon.tenant.mgt_2.1.0 [434] imports
synapse-commons_2.1.1.wso2v3 [528] imports
synapse-core_2.1.1.wso2v3 [529] imports
org.apache.commons.dbcp; version="0.0.0"<commons_dbcp_1.4_1.0.0 [57]>
According to the requirement of my demo-service bundle it's not able to find
org.apache.commons.dbcp;version="[1.4,2)"
Is there any way to export the packages of commons-dbcp-1.4.jar after it gets converted from non-osgi bundle to osgi bundle because I need to make sure that my demo-service bundle should wire with commons-dbcp-1.4.jar..
In brief, any version of thirdparty jar I put in WSO2_HOME\repository\components\lib folder container exports it with version="0.0.0" .. which discourages the main concept for classloading of OSGi
please suggest if any workaround is possible in this case .. :)
Thanks ..
When a version is not specified while exporting packages OSGi defaults to version 0.0.0. In this case as it's automatically converting to osgi bundle it might not be having version explicitly specified. Sometimes this also helps to ensure that multiple versions of packages are not present.
In your case as you need to use the packages in the bundle put in repository\components\lib folder you could manually specify the version. The OSGi-fied bundles of the jars you put in repository\components\lib can be found in repository\components\dropins folder. Inside that bundle you will find the OSGi manifest file. In the manifest file manually specify the versions for the required packages under Export-Package category as follows.
org.apache.commons.dbcp;version=1.4.1
Then on startup, it would use these bundles and you should be able to export packages with specified version.

Find the OSGI bundle that exports a package?

How do I find the bundle that exports a package?
I am using felix and I have a string like "com.test", how do I know which bundle exports that package?
I don't want to use PackageAdmin as it has been deprecated, and I don't really want to get the Export-Package header for each bundle and parse it.
Any ideas?
It sounds like you want to do this programmatically, not at the Gogo shell ... at least I'll assume that from wording of your question.
There is no real way to say "which bundle" exports a given package since there can be many bundles exporting any given package and that package can be in use from many bundles by many bundles. If you have a specific bundle and you want to know which bundle provides package com.test to it, you can get the importing bundle's wiring Bundle.adapt(BundleWiring.class) and then use BundleWiring.getRequiredWires() to get the providers of all of the bundle's dependencies.
From there you just need to find the wire of osgi.wiring.package namespace for the package you want, then the provider of that wire will be a BundleCapability of a BundleRevision of the bundle you are interested in.
Have you tried:
exports | grep com.test ?
Recent versions of the Apache Felix OSGi console include a "dependency finder" plugin which lists the bundle(s) that export a given package or class. There are some screenshots at http://www.6dlabs.com/blog/dklco/2012-05-04/new-cq-55-dependency-finder (which mention CQ5 but the plugin does not depend on that).
That's useful at the admin level, and if you need to find that out in code you could have a look at that plugin's source code, see https://issues.apache.org/jira/browse/FELIX-3045
A quick solution is to iterate over the bundles, list the id and the export package header.
g! each (bundles) { echo ($it bundleId) (($it headers) get Export-Package) }
Note that you need to put spaces around the { and }! This prints for each bundle, its id and its Export-Package header. You can put this in a cmd:
g! exports= { each (bundles) { echo ($it bundleId) (($it headers) get Export-Package) } }
You can then use it easier with grep:
g! exports | grep webconsole
12 org.apache.felix.webconsole;version="3.3.0";uses:="javax.servlet,javax.servlet.http,org.osgi.framework",org.apache.felix.webconsole.bundleinfo;version="1.0.0";uses:="org.osgi.framework",org.apache.felix.webconsole.i18n;version="1.0.0";uses:="org.osgi.framework"
true
The official command for exported packages is inspect
g! inspect cap osgi.wiring.package
However, the output is very messy and hard to grep. However, if you know the package name then you can ask (deprecated) Package Admin.
g! r=servicereference org.osgi.service.packageadmin.PackageAdmin
....
g! pa=service $r
org.apache.felix.framework.PackageAdminImpl#2c7b40e3
g! $pa exportedpackages org.osgi.framework
org.osgi.framework; version=1.10.0
org.osgi.framework; version=1.9.0
org.osgi.framework; version=1.10.0
org.osgi.framework; version=1.9.0
g! each ($pa exportedpackages org.osgi.framework) { $it exportingbundle }
0|Active | 0|org.apache.felix.framework (0.1.0.SNAPSHOT)
Unfortunately, the Package Admin methods are overloaded and Gogo picks the first one that matches, otherwise it would be a lot easier :-(
If you have the set of bundles then the bnd command line can be useful. You can install it here.
You can then do:
$ bnd find -e "com.example*" jars/*.jar
or
$ bnd grep -e "com.example*" jars/*.jar

using cxf in osgi: Provider org.apache.cxf.jaxws.spi.ProviderImpl not found

I am trying to publish some web services (using EndpointImpl.publish()) but I am gettings this error:
Provider org.apache.cxf.jaxws.spi.ProviderImpl not found
the cxf-bundle is installed:
[ 79] [Active ] [Created ] [ 50] Apache CXF Bundle Jar (2.4.3.fuse-01-02)
an extract of the osgi:headers shows the imported package
Import-Package =
javax.jws,
javax.persistence;version="[1.1,2)",
javax.servlet;version="[2.5,3)",
javax.xml.bind,
javax.xml.bind.annotation,
javax.xml.bind.annotation.adapters,
javax.xml.datatype,
javax.xml.namespace,
javax.xml.parsers,
javax.xml.transform,
javax.xml.transform.stream,
javax.xml.validation,
javax.xml.ws;version="[2.2,3)",
javax.xml.ws.soap;version="[2.2,3)",
javax.xml.ws.wsaddressing;version="[2.2,3)",
org.apache.commons.lang;version="[2.5,3)",
org.apache.commons.logging;version="[1.1,2)",
org.apache.cxf.jaxws;version="[2.4,3)",
org.apache.cxf.jaxws.spi;version="[2.4,3)", <--- imported
org.apache.cxf.ws.addressing;version="[2.4,3)",
org.apache.felix.gogo.commands;version="[0.10,1)",
org.apache.openjpa.enhance;version="[2.2,3)",
org.apache.openjpa.util;version="[2.2,3)",
org.osgi.framework;version="[1.5,2)",
org.osgi.service.blueprint;version="[1.0.0,2.0.0)",
org.springframework.beans.factory.xml;version="[3.0,4)",
org.springframework.context;version="[3.0,4)",
org.springframework.context.support;version="[3.0,4)",
org.w3c.dom,
org.xml.sax
Require-Bundle =
org.apache.cxf.bundle
I am not sure what else I need to do.
in case it is important. the container is a karaf 2.2.7
to address pooh's answer:
1- cxf-bundle is exporting this package: org.apache.cxf.jaxws.spi;version="2.4.3.fuse-01-02"
2- bundle was started. the error was during runtime.
3- the manifest was created using maven-bundle-plugin which should create the entire list
4- the error happen while creating a webservice endpoint:
TopologyIFPortType impl = new TopologyWS();
String addressTopology = "http://localhost:" + port
+ "/nsp/webservice/topology";
topologyEndpoint = (EndpointImpl) Endpoint.create(impl);
topologyEndpoint.getFeatures().add(new WSAddressingFeature());
topologyEndpoint.publish(addressTopology);
the complete trace:
javax.xml.ws.spi.FactoryFinder$ConfigurationError: Provider org.apache.cxf.jaxws.spi.ProviderImpl not found
at javax.xml.ws.spi.FactoryFinder$2.run(FactoryFinder.java:130)
at javax.xml.ws.spi.FactoryFinder.doPrivileged(FactoryFinder.java:220)
at javax.xml.ws.spi.FactoryFinder.newInstance(FactoryFinder.java:124)
at javax.xml.ws.spi.FactoryFinder.access$200(FactoryFinder.java:44)
at javax.xml.ws.spi.FactoryFinder$3.run(FactoryFinder.java:211)
at javax.xml.ws.spi.FactoryFinder.doPrivileged(FactoryFinder.java:220)
at javax.xml.ws.spi.FactoryFinder.find(FactoryFinder.java:160)
at javax.xml.ws.spi.Provider.provider(Provider.java:43)
at javax.xml.ws.Endpoint.create(Endpoint.java:41)
at javax.xml.ws.Endpoint.create(Endpoint.java:37)
at org.opennaas.extensions.idb.webservice.WebServiceHolder.startTopology(WebserviceControl.java:78)
at org.opennaas.extensions.idb.webservice.WebServiceHolder.start(WebserviceControl.java:60)
at org.opennaas.extensions.idb.webservice.WebserviceControl.startWebservices(WebserviceControl.java:32)
at org.opennaas.extensions.idb.shell.StartWebservices.doExecute(StartWebservices.java:16)
at org.apache.karaf.shell.console.OsgiCommandSupport.execute(OsgiCommandSupport.java:38)
at org.apache.felix.gogo.commands.basic.AbstractCommand.execute(AbstractCommand.java:35)
at org.apache.felix.gogo.runtime.CommandProxy.execute(CommandProxy.java:78)
at org.apache.felix.gogo.runtime.Closure.executeCmd(Closure.java:474)
at org.apache.felix.gogo.runtime.Closure.executeStatement(Closure.java:400)
at org.apache.felix.gogo.runtime.Pipe.run(Pipe.java:108)
at org.apache.felix.gogo.runtime.Closure.execute(Closure.java:183)
at org.apache.felix.gogo.runtime.Closure.execute(Closure.java:120)
at org.apache.felix.gogo.runtime.CommandSessionImpl.execute(CommandSessionImpl.java:89)
at org.apache.karaf.shell.console.jline.Console.run(Console.java:240)
at java.lang.Thread.run(Thread.java:679)
The version of CXF you use seem to be quite old. You should try with the current release 2.6.1. In 2.6 a lot of OSGi improvements were introduced.
You can install it using:
features:chooseurl cxf 2.6.1
features:install cxf
Don't worry, OSGi gives you full access to the information which bundle uses which package etc. You only have to know how to ask the system to give you the info you need for debugging the problem.
Unfortunately I am not familiar with karaf console commands, I am working more with ProSyst's mBeddedServer OSGi framework, but since all this is standard in OSGi, I can tell you what to look for and you can find the needed commands in karaf.
So, check the following:
1. Is Apache cxf bundle successfully installed? Is it in the "active" state?
(from your posting it seems that it is)
What is the version of the org.apache.cxf.jaxws.spi package that it exports?
This is different from the cxf bundle version!!!
In order to see the package version, look inside the manifest of the cxf bundle, and look for the Export-package header.
Is your bundle installed and started successfully? Is it in the active state?
If the error "Provider not found" appears during starting of your bundle, then your dependencies are not matching the provided packages from the cxf bundle, see point 2.
If, however, the error appears during runtime, it could have several causes:
You haven't imported all needed packages in your manifest. Try using analysis tools which can generate the manifest for you based on your source code.
or:
The code which does the publishing is located e.g. on the system classpath and uses the system classloader, which in OSGI due to modularity and security reasons doesn't have access to the bundle classloaders.
Check what is provided by the system classpath instead of as OSGi bundles. Anything there which uses Class.forName or other reflection methods won't work in the modular OSGi framework.
There are also other possibilites, but you'll need to provide more info. Was there an exception stack trace? What classes are involved in this piece of code and where on the classpath are they located? etc.

I've already added tools.jar in classpath, why still java.lang.NoClassDefFoundError: com.sun.jdi.Bootstrap thrown?

I'm using the HotSwap function of javassist, it requires tools.jar in classpath, so I added -cp tools.jar when start my OSGi appliction. But when I new HotSwap() in the code of one of the bundles,
java.lang.NoClassDefFoundError: com.sun.jdi.Bootstrap
was thrown. com.sun.jdi.Bootstrap is in the tools.jar and I've already added it in classpath and also I verified it worked because if not, the following code will not work:
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
The Classloader of HotSwapper cannot load classcom.sun.jdi.Bootstrap? Then why it works properly in my Eclipse environment?(I added tools.jar into the libraries of Build path)
On why NoClassDefFoundError, any clue is appreciated.
You have to make sure the system bundle exports this package. For example in Felix the file jre.properties defines what packages are exported by the system bundle. Add the package com.sun.jdi there and it should work.
In eclipse this is done in config.ini. You can use org.osgi.framework.system.packages.extra= to define additional packages to export. I would rather not use boodelegation=* as it might export unwanted packages too. See:
http://www.eclipse.org/forums/index.php/m/734358/
http://wiki.eclipse.org/Equinox_Boot_Delegation
In Equinox, you can set Boot Delegation to * to gain acess to all class in bootclass, see this wiki for details. In 3.2, it was osgi.compatibility.bootdelegation=true in config.ini.

Resources