You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@servicemix.apache.org by Guillaume Nodet <gn...@gmail.com> on 2009/02/19 08:31:33 UTC
[Heads up] Classoading problems with JBI components
Yesterday, I've been trying to deploy Ode in ServiceMix 4 and found
some problems.
The first one was the fact that Ode expects the transaction manager to
implement the org.apache.geronimo.transaction.manager.RecoverableTransactionMaanger.
In order to fix that one (SMX4-51), I've applied the patch attached
partially (so that the spring proxy for the transaction manager
actually implement the above interface) and enhanced the JBI URL
handler to be able to customize the generated manifest header for the
OSGi bundle created for the JBI component (SMX4NMR-93). Using a
dynamic import on the above package (or I suppose a plain import)
works.
The second one was a ClassCastException on a SAX class. For some
reason, the SAX classes loaded by the JBI component were loaded from
the JRE instead of the stax-api OSGi bundle. The reason for that one
is that the first parent of the classloader for the component was the
system bundle instead of the classloader for the component's bundle.
I haven't committed the changes yet, but will do it soon.
The last one is caused by the classloader not being able to load
classes and resources. The exceptions are thrown from the following
code:
ProcessStoreImpl-1@24390 daemon, priority=5, in group 'main', status: 'RUNNING'
at org.apache.felix.framework.URLHandlersBundleStreamHandler.openConnection(URLHandlersBundleStreamHandler.java:69)
at java.net.URL.openConnection(URL.java:943)
at sun.net.www.protocol.jar.JarURLConnection.<init>(JarURLConnection.java:64)
at sun.net.www.protocol.jar.Handler.openConnection(Handler.java:24)
at java.net.URL.openConnection(URL.java:943)
at java.net.URL.openStream(URL.java:1,007)
at java.lang.ClassLoader.getResourceAsStream(ClassLoader.java:1,216)
at java.lang.Class.getResourceAsStream(Class.java:1,998)
at org.apache.openjpa.conf.OpenJPAVersion.<clinit>(OpenJPAVersion.java:50)
at org.apache.openjpa.kernel.AbstractBrokerFactory.getFactoryInitializationBanner(AbstractBrokerFactory.java:663)
at org.apache.openjpa.kernel.AbstractBrokerFactory.makeReadOnly(AbstractBrokerFactory.java:616)
at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:183)
at org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:142)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:192)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:145)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:56)
at org.apache.ode.store.jpa.DbConfStoreConnectionFactory.getConnection(DbConfStoreConnectionFactory.java:49)
at org.apache.ode.store.ProcessStoreImpl.getConnection(ProcessStoreImpl.java:549)
at org.apache.ode.store.ProcessStoreImpl.access$300(ProcessStoreImpl.java:74)
at org.apache.ode.store.ProcessStoreImpl$Callable.call(ProcessStoreImpl.java:698)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:269)
at java.util.concurrent.FutureTask.run(FutureTask.java:123)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
at java.lang.Thread.run(Thread.java:613)
The reason is that the jbi classloader is create with bundle urls
pointing to the libraries embedded in the component.
For example:
bundle://72.0:1/lib/openjpa-1.1.0.jar
Those URLs are resolved correctly to locate resources, so we end up
with urls like:
jar:bundle://72.0:1/lib/openjpa-1.1.0.jar!/org/apache/openjpa/kernel/localizer.properties
Now, the problem is that they fail to be opened at the above point in
the code. THis is because Felix is trying to find on the stack trace
a classloader which is of type
org.apache.felix.framework.searchpolicy.ContentClassLoader (in the
URLHandlers#getFrameworkContext() method). But there's none because
all classes are loaded from the JBI component classloader instead of
a felix classloader in this case.
Anyway, I will try a few things:
* when transforming the JBI artifact to an OSGi bundle, we could
leverage the Bundle-Classpath osgi header to point to the embedded
jars. However, I fear we won't be able to control JBI classloader
self-first / parent-first delegation when doing so
* the bundle content is extracted to a folder
(data/jbi/<name>/install) as required by the JBI spec. We could point
directly to those files instead of using URLs like bundle:// .
Any other idea is welcome.
--
Cheers,
Guillaume Nodet
------------------------
Blog: http://gnodet.blogspot.com/
------------------------
Open Source SOA
http://fusesource.com
Re: [Heads up] Classoading problems with JBI components
Posted by Ulhas Bhole <ul...@progress.com>.
I am also getting some class loading issues with latest SNAPSHOT and in
my nmr is not able to find the classes located in
data/jbi/<name>/install directory. So I may be hitting the same problem
as your last problem so I think your suggestion of loading classes from
this directory might work for me also.
-- Ulhas
Guillaume Nodet wrote:
> Yesterday, I've been trying to deploy Ode in ServiceMix 4 and found
> some problems.
>
> The first one was the fact that Ode expects the transaction manager to
> implement the org.apache.geronimo.transaction.manager.RecoverableTransactionMaanger.
> In order to fix that one (SMX4-51), I've applied the patch attached
> partially (so that the spring proxy for the transaction manager
> actually implement the above interface) and enhanced the JBI URL
> handler to be able to customize the generated manifest header for the
> OSGi bundle created for the JBI component (SMX4NMR-93). Using a
> dynamic import on the above package (or I suppose a plain import)
> works.
>
> The second one was a ClassCastException on a SAX class. For some
> reason, the SAX classes loaded by the JBI component were loaded from
> the JRE instead of the stax-api OSGi bundle. The reason for that one
> is that the first parent of the classloader for the component was the
> system bundle instead of the classloader for the component's bundle.
> I haven't committed the changes yet, but will do it soon.
>
> The last one is caused by the classloader not being able to load
> classes and resources. The exceptions are thrown from the following
> code:
>
> ProcessStoreImpl-1@24390 daemon, priority=5, in group 'main', status: 'RUNNING'
> at org.apache.felix.framework.URLHandlersBundleStreamHandler.openConnection(URLHandlersBundleStreamHandler.java:69)
> at java.net.URL.openConnection(URL.java:943)
> at sun.net.www.protocol.jar.JarURLConnection.<init>(JarURLConnection.java:64)
> at sun.net.www.protocol.jar.Handler.openConnection(Handler.java:24)
> at java.net.URL.openConnection(URL.java:943)
> at java.net.URL.openStream(URL.java:1,007)
> at java.lang.ClassLoader.getResourceAsStream(ClassLoader.java:1,216)
> at java.lang.Class.getResourceAsStream(Class.java:1,998)
> at org.apache.openjpa.conf.OpenJPAVersion.<clinit>(OpenJPAVersion.java:50)
> at org.apache.openjpa.kernel.AbstractBrokerFactory.getFactoryInitializationBanner(AbstractBrokerFactory.java:663)
> at org.apache.openjpa.kernel.AbstractBrokerFactory.makeReadOnly(AbstractBrokerFactory.java:616)
> at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:183)
> at org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:142)
> at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:192)
> at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:145)
> at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:56)
> at org.apache.ode.store.jpa.DbConfStoreConnectionFactory.getConnection(DbConfStoreConnectionFactory.java:49)
> at org.apache.ode.store.ProcessStoreImpl.getConnection(ProcessStoreImpl.java:549)
> at org.apache.ode.store.ProcessStoreImpl.access$300(ProcessStoreImpl.java:74)
> at org.apache.ode.store.ProcessStoreImpl$Callable.call(ProcessStoreImpl.java:698)
> at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:269)
> at java.util.concurrent.FutureTask.run(FutureTask.java:123)
> at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
> at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
> at java.lang.Thread.run(Thread.java:613)
>
> The reason is that the jbi classloader is create with bundle urls
> pointing to the libraries embedded in the component.
> For example:
> bundle://72.0:1/lib/openjpa-1.1.0.jar
> Those URLs are resolved correctly to locate resources, so we end up
> with urls like:
> jar:bundle://72.0:1/lib/openjpa-1.1.0.jar!/org/apache/openjpa/kernel/localizer.properties
> Now, the problem is that they fail to be opened at the above point in
> the code. THis is because Felix is trying to find on the stack trace
> a classloader which is of type
> org.apache.felix.framework.searchpolicy.ContentClassLoader (in the
> URLHandlers#getFrameworkContext() method). But there's none because
> all classes are loaded from the JBI component classloader instead of
> a felix classloader in this case.
>
> Anyway, I will try a few things:
> * when transforming the JBI artifact to an OSGi bundle, we could
> leverage the Bundle-Classpath osgi header to point to the embedded
> jars. However, I fear we won't be able to control JBI classloader
> self-first / parent-first delegation when doing so
> * the bundle content is extracted to a folder
> (data/jbi/<name>/install) as required by the JBI spec. We could point
> directly to those files instead of using URLs like bundle:// .
>
> Any other idea is welcome.
>
>
Re: [Heads up] Classoading problems with JBI components
Posted by jb...@nanthrax.net.
Ok, thanks for the clarification Guillaume.
Regards
JB
On Friday 20 February 2009 - 13:22, Guillaume Nodet wrote:
> In the kernel, we just handle everything through OSGi, which is much
> more powerful than just self-first / parent-first style delegation.
>
> 2009/2/20 jb <jb...@nanthrax.net>:
> > Thanks for this feedback Guillaume.
> >
> > Concerning the classloading issue, maybe it can interested to define a classloading
> > policy in the kernel (as we have parent-first/parent-last in application servers) ?
> > From a technical point of view, I don't know if it's possible and, for now, how it can be
> > implemented, but from an usage point of view, it can be interesting.
> >
> > Regards
> > JB
> >
> > On Thursday 19 February 2009 - 08:31, Guillaume Nodet wrote:
> >> Yesterday, I've been trying to deploy Ode in ServiceMix 4 and found
> >> some problems.
> >>
> >> The first one was the fact that Ode expects the transaction manager to
> >> implement the org.apache.geronimo.transaction.manager.RecoverableTransactionMaanger.
> >> In order to fix that one (SMX4-51), I've applied the patch attached
> >> partially (so that the spring proxy for the transaction manager
> >> actually implement the above interface) and enhanced the JBI URL
> >> handler to be able to customize the generated manifest header for the
> >> OSGi bundle created for the JBI component (SMX4NMR-93). Using a
> >> dynamic import on the above package (or I suppose a plain import)
> >> works.
> >>
> >> The second one was a ClassCastException on a SAX class. For some
> >> reason, the SAX classes loaded by the JBI component were loaded from
> >> the JRE instead of the stax-api OSGi bundle. The reason for that one
> >> is that the first parent of the classloader for the component was the
> >> system bundle instead of the classloader for the component's bundle.
> >> I haven't committed the changes yet, but will do it soon.
> >>
> >> The last one is caused by the classloader not being able to load
> >> classes and resources. The exceptions are thrown from the following
> >> code:
> >>
> >> ProcessStoreImpl-1@24390 daemon, priority=5, in group 'main', status: 'RUNNING'
> >> at org.apache.felix.framework.URLHandlersBundleStreamHandler.openConnection(URLHandlersBundleStreamHandler.java:69)
> >> at java.net.URL.openConnection(URL.java:943)
> >> at sun.net.www.protocol.jar.JarURLConnection.<init>(JarURLConnection.java:64)
> >> at sun.net.www.protocol.jar.Handler.openConnection(Handler.java:24)
> >> at java.net.URL.openConnection(URL.java:943)
> >> at java.net.URL.openStream(URL.java:1,007)
> >> at java.lang.ClassLoader.getResourceAsStream(ClassLoader.java:1,216)
> >> at java.lang.Class.getResourceAsStream(Class.java:1,998)
> >> at org.apache.openjpa.conf.OpenJPAVersion.<clinit>(OpenJPAVersion.java:50)
> >> at org.apache.openjpa.kernel.AbstractBrokerFactory.getFactoryInitializationBanner(AbstractBrokerFactory.java:663)
> >> at org.apache.openjpa.kernel.AbstractBrokerFactory.makeReadOnly(AbstractBrokerFactory.java:616)
> >> at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:183)
> >> at org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:142)
> >> at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:192)
> >> at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:145)
> >> at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:56)
> >> at org.apache.ode.store.jpa.DbConfStoreConnectionFactory.getConnection(DbConfStoreConnectionFactory.java:49)
> >> at org.apache.ode.store.ProcessStoreImpl.getConnection(ProcessStoreImpl.java:549)
> >> at org.apache.ode.store.ProcessStoreImpl.access$300(ProcessStoreImpl.java:74)
> >> at org.apache.ode.store.ProcessStoreImpl$Callable.call(ProcessStoreImpl.java:698)
> >> at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:269)
> >> at java.util.concurrent.FutureTask.run(FutureTask.java:123)
> >> at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
> >> at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
> >> at java.lang.Thread.run(Thread.java:613)
> >>
> >> The reason is that the jbi classloader is create with bundle urls
> >> pointing to the libraries embedded in the component.
> >> For example:
> >> bundle://72.0:1/lib/openjpa-1.1.0.jar
> >> Those URLs are resolved correctly to locate resources, so we end up
> >> with urls like:
> >> jar:bundle://72.0:1/lib/openjpa-1.1.0.jar!/org/apache/openjpa/kernel/localizer.properties
> >> Now, the problem is that they fail to be opened at the above point in
> >> the code. THis is because Felix is trying to find on the stack trace
> >> a classloader which is of type
> >> org.apache.felix.framework.searchpolicy.ContentClassLoader (in the
> >> URLHandlers#getFrameworkContext() method). But there's none because
> >> all classes are loaded from the JBI component classloader instead of
> >> a felix classloader in this case.
> >>
> >> Anyway, I will try a few things:
> >> * when transforming the JBI artifact to an OSGi bundle, we could
> >> leverage the Bundle-Classpath osgi header to point to the embedded
> >> jars. However, I fear we won't be able to control JBI classloader
> >> self-first / parent-first delegation when doing so
> >> * the bundle content is extracted to a folder
> >> (data/jbi/<name>/install) as required by the JBI spec. We could point
> >> directly to those files instead of using URLs like bundle:// .
> >>
> >> Any other idea is welcome.
> >>
> >> --
> >> Cheers,
> >> Guillaume Nodet
> >> ------------------------
> >> Blog: http://gnodet.blogspot.com/
> >> ------------------------
> >> Open Source SOA
> >> http://fusesource.com
> >
>
>
>
> --
> Cheers,
> Guillaume Nodet
> ------------------------
> Blog: http://gnodet.blogspot.com/
> ------------------------
> Open Source SOA
> http://fusesource.com
Re: [Heads up] Classoading problems with JBI components
Posted by Guillaume Nodet <gn...@gmail.com>.
In the kernel, we just handle everything through OSGi, which is much
more powerful than just self-first / parent-first style delegation.
2009/2/20 jb <jb...@nanthrax.net>:
> Thanks for this feedback Guillaume.
>
> Concerning the classloading issue, maybe it can interested to define a classloading
> policy in the kernel (as we have parent-first/parent-last in application servers) ?
> From a technical point of view, I don't know if it's possible and, for now, how it can be
> implemented, but from an usage point of view, it can be interesting.
>
> Regards
> JB
>
> On Thursday 19 February 2009 - 08:31, Guillaume Nodet wrote:
>> Yesterday, I've been trying to deploy Ode in ServiceMix 4 and found
>> some problems.
>>
>> The first one was the fact that Ode expects the transaction manager to
>> implement the org.apache.geronimo.transaction.manager.RecoverableTransactionMaanger.
>> In order to fix that one (SMX4-51), I've applied the patch attached
>> partially (so that the spring proxy for the transaction manager
>> actually implement the above interface) and enhanced the JBI URL
>> handler to be able to customize the generated manifest header for the
>> OSGi bundle created for the JBI component (SMX4NMR-93). Using a
>> dynamic import on the above package (or I suppose a plain import)
>> works.
>>
>> The second one was a ClassCastException on a SAX class. For some
>> reason, the SAX classes loaded by the JBI component were loaded from
>> the JRE instead of the stax-api OSGi bundle. The reason for that one
>> is that the first parent of the classloader for the component was the
>> system bundle instead of the classloader for the component's bundle.
>> I haven't committed the changes yet, but will do it soon.
>>
>> The last one is caused by the classloader not being able to load
>> classes and resources. The exceptions are thrown from the following
>> code:
>>
>> ProcessStoreImpl-1@24390 daemon, priority=5, in group 'main', status: 'RUNNING'
>> at org.apache.felix.framework.URLHandlersBundleStreamHandler.openConnection(URLHandlersBundleStreamHandler.java:69)
>> at java.net.URL.openConnection(URL.java:943)
>> at sun.net.www.protocol.jar.JarURLConnection.<init>(JarURLConnection.java:64)
>> at sun.net.www.protocol.jar.Handler.openConnection(Handler.java:24)
>> at java.net.URL.openConnection(URL.java:943)
>> at java.net.URL.openStream(URL.java:1,007)
>> at java.lang.ClassLoader.getResourceAsStream(ClassLoader.java:1,216)
>> at java.lang.Class.getResourceAsStream(Class.java:1,998)
>> at org.apache.openjpa.conf.OpenJPAVersion.<clinit>(OpenJPAVersion.java:50)
>> at org.apache.openjpa.kernel.AbstractBrokerFactory.getFactoryInitializationBanner(AbstractBrokerFactory.java:663)
>> at org.apache.openjpa.kernel.AbstractBrokerFactory.makeReadOnly(AbstractBrokerFactory.java:616)
>> at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:183)
>> at org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:142)
>> at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:192)
>> at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:145)
>> at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:56)
>> at org.apache.ode.store.jpa.DbConfStoreConnectionFactory.getConnection(DbConfStoreConnectionFactory.java:49)
>> at org.apache.ode.store.ProcessStoreImpl.getConnection(ProcessStoreImpl.java:549)
>> at org.apache.ode.store.ProcessStoreImpl.access$300(ProcessStoreImpl.java:74)
>> at org.apache.ode.store.ProcessStoreImpl$Callable.call(ProcessStoreImpl.java:698)
>> at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:269)
>> at java.util.concurrent.FutureTask.run(FutureTask.java:123)
>> at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
>> at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
>> at java.lang.Thread.run(Thread.java:613)
>>
>> The reason is that the jbi classloader is create with bundle urls
>> pointing to the libraries embedded in the component.
>> For example:
>> bundle://72.0:1/lib/openjpa-1.1.0.jar
>> Those URLs are resolved correctly to locate resources, so we end up
>> with urls like:
>> jar:bundle://72.0:1/lib/openjpa-1.1.0.jar!/org/apache/openjpa/kernel/localizer.properties
>> Now, the problem is that they fail to be opened at the above point in
>> the code. THis is because Felix is trying to find on the stack trace
>> a classloader which is of type
>> org.apache.felix.framework.searchpolicy.ContentClassLoader (in the
>> URLHandlers#getFrameworkContext() method). But there's none because
>> all classes are loaded from the JBI component classloader instead of
>> a felix classloader in this case.
>>
>> Anyway, I will try a few things:
>> * when transforming the JBI artifact to an OSGi bundle, we could
>> leverage the Bundle-Classpath osgi header to point to the embedded
>> jars. However, I fear we won't be able to control JBI classloader
>> self-first / parent-first delegation when doing so
>> * the bundle content is extracted to a folder
>> (data/jbi/<name>/install) as required by the JBI spec. We could point
>> directly to those files instead of using URLs like bundle:// .
>>
>> Any other idea is welcome.
>>
>> --
>> Cheers,
>> Guillaume Nodet
>> ------------------------
>> Blog: http://gnodet.blogspot.com/
>> ------------------------
>> Open Source SOA
>> http://fusesource.com
>
--
Cheers,
Guillaume Nodet
------------------------
Blog: http://gnodet.blogspot.com/
------------------------
Open Source SOA
http://fusesource.com
Re: [Heads up] Classoading problems with JBI components
Posted by jb...@nanthrax.net.
Thanks for this feedback Guillaume.
Concerning the classloading issue, maybe it can interested to define a classloading
policy in the kernel (as we have parent-first/parent-last in application servers) ?
>From a technical point of view, I don't know if it's possible and, for now, how it can be
implemented, but from an usage point of view, it can be interesting.
Regards
JB
On Thursday 19 February 2009 - 08:31, Guillaume Nodet wrote:
> Yesterday, I've been trying to deploy Ode in ServiceMix 4 and found
> some problems.
>
> The first one was the fact that Ode expects the transaction manager to
> implement the org.apache.geronimo.transaction.manager.RecoverableTransactionMaanger.
> In order to fix that one (SMX4-51), I've applied the patch attached
> partially (so that the spring proxy for the transaction manager
> actually implement the above interface) and enhanced the JBI URL
> handler to be able to customize the generated manifest header for the
> OSGi bundle created for the JBI component (SMX4NMR-93). Using a
> dynamic import on the above package (or I suppose a plain import)
> works.
>
> The second one was a ClassCastException on a SAX class. For some
> reason, the SAX classes loaded by the JBI component were loaded from
> the JRE instead of the stax-api OSGi bundle. The reason for that one
> is that the first parent of the classloader for the component was the
> system bundle instead of the classloader for the component's bundle.
> I haven't committed the changes yet, but will do it soon.
>
> The last one is caused by the classloader not being able to load
> classes and resources. The exceptions are thrown from the following
> code:
>
> ProcessStoreImpl-1@24390 daemon, priority=5, in group 'main', status: 'RUNNING'
> at org.apache.felix.framework.URLHandlersBundleStreamHandler.openConnection(URLHandlersBundleStreamHandler.java:69)
> at java.net.URL.openConnection(URL.java:943)
> at sun.net.www.protocol.jar.JarURLConnection.<init>(JarURLConnection.java:64)
> at sun.net.www.protocol.jar.Handler.openConnection(Handler.java:24)
> at java.net.URL.openConnection(URL.java:943)
> at java.net.URL.openStream(URL.java:1,007)
> at java.lang.ClassLoader.getResourceAsStream(ClassLoader.java:1,216)
> at java.lang.Class.getResourceAsStream(Class.java:1,998)
> at org.apache.openjpa.conf.OpenJPAVersion.<clinit>(OpenJPAVersion.java:50)
> at org.apache.openjpa.kernel.AbstractBrokerFactory.getFactoryInitializationBanner(AbstractBrokerFactory.java:663)
> at org.apache.openjpa.kernel.AbstractBrokerFactory.makeReadOnly(AbstractBrokerFactory.java:616)
> at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:183)
> at org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:142)
> at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:192)
> at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:145)
> at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:56)
> at org.apache.ode.store.jpa.DbConfStoreConnectionFactory.getConnection(DbConfStoreConnectionFactory.java:49)
> at org.apache.ode.store.ProcessStoreImpl.getConnection(ProcessStoreImpl.java:549)
> at org.apache.ode.store.ProcessStoreImpl.access$300(ProcessStoreImpl.java:74)
> at org.apache.ode.store.ProcessStoreImpl$Callable.call(ProcessStoreImpl.java:698)
> at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:269)
> at java.util.concurrent.FutureTask.run(FutureTask.java:123)
> at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
> at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
> at java.lang.Thread.run(Thread.java:613)
>
> The reason is that the jbi classloader is create with bundle urls
> pointing to the libraries embedded in the component.
> For example:
> bundle://72.0:1/lib/openjpa-1.1.0.jar
> Those URLs are resolved correctly to locate resources, so we end up
> with urls like:
> jar:bundle://72.0:1/lib/openjpa-1.1.0.jar!/org/apache/openjpa/kernel/localizer.properties
> Now, the problem is that they fail to be opened at the above point in
> the code. THis is because Felix is trying to find on the stack trace
> a classloader which is of type
> org.apache.felix.framework.searchpolicy.ContentClassLoader (in the
> URLHandlers#getFrameworkContext() method). But there's none because
> all classes are loaded from the JBI component classloader instead of
> a felix classloader in this case.
>
> Anyway, I will try a few things:
> * when transforming the JBI artifact to an OSGi bundle, we could
> leverage the Bundle-Classpath osgi header to point to the embedded
> jars. However, I fear we won't be able to control JBI classloader
> self-first / parent-first delegation when doing so
> * the bundle content is extracted to a folder
> (data/jbi/<name>/install) as required by the JBI spec. We could point
> directly to those files instead of using URLs like bundle:// .
>
> Any other idea is welcome.
>
> --
> Cheers,
> Guillaume Nodet
> ------------------------
> Blog: http://gnodet.blogspot.com/
> ------------------------
> Open Source SOA
> http://fusesource.com
Re: [Heads up] Classoading problems with JBI components
Posted by Guillaume Nodet <gn...@gmail.com>.
On Thu, Feb 19, 2009 at 09:46, Gert Vanthienen
<ge...@skynet.be> wrote:
> Guillaume,
>
> Nice work, looks like there were a few hard nuts to crack down the road...
>
> For the classloader question, wouldn't it be possible to somehow create OSGi
> classloaders to implement the JBI classloading architecture as well. This
> would deal with the problem and it would allow you to fine-tune OSGi and JBI
> integration for e.g. a SU classloader afterwards as well?
Not sure if we can completely mimic the JBI classloading mechanism
specified in the spec using OSGi classloaders.
OSGi classloaders resolve classes in the following way:
* boot classpath delegation
* if the class has not been found and the class is in the java.*
packages, throw CNFE
* search static imports
* search the bundle
* search dynamic imports
The JBI spec has the following ordering rules:
* component classloader if self-first delegation
* shared libraries
* jbi classloader
* component classloader if parent-first delegation
In addition, java.* and javax.* must always be loaded from the jbi
classloader first
The only way I've been thinking of to do that would be to scan all
jars in the component classpath for imported packages. If the
delegation is parent-first, the components' bundle would import all
those packages with an optional import (so that the bundle resolution
won't fail). For shared libraries, using Require-Bundle could work.
I guess one problem would be a component that uses Class.forName().
In such a case I don't think there is a way to delegate to the parents
first. Though as we know all the classes in the component
classloader, the search will either find a known class (inside the
imported packages, then the bundle) or fail.
So I think it may be possible through the use of bnd tool, lots of
optional imports, Require-Bundle and Bundle-Classpath ...
> If that's not a solution, I'd rather opt for the second solution -- go for
> the simple solution of using the expanded files.
I have a patch ready. I will commit it and investigate the first
solution later.
> Regards,
>
> Gert
>
> Guillaume Nodet wrote:
>>
>> Yesterday, I've been trying to deploy Ode in ServiceMix 4 and found
>> some problems.
>>
>> The first one was the fact that Ode expects the transaction manager to
>> implement the
>> org.apache.geronimo.transaction.manager.RecoverableTransactionMaanger.
>> In order to fix that one (SMX4-51), I've applied the patch attached
>> partially (so that the spring proxy for the transaction manager
>> actually implement the above interface) and enhanced the JBI URL
>> handler to be able to customize the generated manifest header for the
>> OSGi bundle created for the JBI component (SMX4NMR-93). Using a
>> dynamic import on the above package (or I suppose a plain import)
>> works.
>>
>> The second one was a ClassCastException on a SAX class. For some
>> reason, the SAX classes loaded by the JBI component were loaded from
>> the JRE instead of the stax-api OSGi bundle. The reason for that one
>> is that the first parent of the classloader for the component was the
>> system bundle instead of the classloader for the component's bundle.
>> I haven't committed the changes yet, but will do it soon.
>>
>> The last one is caused by the classloader not being able to load
>> classes and resources. The exceptions are thrown from the following
>> code:
>>
>> ProcessStoreImpl-1@24390 daemon, priority=5, in group 'main', status:
>> 'RUNNING'
>> at
>> org.apache.felix.framework.URLHandlersBundleStreamHandler.openConnection(URLHandlersBundleStreamHandler.java:69)
>> at java.net.URL.openConnection(URL.java:943)
>> at
>> sun.net.www.protocol.jar.JarURLConnection.<init>(JarURLConnection.java:64)
>> at
>> sun.net.www.protocol.jar.Handler.openConnection(Handler.java:24)
>> at java.net.URL.openConnection(URL.java:943)
>> at java.net.URL.openStream(URL.java:1,007)
>> at
>> java.lang.ClassLoader.getResourceAsStream(ClassLoader.java:1,216)
>> at java.lang.Class.getResourceAsStream(Class.java:1,998)
>> at
>> org.apache.openjpa.conf.OpenJPAVersion.<clinit>(OpenJPAVersion.java:50)
>> at
>> org.apache.openjpa.kernel.AbstractBrokerFactory.getFactoryInitializationBanner(AbstractBrokerFactory.java:663)
>> at
>> org.apache.openjpa.kernel.AbstractBrokerFactory.makeReadOnly(AbstractBrokerFactory.java:616)
>> at
>> org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:183)
>> at
>> org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:142)
>> at
>> org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:192)
>> at
>> org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:145)
>> at
>> org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:56)
>> at
>> org.apache.ode.store.jpa.DbConfStoreConnectionFactory.getConnection(DbConfStoreConnectionFactory.java:49)
>> at
>> org.apache.ode.store.ProcessStoreImpl.getConnection(ProcessStoreImpl.java:549)
>> at
>> org.apache.ode.store.ProcessStoreImpl.access$300(ProcessStoreImpl.java:74)
>> at
>> org.apache.ode.store.ProcessStoreImpl$Callable.call(ProcessStoreImpl.java:698)
>> at
>> java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:269)
>> at java.util.concurrent.FutureTask.run(FutureTask.java:123)
>> at
>> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
>> at
>> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
>> at java.lang.Thread.run(Thread.java:613)
>>
>> The reason is that the jbi classloader is create with bundle urls
>> pointing to the libraries embedded in the component.
>> For example:
>> bundle://72.0:1/lib/openjpa-1.1.0.jar
>> Those URLs are resolved correctly to locate resources, so we end up
>> with urls like:
>>
>> jar:bundle://72.0:1/lib/openjpa-1.1.0.jar!/org/apache/openjpa/kernel/localizer.properties
>> Now, the problem is that they fail to be opened at the above point in
>> the code. THis is because Felix is trying to find on the stack trace
>> a classloader which is of type
>> org.apache.felix.framework.searchpolicy.ContentClassLoader (in the
>> URLHandlers#getFrameworkContext() method). But there's none because
>> all classes are loaded from the JBI component classloader instead of
>> a felix classloader in this case.
>>
>> Anyway, I will try a few things:
>> * when transforming the JBI artifact to an OSGi bundle, we could
>> leverage the Bundle-Classpath osgi header to point to the embedded
>> jars. However, I fear we won't be able to control JBI classloader
>> self-first / parent-first delegation when doing so
>> * the bundle content is extracted to a folder
>> (data/jbi/<name>/install) as required by the JBI spec. We could point
>> directly to those files instead of using URLs like bundle:// .
>>
>> Any other idea is welcome.
>>
>>
>
>
--
Cheers,
Guillaume Nodet
------------------------
Blog: http://gnodet.blogspot.com/
------------------------
Open Source SOA
http://fusesource.com
Re: [Heads up] Classoading problems with JBI components
Posted by Gert Vanthienen <ge...@skynet.be>.
Guillaume,
Nice work, looks like there were a few hard nuts to crack down the road...
For the classloader question, wouldn't it be possible to somehow create
OSGi classloaders to implement the JBI classloading architecture as
well. This would deal with the problem and it would allow you to
fine-tune OSGi and JBI integration for e.g. a SU classloader afterwards
as well?
If that's not a solution, I'd rather opt for the second solution -- go
for the simple solution of using the expanded files.
Regards,
Gert
Guillaume Nodet wrote:
> Yesterday, I've been trying to deploy Ode in ServiceMix 4 and found
> some problems.
>
> The first one was the fact that Ode expects the transaction manager to
> implement the org.apache.geronimo.transaction.manager.RecoverableTransactionMaanger.
> In order to fix that one (SMX4-51), I've applied the patch attached
> partially (so that the spring proxy for the transaction manager
> actually implement the above interface) and enhanced the JBI URL
> handler to be able to customize the generated manifest header for the
> OSGi bundle created for the JBI component (SMX4NMR-93). Using a
> dynamic import on the above package (or I suppose a plain import)
> works.
>
> The second one was a ClassCastException on a SAX class. For some
> reason, the SAX classes loaded by the JBI component were loaded from
> the JRE instead of the stax-api OSGi bundle. The reason for that one
> is that the first parent of the classloader for the component was the
> system bundle instead of the classloader for the component's bundle.
> I haven't committed the changes yet, but will do it soon.
>
> The last one is caused by the classloader not being able to load
> classes and resources. The exceptions are thrown from the following
> code:
>
> ProcessStoreImpl-1@24390 daemon, priority=5, in group 'main', status: 'RUNNING'
> at org.apache.felix.framework.URLHandlersBundleStreamHandler.openConnection(URLHandlersBundleStreamHandler.java:69)
> at java.net.URL.openConnection(URL.java:943)
> at sun.net.www.protocol.jar.JarURLConnection.<init>(JarURLConnection.java:64)
> at sun.net.www.protocol.jar.Handler.openConnection(Handler.java:24)
> at java.net.URL.openConnection(URL.java:943)
> at java.net.URL.openStream(URL.java:1,007)
> at java.lang.ClassLoader.getResourceAsStream(ClassLoader.java:1,216)
> at java.lang.Class.getResourceAsStream(Class.java:1,998)
> at org.apache.openjpa.conf.OpenJPAVersion.<clinit>(OpenJPAVersion.java:50)
> at org.apache.openjpa.kernel.AbstractBrokerFactory.getFactoryInitializationBanner(AbstractBrokerFactory.java:663)
> at org.apache.openjpa.kernel.AbstractBrokerFactory.makeReadOnly(AbstractBrokerFactory.java:616)
> at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:183)
> at org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:142)
> at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:192)
> at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:145)
> at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:56)
> at org.apache.ode.store.jpa.DbConfStoreConnectionFactory.getConnection(DbConfStoreConnectionFactory.java:49)
> at org.apache.ode.store.ProcessStoreImpl.getConnection(ProcessStoreImpl.java:549)
> at org.apache.ode.store.ProcessStoreImpl.access$300(ProcessStoreImpl.java:74)
> at org.apache.ode.store.ProcessStoreImpl$Callable.call(ProcessStoreImpl.java:698)
> at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:269)
> at java.util.concurrent.FutureTask.run(FutureTask.java:123)
> at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
> at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
> at java.lang.Thread.run(Thread.java:613)
>
> The reason is that the jbi classloader is create with bundle urls
> pointing to the libraries embedded in the component.
> For example:
> bundle://72.0:1/lib/openjpa-1.1.0.jar
> Those URLs are resolved correctly to locate resources, so we end up
> with urls like:
> jar:bundle://72.0:1/lib/openjpa-1.1.0.jar!/org/apache/openjpa/kernel/localizer.properties
> Now, the problem is that they fail to be opened at the above point in
> the code. THis is because Felix is trying to find on the stack trace
> a classloader which is of type
> org.apache.felix.framework.searchpolicy.ContentClassLoader (in the
> URLHandlers#getFrameworkContext() method). But there's none because
> all classes are loaded from the JBI component classloader instead of
> a felix classloader in this case.
>
> Anyway, I will try a few things:
> * when transforming the JBI artifact to an OSGi bundle, we could
> leverage the Bundle-Classpath osgi header to point to the embedded
> jars. However, I fear we won't be able to control JBI classloader
> self-first / parent-first delegation when doing so
> * the bundle content is extracted to a folder
> (data/jbi/<name>/install) as required by the JBI spec. We could point
> directly to those files instead of using URLs like bundle:// .
>
> Any other idea is welcome.
>
>