Camel - unmarshal().serialization() - ClassNotFoundException - java

I'm trying to unmarshal with serialization method a bean that is not the current bundle but in a commons components bundle.
I get the following error when camel tries to unmarshal my bean :
22:43:11,865 | ERROR | nModule-thread-1 | DefaultErrorHandler | 89 - org.apache.camel.camel-core - 2.8.0.fuse-06-11 | Failed
delivery for exchangeId: ID-ITEM-64684-49962-1354223882336-2-1.
Exhausted after delivery attempt: 1 caught:
java.lang.ClassNotFoundException: commons.InformationInput
java.lang.ClassNotFoundException: commons.InformationInput at
java.net.URLClassLoader$1.run(URLClassLoader.java:202)[:1.6.0_33] at
java.security.AccessController.doPrivileged(Native Method)[:1.6.0_33]
at
java.net.URLClassLoader.findClass(URLClassLoader.java:190)[:1.6.0_33]
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)[:1.6.0_33]http://stackoverflow.com/questions/6749334/osgi-bundle-access-spring-context-file-from-another-bundle
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)[:1.6.0_33]
at
org.apache.felix.framework.ModuleImpl.doImplicitBootDelegation(ModuleImpl.java:1610)
at
org.apache.felix.framework.ModuleImpl.searchDynamicImports(ModuleImpl.java:1547)
My bundle containing the bean is correctly started and i've defined the commons package in the Export-Package of the bundle definition
Does anyone managed to such thing ?

This sometimes occurs when the bundle that is serializing/deserializing classes does not know in advance what packages must be imported.
One workaround is to use DynamicImport-Package. For example:
DynamicImport-Package: *
This then means the bundle can import classes in any package, but beware of the costs (see the linked article).

This sounds similar to Hibernate issues an OSGi environment where it fails because of class loading issues. I would recommend something classed class buddy loading. in the Manifest of your commons bundle that contains the class add this
Eclipse-BuddyPolicy:registered
Then in your dependent buddy make sure you have it added as a dependent bundle and this to its manifest.
Eclipse-RegisterBuddy:com.nameofmycommonbundle
This should solve your problem.
Here is a reference to hibernate reference

I find a workaroud by enabling dynamicimport on camel-core bundle.
This can be done on karaf console : dev:dynamicimport <camel-core-bundle-id>

Related

JAXB + OSGi with Java 11

I'm trying to load the JAXB modules as OSGi bundles with Java 11 and Apache Felix using a POM-first approach (the OSGi meta data gets generated).
First I tried with:
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-osgi</artifactId>
<version>2.3.3</version>
</dependency>
but this gives me the following runtime exception:
SCHWERWIEGEND: Implementation of JAXB-API has not been found on module path or classpath.
javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.
- with linked exception:
[java.lang.ClassNotFoundException: com.sun.xml.bind.v2.ContextFactory]
It might be related to the following issue, but I'm not sure: https://github.com/eclipse-ee4j/jaxb-api/issues/78
So I tried with v3.0.0 but now one of my annotation processory which generate an XML document using JAXB, fails:
Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project my-module: Compilation failure
Implementation of JAXB-API has not been found on module path or classpath.
I noticed that jaxb-osgi-3.0.0.jar does not provide the com.sun.xml.bind package anymore
I also tried to migrate from javax.xml.bind to jakarta.xml.bind, but the Maven Plugins, which generate POJO classes from XSDs, don't seem to be ready yet at the time of writing (neither org.jvnet.jaxb2.maven2:maven-jaxb2-plugin nor org.codehaus.mojo:jaxb2-maven-plugin).
My questions:
Where can I get the com.sun.xml.bind from?
How do the jaxb-osgi and jaxb-impl modules relate?
How is this all supposed to work?
How can I proceed?
Update - background information
I have the following setup based on the Extender Pattern:
core extender module M:
provides some JAXB classes
a BundleTracker to unmarshal XML documents from a META-INF sub-directory of some bundles X, Y, Z
an abstract custom annotation processor to marshal the XML documents
extension modules A, B, C:
provide additional JAXB classes (generated from XSDs)
extensions are registered using Declarative Services
custom annotations
annotation processors to convert the annotation attributes to JAXB based models and generate the XML-document at the expected place
extendee modules X, Y, Z
using the annotation of modules A, B, C
using the annotation processors of A, B, C to generate the XML-documents
Goal: it should be easy to create extendee modules such as X, Y, Z
Everything works fine with Java SE 8 where JAXB is still bundled with the JRE.
Update 1
Because the Maven plugins are not ready I'm stuck with v2.3.3 for now.
I changed the following:
I'm providing a classloader when calling JAXBContext.newInstance
I added the following configuration to the maven-bundle-plugin in several modules:
com.sun.xml.bind.v2, *
This solved the java.lang.ClassNotFoundException: com.sun.xml.bind.v2.ContextFactory issues (it doesn't seem to be the correct solution for this, though), but now the ObjectFactory cannot be located though they were generated.
Update 2
I'm using now a modified jaxb-osgi bundle (see issue) and Apache Aries SPI Fly Dynamic Weaving Bundle (1.3.2) (the reference implementation of the OSGi ServiceLoader Mediator specification) and I added the following requirements to the core module M:
Require-Capability: [...],osgi.extender;filter:="(o
sgi.extender=osgi.serviceloader.processor)",osgi.serviceloader;filter:=
"(osgi.serviceloader=javax.xml.bind.JAXBContextFactory)";cardinality:=m
ultiple,[...]"
The services seem to get detected:
2021-02-13 12:09:31 INFO org.apache.aries.spifly.BaseActivator log - Registered provider com.sun.xml.bind.v2.JAXBContextFactory of service javax.xml.bind.JAXBContextFactory in bundle com.sun.xml.bind.jaxb-osgi
2021-02-13 12:09:31 INFO org.apache.aries.spifly.BaseActivator log - Registered provider com.sun.tools.xjc.addon.code_injector.PluginImpl of service com.sun.tools.xjc.Plugin in bundle com.sun.xml.bind.jaxb-osgi
2021-02-13 12:09:31 INFO org.apache.aries.spifly.BaseActivator log - Registered provider com.sun.tools.xjc.addon.locator.SourceLocationAddOn of service com.sun.tools.xjc.Plugin in bundle com.sun.xml.bind.jaxb-osgi
2021-02-13 12:09:31 INFO org.apache.aries.spifly.BaseActivator log - Registered provider com.sun.tools.xjc.addon.sync.SynchronizedMethodAddOn of service com.sun.tools.xjc.Plugin in bundle com.sun.xml.bind.jaxb-osgi
2021-02-13 12:09:31 INFO org.apache.aries.spifly.BaseActivator log - Registered provider com.sun.tools.xjc.addon.at_generated.PluginImpl of service com.sun.tools.xjc.Plugin in bundle com.sun.xml.bind.jaxb-osgi
2021-02-13 12:09:31 INFO org.apache.aries.spifly.BaseActivator log - Registered provider com.sun.tools.xjc.addon.episode.PluginImpl of service com.sun.tools.xjc.Plugin in bundle com.sun.xml.bind.jaxb-osgi
2021-02-13 12:09:31 INFO org.apache.aries.spifly.BaseActivator log - Registered provider com.sun.tools.xjc.addon.accessors.PluginImpl of service com.sun.tools.xjc.Plugin in bundle com.sun.xml.bind.jaxb-osgi
But I still get:
javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.
- with linked exception:
[java.lang.ClassNotFoundException: com.sun.xml.bind.v2.ContextFactory not found by
Why does it try to load the hard-coded default com.sun.xml.bind.v2.ContextFactory instead of com.sun.xml.bind.v2.JAXBContextFactory via ServiceLoader?
Since each OSGI bundle uses its own classloader the JAXB API is not able to use the standard ServiceLoader to locate the JAXB implementation. However since version 2.2.2 the JAXB API can use osgi-resource-locator as a fallback.
Therefore, in order to use JAXB on Java 11, you just need to:
Add a dependency on the javax.xml.bind and org.glassfish.hk2.osgiresourcelocator packages,
Deploy the osgi-resource-locator and jaxb-osgi bundles together with your bundle.
Remark: if you want to use MOXy, you need additional steps, since MOXy does not ship with a META-INF/services/javax.xml.bind.JAXBContext file (cf. this answer).

Servicemix Spring 4 wiring issue

Edit:
To better/shorter folmulate my main question;
Is it possible to get an OSGI application running using spring-osgi (1.2.1) and Spring 4 at the same time? And if so, how?
Original:
I am trying to make servicemix 6.1.3 work with Spring 4.
I know support has been officially dropped as of Spring version 3 but I need spring 4 for security reasons and frankly keeping our application up to date with newer functionality.
So I imported the required servicemix spring V4 bundles.
The issue here is that our application also uses the spring-osgi functionality (so not the abovementioned osgi-ified bundles by servicemix but the actual spring-osgi bundles which have V 1.2.1 as seen below)
The error:
Error executing command: Error executing command on bundles:
Unable to execute command on bundle 352: Uses constraint violation. Unable to resolve bundle revision my.app.service [352.7] because it is exposed to package 'org.springframework.context.support' from bundle revisions org.apache.servicemix.bundles.spring-
context [240.0] and org.apache.servicemix.bundles.spring-context [105.0] via two dependency chains.
Chain 1:
my.app.service [352.7]
import: (&(osgi.wiring.package=org.springframework.context.support)(version>=4.2.0)(version<=4.4.0))
|
export: osgi.wiring.package=org.springframework.context.support
org.apache.servicemix.bundles.spring-context [240.0]
Chain 2:
my.app.service [352.7]
import: (&(osgi.wiring.package=org.springframework.osgi.web.context.support)(version>=1.2.1))
|
export: osgi.wiring.package=org.springframework.osgi.web.context.support; uses:=org.springframework.osgi.context.support
org.springframework.osgi.web [252.0]
import: (&(osgi.wiring.package=org.springframework.osgi.context.support)(version>=1.2.1)(version<=1.2.1))
|
export: osgi.wiring.package=org.springframework.osgi.context.support; uses:=org.springframework.context.support
org.springframework.osgi.core [109.0]
import: (&(osgi.wiring.package=org.springframework.context.support)(version>=2.5.6)(!(version>=4.0.0)))
|
export: osgi.wiring.package=org.springframework.context.support
org.apache.servicemix.bundles.spring-context [105.0]
Now as you can see the issue is that I have spring-context twice running in servicemix. Once from the default installation [105] (I expect on the background a lot of servicemix's bundles (camel, activeMQ, etc) are using Spring 3, hence I dont want to remove them in fear of other issues; but if you know better, please enlighten me) and a Spring V4 bundle [240].
Our usage of spring-osgi requires us to use its bundles which are hardcoded to use "org.springframework.context.support version>=2.5.6 !version>=4.0.0".
Now my question;
- Is there a way around this? To force org.springframework.osgi.core to use the spring-context V4 bundle? Or is it just impossible to use Spring 4 at the same time as Spring 3's OSGI bundles?
Additional info:
I used the following in my pom's maven-bundle-plugin import-Package tag to enforce usage of Spring 4: (spring.version=[4.2,4.4])
org.springframework.context.support;version="${spring.version}",
And in the parent pom has the following in the dependency-management section.
<dependency>
<groupId>org.apache.servicemix.bundles</groupId>
<artifactId>org.apache.servicemix.bundles.spring-context</artifactId>
<version>${spring.version}</version>
<scope>provided</scope>
</dependency>
Edit 2:
Maybe I can manually bypass the org.springframework.context.support (version>=2.5.6)(!(version>=4.0.0)) requirement by downloading the spring osgi 1.2.x branch from github, change the in the pom and recompile.
Still obviously this isnt a good solution at all sice im hacking myself through to unsupported versions, so please advise.

Osgi ServiceMix ClassCastException

I am having trouble with ServiceMix 5.5.2.
I have a bundle A that contain a class test.java.Root.class and after update of other bundle in ServiceMix my bundle A says:
ClassCastException : class test.java.Root can t be cast to test.java.Root
It the same class...
I know that the real problem is that this class was loading twice by different ClassLoader but I don't know why and when: the class is inside the jar and the package is not exported.
I have done refresh on the bundle but nothing work. Only a ServiceMix restart work :(
How can I find (before restarting and avoid restarting) all references of the class and where reference are still possibly in use?
Does ServiceMix propose Karaf command to see this?

starting slf4j bundle doesn't start on felix

I have felix-framework-5.0.1 and I'm trying to start slf4j-api-1.6.0.jar bundle into felix isgi container.
in felix console I'm typing install file:bundle/slf4j-api-1.6.0.jar
I'm getting a message Bundle ID: 42
then I'm trying to start the bundle start 42
I'm getting the message
org.osgi.framework.BundleException: Unable to resolve slf4j.api [42](R 42.0): missing requirement [slf4j.api [42](R 42.0)] osgi.wiring.package; (&(osgi.wiring.p
ackage=org.slf4j.impl)(version>=1.5.5)) Unresolved requirements: [[slf4j.api [42](R 42.0)] osgi.wiring.package; (&(osgi.wiring.package=org.slf4j.impl)(version>=
1.5.5))]
g!
Can any body help me? how can I start slf4j bundle into felix?
slf4j-api needs org.slf4j.impl package. This package is included into every slf4j implementations like slf4j-simple, slf4j-logback, etc.
The implementation bundles need org.slf4j package that comes from the API artifact. There is a cross-reference. This can work only due to the reason that implementations are fragment bundles of the API. When the implementation is installed together with the API, they will have a common classloader and they will be resolved together. Both of their requirements will be satisfied.
In short: You must choose one of the implementations and install that as well. E.g.: slf4j-simple.
You should use the same version of API and implementation to satisfy their "cross requirement".
Your library contains the following 3 packages (link):
org.slf4j
org.slf4j.helpers
org.slf4j.spi
but you have to have an additional library that will contain org.slf4j.impl package.
Also, from manifest file you can see what packages are exported (Export-Package) (they are visible by other bundles) and what packages are imported (Import-Package) (they have to be accessible for the given bundle). Sometimes the given package have to be from bundle with the correct version.
If you cannot find correct bundle maybe this page will help you.

OSGI, OSGI - bundle and Hazelcast deserialization class not found exception

My Question is
I have two osgi bundles, In which one bundle has hazelcast (3.3 version) jar and I have exported all the packages in it... which means the other bundle can use all the packages of hazelcast available in first bundle.
So what I planned is,
-> One bundle is for keeping the hazelcast jar as common bundle.
-> Other bundle is for performing the business operations in which the first bundle will be the dependent bundle for this,
I have the hazelcast xml which has a serialization factory mapping in it.
Note : The serialization factory class is there in other bundle (Not in hazelcast jar bundle), So what happens is when I start the hazelcast server, It clearly says that the serialization factory class is not found.
com.hazelcast.nio.serialization.HazelcastSerializationException: java.lang.ClassNotFoundException: com.test.beans.SerializableFactory
at com.hazelcast.nio.serialization.SerializationServiceBuilder.buildDataSerializableFactories(SerializationServiceBuilder.java:290)
at com.hazelcast.nio.serialization.SerializationServiceBuilder.addConfigDataSerializableFactories(SerializationServiceBuilder.java:247)
at com.hazelcast.nio.serialization.SerializationServiceBuilder.build(SerializationServiceBuilder.java:169)
at com.hazelcast.instance.Node.createSerializationService(Node.java:193)
at com.hazelcast.instance.Node.<init>(Node.java:140)
at com.hazelcast.instance.HazelcastInstanceImpl.<init>(HazelcastInstanceImpl.java:120)
at com.hazelcast.instance.HazelcastInstanceFactory.constructHazelcastInstance(HazelcastInstanceFactory.java:153)
at com.hazelcast.instance.HazelcastInstanceFactory.newHazelcastInstance(HazelcastInstanceFactory.java:136)
at com.hazelcast.instance.HazelcastInstanceFactory.newHazelcastInstance(HazelcastInstanceFactory.java:112)
at com.hazelcast.core.Hazelcast.newHazelcastInstance(Hazelcast.java:58)
For your INFORMATION, I already tried config.setClassloader

Categories