You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@felix.apache.org by Alessandro Gherardi <al...@yahoo.com.INVALID> on 2016/09/06 16:46:38 UTC

Issues with embedded Felix framework and JAXRS

Hi,I have a non-OSGi Java app that loads an OSGi bundle by embedding Felix. The bundle exposes its functionality as an OSGi service. The app accesses the service via a service tracker. The app uses the org.osgi.framework.system.packages.extra option so that the service interface and the classes that the interfaces refers to are all loaded by the same classloader in both the app and the bundle.
The bundle uses Jersey 2.X and the app uses Jersey 1.17. When the app calls the bundle via the service, the Jersey 2.X code throws the following exception:
Exception in thread "main" java.lang.LinkageError: ClassCastException: attempting to castfile:/C:/XXX/bin/javax/ws/rs/ext/RuntimeDelegate.class to bundle://59.1:1/javax/ws/rs/ext/RuntimeDelegate.classat javax.ws.rs.ext.RuntimeDelegate.findDelegate(RuntimeDelegate.java:146) at javax.ws.rs.ext.RuntimeDelegate.getInstance(RuntimeDelegate.java:120) at javax.ws.rs.core.UriBuilder.newInstance(UriBuilder.java:95)...
Looking at the Jersey source code, it appears that RuntimeDelegate tries to load a concrete subclass via javax.ws.rs.ext.FactoryFinder. FactoryFinder reads the name of the subclass from file META-INF/services/javax.ws.rs.ext.RuntimeDelegate, and it loads that file via the calling threads's context class loader. Since the calling thread is an application's thread, its class loader is the application's class loader, so META-INF/services/javax.ws.rs.ext.RuntimeDelegate points to a Jersey 1.17 class.
I can kind-of workaround the problem by setting the application thread to an "empty" class loader before calling the service - i.e.:
ClassLoader saveCL = Thread.currentThread().getContextClassLoader();
ClassLoader myCL = new URLClassLoader(new URL[0], saveCL.getParent());
try {
  Thread.currentThread().setContextClassLoader(myCL);
  call OSGi service
} finally {
  Thrad.currentThread().setContextClassloader(saveCL);
}

However, I'm surprised I have to do that. Shouldn't the framework take care of this - even if the service caller is the embedded application rather than another OSGi bundle?
Notice: This issue may or may not be related to  commons-logging and Axis problems
Thank you in advance,Alessandro
  
|  
|   
|   
|   |    |

   |

  |
|  
|   |  
commons-logging and Axis problems
   |   |

  |

  |

 


Re: Issues with embedded Felix framework and JAXRS

Posted by David Bosschaert <da...@gmail.com>.
FWIW, if you need to set the TCCL in OSGi, the Apache Aries SPI Fly
component may be of help: http://aries.apache.org/modules/spi-fly.html

Best regards,

David

On 6 September 2016 at 19:07, Raymond Auge <ra...@liferay.com> wrote:

> Context classloaders are an Java EE construct and not something that OSGi
> frameworks usually care about. Therefore, when running OSGi embedded in a
> JavaEE container you generally need to do all the work to ensure TCCL's are
> properly handled.
>
> Sincerely,
> - Ray
>
> On Tue, Sep 6, 2016 at 12:46 PM, Alessandro Gherardi <
> alessandro.gherardi@yahoo.com.invalid> wrote:
>
> > Hi,I have a non-OSGi Java app that loads an OSGi bundle by embedding
> > Felix. The bundle exposes its functionality as an OSGi service. The app
> > accesses the service via a service tracker. The app uses the
> > org.osgi.framework.system.packages.extra option so that the service
> > interface and the classes that the interfaces refers to are all loaded by
> > the same classloader in both the app and the bundle.
> > The bundle uses Jersey 2.X and the app uses Jersey 1.17. When the app
> > calls the bundle via the service, the Jersey 2.X code throws the
> following
> > exception:
> > Exception in thread "main" java.lang.LinkageError: ClassCastException:
> > attempting to castfile:/C:/XXX/bin/javax/ws/rs/ext/RuntimeDelegate.class
> > to bundle://59.1:1/javax/ws/rs/ext/RuntimeDelegate.classat
> > javax.ws.rs.ext.RuntimeDelegate.findDelegate(RuntimeDelegate.java:146)
> at
> > javax.ws.rs.ext.RuntimeDelegate.getInstance(RuntimeDelegate.java:120) at
> > javax.ws.rs.core.UriBuilder.newInstance(UriBuilder.java:95)...
> > Looking at the Jersey source code, it appears that RuntimeDelegate tries
> > to load a concrete subclass via javax.ws.rs.ext.FactoryFinder.
> > FactoryFinder reads the name of the subclass from file META-INF/services/
> > javax.ws.rs.ext.RuntimeDelegate, and it loads that file via the calling
> > threads's context class loader. Since the calling thread is an
> > application's thread, its class loader is the application's class loader,
> > so META-INF/services/javax.ws.rs.ext.RuntimeDelegate points to a Jersey
> > 1.17 class.
> > I can kind-of workaround the problem by setting the application thread to
> > an "empty" class loader before calling the service - i.e.:
> > ClassLoader saveCL = Thread.currentThread().getContextClassLoader();
> > ClassLoader myCL = new URLClassLoader(new URL[0], saveCL.getParent());
> > try {
> >   Thread.currentThread().setContextClassLoader(myCL);
> >   call OSGi service
> > } finally {
> >   Thrad.currentThread().setContextClassloader(saveCL);
> > }
> >
> > However, I'm surprised I have to do that. Shouldn't the framework take
> > care of this - even if the service caller is the embedded application
> > rather than another OSGi bundle?
> > Notice: This issue may or may not be related to  commons-logging and Axis
> > problems
> > Thank you in advance,Alessandro
> >
> > |
> > |
> > |
> > |   |    |
> >
> >    |
> >
> >   |
> > |
> > |   |
> > commons-logging and Axis problems
> >    |   |
> >
> >   |
> >
> >   |
> >
> >
> >
> >
>
>
> --
> *Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile>
>  (@rotty3000)
> Senior Software Architect *Liferay, Inc.* <http://www.liferay.com>
>  (@Liferay)
> Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org>
> (@OSGiAlliance)
>

Re: Issues with embedded Felix framework and JAXRS

Posted by Alessandro Gherardi <al...@yahoo.com.INVALID>.
Thank you.
One more question: If I only want to include one service in SPI-Provider - i.e., no * wildcard - should I set SPI-Provider to the name of the file under META-INF/services, or to the name of the class contained in that file?
For instance, say I have META-INF/services/org.apache.cxf.bus.factory, and that file contains org.apache.cxf.bus.spring.SpringBusFactory .
Should I set:
SPI-Provider: org.apache.cxf.bus.factory
or
SPI-Provider: org.apache.cxf.bus.spring.SpringBusFactory



      From: Raymond Auge <ra...@liferay.com>
 To: felix users <us...@felix.apache.org>; Alessandro Gherardi <al...@yahoo.com> 
 Sent: Tuesday, September 6, 2016 1:08 PM
 Subject: Re: Issues with embedded Felix framework and JAXRS
   
The issue remains with libraries designed for Java EE, they use TCCL
themselves because this has been forced upon them.

You'll have to do as David suggested and use SPI-Fly providing the
requirements and capabilities to the bundles in question to ensure that the
SPY-fly can wire the bundles together properly and do the instrumentation
necessary to make it all work.

- Ray

On Tue, Sep 6, 2016 at 2:50 PM, Alessandro Gherardi <
alessandro.gherardi@yahoo.com.invalid> wrote:

>
> Thanks.
> However, my application is NOT running within a J2EE container - it's a
> stand-alone, J2SE application started via java -cp ... path.to.main.class.
>
>
>
>      From: Raymond Auge <ra...@liferay.com>
>  To: felix users <us...@felix.apache.org>; Alessandro Gherardi <
> alessandro.gherardi@yahoo.com>
>  Sent: Tuesday, September 6, 2016 12:07 PM
>  Subject: Re: Issues with embedded Felix framework and JAXRS
>
> Context classloaders are an Java EE construct and not something that OSGi
> frameworks usually care about. Therefore, when running OSGi embedded in a
> JavaEE container you generally need to do all the work to ensure TCCL's are
> properly handled.
>
> Sincerely,
> - Ray
>
> On Tue, Sep 6, 2016 at 12:46 PM, Alessandro Gherardi <
> alessandro.gherardi@yahoo.com.invalid> wrote:
>
> > Hi,I have a non-OSGi Java app that loads an OSGi bundle by embedding
> > Felix. The bundle exposes its functionality as an OSGi service. The app
> > accesses the service via a service tracker. The app uses the
> > org.osgi.framework.system.packages.extra option so that the service
> > interface and the classes that the interfaces refers to are all loaded by
> > the same classloader in both the app and the bundle.
> > The bundle uses Jersey 2.X and the app uses Jersey 1.17. When the app
> > calls the bundle via the service, the Jersey 2.X code throws the
> following
> > exception:
> > Exception in thread "main" java.lang.LinkageError: ClassCastException:
> > attempting to castfile:/C:/XXX/bin/javax/ws/rs/ext/RuntimeDelegate.class
> > to bundle://59.1:1/javax/ws/rs/ext/RuntimeDelegate.classat
> > javax.ws.rs.ext.RuntimeDelegate.findDelegate(RuntimeDelegate.java:146)
> at
> > javax.ws.rs.ext.RuntimeDelegate.getInstance(RuntimeDelegate.java:120) at
> > javax.ws.rs.core.UriBuilder.newInstance(UriBuilder.java:95)...
> > Looking at the Jersey source code, it appears that RuntimeDelegate tries
> > to load a concrete subclass via javax.ws.rs.ext.FactoryFinder.
> > FactoryFinder reads the name of the subclass from file META-INF/services/
> > javax.ws.rs.ext.RuntimeDelegate, and it loads that file via the calling
> > threads's context class loader. Since the calling thread is an
> > application's thread, its class loader is the application's class loader,
> > so META-INF/services/javax.ws.rs.ext.RuntimeDelegate points to a Jersey
> > 1.17 class.
> > I can kind-of workaround the problem by setting the application thread to
> > an "empty" class loader before calling the service - i.e.:
> > ClassLoader saveCL = Thread.currentThread().getContextClassLoader();
> > ClassLoader myCL = new URLClassLoader(new URL[0], saveCL.getParent());
> > try {
> >  Thread.currentThread().setContextClassLoader(myCL);
> >  call OSGi service
> > } finally {
> >  Thrad.currentThread().setContextClassloader(saveCL);
> > }
> >
> > However, I'm surprised I have to do that. Shouldn't the framework take
> > care of this - even if the service caller is the embedded application
> > rather than another OSGi bundle?
> > Notice: This issue may or may not be related to  commons-logging and Axis
> > problems
> > Thank you in advance,Alessandro
> >
> > |
> > |
> > |
> > |  |    |
> >
> >    |
> >
> >  |
> > |
> > |  |
> > commons-logging and Axis problems
> >    |  |
> >
> >  |
> >
> >  |
> >
> >
> >
> >
>
>
> --
> *Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile>
>  (@rotty3000)
> Senior Software Architect *Liferay, Inc.* <http://www.liferay.com/>
>  (@Liferay)
> Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org/>
> (@OSGiAlliance)
>
>




-- 
*Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile>
 (@rotty3000)
Senior Software Architect *Liferay, Inc.* <http://www.liferay.com/>
 (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org/> (@OSGiAlliance)

   

Re: Issues with embedded Felix framework and JAXRS

Posted by Raymond Auge <ra...@liferay.com>.
The issue remains with libraries designed for Java EE, they use TCCL
themselves because this has been forced upon them.

You'll have to do as David suggested and use SPI-Fly providing the
requirements and capabilities to the bundles in question to ensure that the
SPY-fly can wire the bundles together properly and do the instrumentation
necessary to make it all work.

- Ray

On Tue, Sep 6, 2016 at 2:50 PM, Alessandro Gherardi <
alessandro.gherardi@yahoo.com.invalid> wrote:

>
> Thanks.
> However, my application is NOT running within a J2EE container - it's a
> stand-alone, J2SE application started via java -cp ... path.to.main.class.
>
>
>
>       From: Raymond Auge <ra...@liferay.com>
>  To: felix users <us...@felix.apache.org>; Alessandro Gherardi <
> alessandro.gherardi@yahoo.com>
>  Sent: Tuesday, September 6, 2016 12:07 PM
>  Subject: Re: Issues with embedded Felix framework and JAXRS
>
> Context classloaders are an Java EE construct and not something that OSGi
> frameworks usually care about. Therefore, when running OSGi embedded in a
> JavaEE container you generally need to do all the work to ensure TCCL's are
> properly handled.
>
> Sincerely,
> - Ray
>
> On Tue, Sep 6, 2016 at 12:46 PM, Alessandro Gherardi <
> alessandro.gherardi@yahoo.com.invalid> wrote:
>
> > Hi,I have a non-OSGi Java app that loads an OSGi bundle by embedding
> > Felix. The bundle exposes its functionality as an OSGi service. The app
> > accesses the service via a service tracker. The app uses the
> > org.osgi.framework.system.packages.extra option so that the service
> > interface and the classes that the interfaces refers to are all loaded by
> > the same classloader in both the app and the bundle.
> > The bundle uses Jersey 2.X and the app uses Jersey 1.17. When the app
> > calls the bundle via the service, the Jersey 2.X code throws the
> following
> > exception:
> > Exception in thread "main" java.lang.LinkageError: ClassCastException:
> > attempting to castfile:/C:/XXX/bin/javax/ws/rs/ext/RuntimeDelegate.class
> > to bundle://59.1:1/javax/ws/rs/ext/RuntimeDelegate.classat
> > javax.ws.rs.ext.RuntimeDelegate.findDelegate(RuntimeDelegate.java:146)
> at
> > javax.ws.rs.ext.RuntimeDelegate.getInstance(RuntimeDelegate.java:120) at
> > javax.ws.rs.core.UriBuilder.newInstance(UriBuilder.java:95)...
> > Looking at the Jersey source code, it appears that RuntimeDelegate tries
> > to load a concrete subclass via javax.ws.rs.ext.FactoryFinder.
> > FactoryFinder reads the name of the subclass from file META-INF/services/
> > javax.ws.rs.ext.RuntimeDelegate, and it loads that file via the calling
> > threads's context class loader. Since the calling thread is an
> > application's thread, its class loader is the application's class loader,
> > so META-INF/services/javax.ws.rs.ext.RuntimeDelegate points to a Jersey
> > 1.17 class.
> > I can kind-of workaround the problem by setting the application thread to
> > an "empty" class loader before calling the service - i.e.:
> > ClassLoader saveCL = Thread.currentThread().getContextClassLoader();
> > ClassLoader myCL = new URLClassLoader(new URL[0], saveCL.getParent());
> > try {
> >  Thread.currentThread().setContextClassLoader(myCL);
> >  call OSGi service
> > } finally {
> >  Thrad.currentThread().setContextClassloader(saveCL);
> > }
> >
> > However, I'm surprised I have to do that. Shouldn't the framework take
> > care of this - even if the service caller is the embedded application
> > rather than another OSGi bundle?
> > Notice: This issue may or may not be related to  commons-logging and Axis
> > problems
> > Thank you in advance,Alessandro
> >
> > |
> > |
> > |
> > |  |    |
> >
> >    |
> >
> >  |
> > |
> > |  |
> > commons-logging and Axis problems
> >    |  |
> >
> >  |
> >
> >  |
> >
> >
> >
> >
>
>
> --
> *Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile>
>  (@rotty3000)
> Senior Software Architect *Liferay, Inc.* <http://www.liferay.com/>
>  (@Liferay)
> Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org/>
> (@OSGiAlliance)
>
>




-- 
*Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile>
 (@rotty3000)
Senior Software Architect *Liferay, Inc.* <http://www.liferay.com>
 (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org> (@OSGiAlliance)

Re: Issues with embedded Felix framework and JAXRS

Posted by Alessandro Gherardi <al...@yahoo.com.INVALID>.
Thanks.
However, my application is NOT running within a J2EE container - it's a stand-alone, J2SE application started via java -cp ... path.to.main.class.



      From: Raymond Auge <ra...@liferay.com>
 To: felix users <us...@felix.apache.org>; Alessandro Gherardi <al...@yahoo.com> 
 Sent: Tuesday, September 6, 2016 12:07 PM
 Subject: Re: Issues with embedded Felix framework and JAXRS
   
Context classloaders are an Java EE construct and not something that OSGi
frameworks usually care about. Therefore, when running OSGi embedded in a
JavaEE container you generally need to do all the work to ensure TCCL's are
properly handled.

Sincerely,
- Ray

On Tue, Sep 6, 2016 at 12:46 PM, Alessandro Gherardi <
alessandro.gherardi@yahoo.com.invalid> wrote:

> Hi,I have a non-OSGi Java app that loads an OSGi bundle by embedding
> Felix. The bundle exposes its functionality as an OSGi service. The app
> accesses the service via a service tracker. The app uses the
> org.osgi.framework.system.packages.extra option so that the service
> interface and the classes that the interfaces refers to are all loaded by
> the same classloader in both the app and the bundle.
> The bundle uses Jersey 2.X and the app uses Jersey 1.17. When the app
> calls the bundle via the service, the Jersey 2.X code throws the following
> exception:
> Exception in thread "main" java.lang.LinkageError: ClassCastException:
> attempting to castfile:/C:/XXX/bin/javax/ws/rs/ext/RuntimeDelegate.class
> to bundle://59.1:1/javax/ws/rs/ext/RuntimeDelegate.classat
> javax.ws.rs.ext.RuntimeDelegate.findDelegate(RuntimeDelegate.java:146) at
> javax.ws.rs.ext.RuntimeDelegate.getInstance(RuntimeDelegate.java:120) at
> javax.ws.rs.core.UriBuilder.newInstance(UriBuilder.java:95)...
> Looking at the Jersey source code, it appears that RuntimeDelegate tries
> to load a concrete subclass via javax.ws.rs.ext.FactoryFinder.
> FactoryFinder reads the name of the subclass from file META-INF/services/
> javax.ws.rs.ext.RuntimeDelegate, and it loads that file via the calling
> threads's context class loader. Since the calling thread is an
> application's thread, its class loader is the application's class loader,
> so META-INF/services/javax.ws.rs.ext.RuntimeDelegate points to a Jersey
> 1.17 class.
> I can kind-of workaround the problem by setting the application thread to
> an "empty" class loader before calling the service - i.e.:
> ClassLoader saveCL = Thread.currentThread().getContextClassLoader();
> ClassLoader myCL = new URLClassLoader(new URL[0], saveCL.getParent());
> try {
>  Thread.currentThread().setContextClassLoader(myCL);
>  call OSGi service
> } finally {
>  Thrad.currentThread().setContextClassloader(saveCL);
> }
>
> However, I'm surprised I have to do that. Shouldn't the framework take
> care of this - even if the service caller is the embedded application
> rather than another OSGi bundle?
> Notice: This issue may or may not be related to  commons-logging and Axis
> problems
> Thank you in advance,Alessandro
>
> |
> |
> |
> |  |    |
>
>    |
>
>  |
> |
> |  |
> commons-logging and Axis problems
>    |  |
>
>  |
>
>  |
>
>
>
>


-- 
*Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile>
 (@rotty3000)
Senior Software Architect *Liferay, Inc.* <http://www.liferay.com/>
 (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org/> (@OSGiAlliance)

   

Re: Issues with embedded Felix framework and JAXRS

Posted by Raymond Auge <ra...@liferay.com>.
Context classloaders are an Java EE construct and not something that OSGi
frameworks usually care about. Therefore, when running OSGi embedded in a
JavaEE container you generally need to do all the work to ensure TCCL's are
properly handled.

Sincerely,
- Ray

On Tue, Sep 6, 2016 at 12:46 PM, Alessandro Gherardi <
alessandro.gherardi@yahoo.com.invalid> wrote:

> Hi,I have a non-OSGi Java app that loads an OSGi bundle by embedding
> Felix. The bundle exposes its functionality as an OSGi service. The app
> accesses the service via a service tracker. The app uses the
> org.osgi.framework.system.packages.extra option so that the service
> interface and the classes that the interfaces refers to are all loaded by
> the same classloader in both the app and the bundle.
> The bundle uses Jersey 2.X and the app uses Jersey 1.17. When the app
> calls the bundle via the service, the Jersey 2.X code throws the following
> exception:
> Exception in thread "main" java.lang.LinkageError: ClassCastException:
> attempting to castfile:/C:/XXX/bin/javax/ws/rs/ext/RuntimeDelegate.class
> to bundle://59.1:1/javax/ws/rs/ext/RuntimeDelegate.classat
> javax.ws.rs.ext.RuntimeDelegate.findDelegate(RuntimeDelegate.java:146) at
> javax.ws.rs.ext.RuntimeDelegate.getInstance(RuntimeDelegate.java:120) at
> javax.ws.rs.core.UriBuilder.newInstance(UriBuilder.java:95)...
> Looking at the Jersey source code, it appears that RuntimeDelegate tries
> to load a concrete subclass via javax.ws.rs.ext.FactoryFinder.
> FactoryFinder reads the name of the subclass from file META-INF/services/
> javax.ws.rs.ext.RuntimeDelegate, and it loads that file via the calling
> threads's context class loader. Since the calling thread is an
> application's thread, its class loader is the application's class loader,
> so META-INF/services/javax.ws.rs.ext.RuntimeDelegate points to a Jersey
> 1.17 class.
> I can kind-of workaround the problem by setting the application thread to
> an "empty" class loader before calling the service - i.e.:
> ClassLoader saveCL = Thread.currentThread().getContextClassLoader();
> ClassLoader myCL = new URLClassLoader(new URL[0], saveCL.getParent());
> try {
>   Thread.currentThread().setContextClassLoader(myCL);
>   call OSGi service
> } finally {
>   Thrad.currentThread().setContextClassloader(saveCL);
> }
>
> However, I'm surprised I have to do that. Shouldn't the framework take
> care of this - even if the service caller is the embedded application
> rather than another OSGi bundle?
> Notice: This issue may or may not be related to  commons-logging and Axis
> problems
> Thank you in advance,Alessandro
>
> |
> |
> |
> |   |    |
>
>    |
>
>   |
> |
> |   |
> commons-logging and Axis problems
>    |   |
>
>   |
>
>   |
>
>
>
>


-- 
*Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile>
 (@rotty3000)
Senior Software Architect *Liferay, Inc.* <http://www.liferay.com>
 (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org> (@OSGiAlliance)