[OBR] Bundle update, versioning and wiring behaviour with split packages
This is fairly complicated to explain, but here goes. I am trying to understand what the behaviour should be in the following circumstance: - bundle A exports a package and is used by bundles B, C and D - bundle E exports a package with the same name and is not used by any bundle - A new repository.xml is deployed using OBR with an updated version of bundle A *without* the exported package My observation is that: - Two versions of bundle A now exist - All the previous wirings are retained to the package in the old bundle are retained. Similarly, existing package wirings to other packages are also retained - Bundle E is not used, still. - The new version of the bundle "may be" used for some package wirings, but not worked out the behaviour there yet. Does this sound correct? And am I correct in thinking the problem was in originally having a split package? Now, in more detail and with proper bundle/package names: I have a bundle `com.elsten.bliss.platform`. Here are the wirings before update: --- g! inspect capability osgi.wiring.package 59 com.elsten.bliss.platform [59] provides: osgi.wiring.package; com.elsten.bliss.client.impl 1.1.0 required by: com.elsten.bliss.ui [33] osgi.wiring.package; com.elsten.bliss.licence 1.0.1 required by: com.elsten.bliss.ui [33] osgi.wiring.package; com.elsten.bliss.main 2.0.5 required by: com.elsten.bliss.ui.systemtray [23] com.elsten.bliss.api [40] osgi.wiring.package; com.elsten.bliss.music.policy.config 1.0.0 required by: com.elsten.bliss.ui [33] com.elsten.bliss.configuration.file [72] osgi.wiring.package; com.elsten.bliss.music.policy.coverartpolicy 1.1.0 required by: com.elsten.bliss.ui [33] osgi.wiring.package; com.elsten.bliss.music.policy.coverartpolicy.assessment 1.0.0 required by: com.elsten.bliss.ui [33] osgi.wiring.package; com.elsten.bliss.music.policy.coverartpolicy.response 1.0.0 [UNUSED] osgi.wiring.package; com.elsten.bliss.music.policy.fileorg 1.1.0 required by: com.elsten.bliss.ui [33] osgi.wiring.package; com.elsten.bliss.music.policy.fileorg.pattern 1.0.0 required by: com.elsten.bliss.ui [33] osgi.wiring.package; com.elsten.bliss.music.policy.fileorg.pattern.token 1.0.0 [UNUSED] osgi.wiring.package; com.elsten.bliss.music.policy.tag.auto 1.0.0 required by: com.elsten.bliss.untagged.acoustid [52] osgi.wiring.package; com.elsten.bliss.music.policy.tagsync 1.0.0 required by: jdbm-trunk-patched [20] com.elsten.bliss.ui [33] osgi.wiring.package; com.elsten.bliss.music.policy.tagsync.allowablegenres 1.0.0 required by: com.elsten.bliss.ui [33] osgi.wiring.package; com.elsten.bliss.music.policy.tagsync.consolidateartist 1.0.1 [UNUSED] osgi.wiring.package; com.elsten.bliss.music.policy.tagsync.response 1.0.0 [UNUSED] osgi.wiring.package; com.elsten.bliss.music.policy.tagsync.trackartist 1.0.0 [UNUSED] osgi.wiring.package; com.elsten.bliss.music.policy.tagsync.tracknumberformat 1.0.0 required by: jdbm-trunk-patched [20] osgi.wiring.package; com.elsten.bliss.music.policy2 1.0.1 required by: com.elsten.bliss.ui [33] com.elsten.bliss.configuration.file [72] osgi.wiring.package; com.elsten.bliss.platform.storage.bus 1.0.0 [UNUSED] osgi.wiring.package; com.elsten.bliss.platform.storage.file.jaudiotagger 1.0.0 required by: jdbm-trunk-patched [20] osgi.wiring.package; com.elsten.bliss.platform.tagindex 1.0.0 [UNUSED] osgi.wiring.package; com.elsten.bliss.platform.util2 1.0.0 required by: com.elsten.bliss.web.debug [14] osgi.wiring.package; com.elsten.bliss.untagged2 1.0.0 required by: com.elsten.bliss.untagged.acoustid [52] com.elsten.bliss.ui [33] osgi.wiring.package; com.elsten.bliss.platform.activity 1.0.0 [UNUSED] osgi.wiring.package; com.elsten.bliss.platform2 1.0.0 [UNUSED] osgi.wiring.package; com.elsten.bliss.platform.storage.file 1.0.0 required by: com.elsten.bliss.configuration.file [72] osgi.wiring.package; com.elsten.bliss.music.conceptual 1.0.0 [UNUSED] osgi.wiring.package; com.elsten.bliss.music.tagged.mapper 1.0.0 [UNUSED] osgi.wiring.package; com.elsten.bliss.platform.storage.file.jaudiotagger.tag 28.1.2 [UNUSED] osgi.wiring.package; com.elsten.bliss.music.policy.tagsync.regex 28.1.2 [UNUSED] osgi.wiring.package; com.elsten.bliss.client.platform 1.0.0 [UNUSED] --- And services: --- g! inspect capability service 59 com.elsten.bliss.platform [59] provides: service; com.elsten.bliss.client.Client with properties: service.id = 31 Used by: com.elsten.bliss.ui [33] service; com.elsten.bliss.licence.PerFixLicenceStore with properties: service.id = 32 Used by: com.elsten.bliss.ui [33] service; com.elsten.bliss.musi
Re: OOME when running a bndtools JUnit test, I think because of bundle resolution
Ok, I think I found the cause. I have both a system bundle fragment exporting some packages, AND: -runsystempackages: sun.misc,sun.nio,sun.nio.ch ,sun.reflect,junit.framework,javax.servlet,javax.servlet.http,sun.reflect ... in my bndrun file. I removed the latter, and now it appears to start without issue. Dan On Fri, Jun 14, 2013 at 4:16 PM, Dan Gravell wrote: > I'm getting an OOME when running a bndtools JUnit test. The reason I'm > posting about it here is because I think this relates to Felix's bundle > resolvers. > > Even if I run the test with -Xmx512M I am getting the OOME, which is > manifest as a "GC overhead limit exceeded". This, despite running a super > set of bundles with -Xmx128M using the bndtools runner and also, at > deployment time, simply deployed within Felix. So I am trying to work out > what's going on... > > Here's the stack trace that's printed: > > ! Unexpected error in the run body: GC overhead limit exceeded > java.lang.OutOfMemoryError: GC overhead limit exceeded > at java.util.ArrayList.iterator(ArrayList.java:737) > at > org.apache.felix.framework.resolver.ResolverImpl.mergeUses(ResolverImpl.java:871) > at > org.apache.felix.framework.resolver.ResolverImpl.mergeUses(ResolverImpl.java:913) > at > org.apache.felix.framework.resolver.ResolverImpl.mergeUses(ResolverImpl.java:913) > at > org.apache.felix.framework.resolver.ResolverImpl.calculatePackageSpaces(ResolverImpl.java:679) > at > org.apache.felix.framework.resolver.ResolverImpl.resolve(ResolverImpl.java:183) > at > org.apache.felix.framework.StatefulResolver.resolve(StatefulResolver.java:403) > at org.apache.felix.framework.Felix.resolveBundles(Felix.java:3931) > at > org.apache.felix.framework.FrameworkWiringImpl.resolveBundles(FrameworkWiringImpl.java:123) > at > org.apache.felix.framework.PackageAdminImpl.resolveBundles(PackageAdminImpl.java:263) > at aQute.launcher.Launcher.update(Launcher.java:296) > at aQute.launcher.Launcher.activate(Launcher.java:241) > at aQute.launcher.Launcher.run(Launcher.java:145) > at aQute.launcher.Launcher.main(Launcher.java:80) > > I can provide the HPROF and the bundles, although the HPROF is 146MB and > wanted to avoid using up my monthly bandwidth allowance. It will also take > a good hour and a half to upload I think. It shows a ResolverImpl consuming > 413MB with 3442 Candidates objects in its m_usesPermutations list. > > Let me know what I can provide to help with this. > > I'm guessing there's something kooky about my bundles, but it seems > strange given they work in other scenarios. > > Dan > > >
OOME when running a bndtools JUnit test, I think because of bundle resolution
I'm getting an OOME when running a bndtools JUnit test. The reason I'm posting about it here is because I think this relates to Felix's bundle resolvers. Even if I run the test with -Xmx512M I am getting the OOME, which is manifest as a "GC overhead limit exceeded". This, despite running a super set of bundles with -Xmx128M using the bndtools runner and also, at deployment time, simply deployed within Felix. So I am trying to work out what's going on... Here's the stack trace that's printed: ! Unexpected error in the run body: GC overhead limit exceeded java.lang.OutOfMemoryError: GC overhead limit exceeded at java.util.ArrayList.iterator(ArrayList.java:737) at org.apache.felix.framework.resolver.ResolverImpl.mergeUses(ResolverImpl.java:871) at org.apache.felix.framework.resolver.ResolverImpl.mergeUses(ResolverImpl.java:913) at org.apache.felix.framework.resolver.ResolverImpl.mergeUses(ResolverImpl.java:913) at org.apache.felix.framework.resolver.ResolverImpl.calculatePackageSpaces(ResolverImpl.java:679) at org.apache.felix.framework.resolver.ResolverImpl.resolve(ResolverImpl.java:183) at org.apache.felix.framework.StatefulResolver.resolve(StatefulResolver.java:403) at org.apache.felix.framework.Felix.resolveBundles(Felix.java:3931) at org.apache.felix.framework.FrameworkWiringImpl.resolveBundles(FrameworkWiringImpl.java:123) at org.apache.felix.framework.PackageAdminImpl.resolveBundles(PackageAdminImpl.java:263) at aQute.launcher.Launcher.update(Launcher.java:296) at aQute.launcher.Launcher.activate(Launcher.java:241) at aQute.launcher.Launcher.run(Launcher.java:145) at aQute.launcher.Launcher.main(Launcher.java:80) I can provide the HPROF and the bundles, although the HPROF is 146MB and wanted to avoid using up my monthly bandwidth allowance. It will also take a good hour and a half to upload I think. It shows a ResolverImpl consuming 413MB with 3442 Candidates objects in its m_usesPermutations list. Let me know what I can provide to help with this. I'm guessing there's something kooky about my bundles, but it seems strange given they work in other scenarios. Dan
Re: Giving up on in process update... suggestions for how to structure separate JVM update?
Considered that too... the trouble with that is OS X support. It would mean having to install a Java runtime as part of an 'installation' process. On OS X right now it's as simple as running a .app 'bundle' (overloaded term!) inside a DMG. If Java 6 isn't installed already, OS X does the work of installing for you. I sell my software, and I need as low a friction solution as possible. Dan On Tue, May 14, 2013 at 3:52 PM, Bruce Jackson wrote: > I'd remove JNotify and replace it with the new filesystem classes in J2SE > 7. That way you'll be able to sort out the thread management yourself. > > > On 14 May 2013, at 15:46, Dan Gravell wrote: > > > H, sorry, don't want to misrepresent things... In neither case do you > > *explicitly* start threads. > > > > JNotify's threads are started by the class initialisers... so load the > > class (as you do when you add a 'watch' via a static method for a > > directory) and the thread starts. > > > > Lift's are started as part of its HTTP request handling. I managed to > patch > > it to stop all the threads upon shutdown of its surrounding servlet > > container (I use Jetty) but this is just code I will have to maintain > going > > forward with new releases. > > > > Neither behaviour is particularly desirable but JNotify's age and lack of > > committers and Lift's usage scenarios are probably good reasons why the > > respective projects' resources are not spent on fixing this. > > > > Dan > > > > > > On Tue, May 14, 2013 at 3:41 PM, Neil Bartlett > wrote: > > > >> So, they give you API to start a bunch of threads, but not stop them? > >> Awesome... > >> > >> On Tue, May 14, 2013 at 3:35 PM, Dan Gravell > >> wrote: > >>> In one case (JNotify) I create straight wrappers so the JARs are > >>> 'OSGi-ified', in another case I have the JARs embedded in the bundle > that > >>> uses them (Lift). > >>> > >>> Adding the bundle activator might work if the support to shutdown the > >>> threads is in the API for the code I am using. However, it isn't, and > as > >>> you know Java threads are co-operative so I can't simply stop them. > >>> > >>> Dan > >>> > >>> > >>> On Tue, May 14, 2013 at 2:57 PM, Felix Meschberger >>> wrote: > >>> > >>>> Hi Dan, > >>>> > >>>> Am 14.05.2013 um 07:16 schrieb Dan Gravell: > >>>> > >>>>>> With respect to when the thread has to stop, think about it the > other > >>>>>> way around... what if you never stop any threads? This would mean > >> that > >>>>>> objects allocated by the thread do not become candidates for garbage > >>>>>> collection; therefore neither do the classes that define those > >>>>>> objects; therefore, neither do the classloaders that loaded those > >>>>>> classes. So you're going to create a lot of garbage on the heap, > >>>>>> eventually resulting in OOME. Also, if a bundle's thread continues > >>>>>> running after the bundle has been stopped/updated then you could get > >>>>>> unexpected exceptions occurring in that thread; e.g. the bundle > >>>>>> classloader might not allow any new classes to be loaded, and calls > >>>>>> into OSGi using your BundleContext will probably throw > >>>>>> IllegalStateException. Generally these exceptions are not harmful > >>>>>> since you wanted the thread to die anyway, but they could cause > >>>>>> confusion if written to a log. > >>>>>> > >>>>> > >>>>> Just to be clear: you're preaching to the converted, I understand why > >> the > >>>>> threads should be stopped. The issue is that I am re-using other > >> projects > >>>>> that don't conform to these rules projects that were never > >> written as > >>>>> OSGi bundles. It's a bit like the class loading assumptions you see > in > >>>>> other projects... except arguably more subtle. > >>>> > >>>> So you are using libraries which are not built with OSGi in mind. > Still > >>>> you need OSGi manifests for the libraries to become bundles. So you at > >>>> least wrap the libra
Re: Giving up on in process update... suggestions for how to structure separate JVM update?
H, sorry, don't want to misrepresent things... In neither case do you *explicitly* start threads. JNotify's threads are started by the class initialisers... so load the class (as you do when you add a 'watch' via a static method for a directory) and the thread starts. Lift's are started as part of its HTTP request handling. I managed to patch it to stop all the threads upon shutdown of its surrounding servlet container (I use Jetty) but this is just code I will have to maintain going forward with new releases. Neither behaviour is particularly desirable but JNotify's age and lack of committers and Lift's usage scenarios are probably good reasons why the respective projects' resources are not spent on fixing this. Dan On Tue, May 14, 2013 at 3:41 PM, Neil Bartlett wrote: > So, they give you API to start a bunch of threads, but not stop them? > Awesome... > > On Tue, May 14, 2013 at 3:35 PM, Dan Gravell > wrote: > > In one case (JNotify) I create straight wrappers so the JARs are > > 'OSGi-ified', in another case I have the JARs embedded in the bundle that > > uses them (Lift). > > > > Adding the bundle activator might work if the support to shutdown the > > threads is in the API for the code I am using. However, it isn't, and as > > you know Java threads are co-operative so I can't simply stop them. > > > > Dan > > > > > > On Tue, May 14, 2013 at 2:57 PM, Felix Meschberger >wrote: > > > >> Hi Dan, > >> > >> Am 14.05.2013 um 07:16 schrieb Dan Gravell: > >> > >> >> With respect to when the thread has to stop, think about it the other > >> >> way around... what if you never stop any threads? This would mean > that > >> >> objects allocated by the thread do not become candidates for garbage > >> >> collection; therefore neither do the classes that define those > >> >> objects; therefore, neither do the classloaders that loaded those > >> >> classes. So you're going to create a lot of garbage on the heap, > >> >> eventually resulting in OOME. Also, if a bundle's thread continues > >> >> running after the bundle has been stopped/updated then you could get > >> >> unexpected exceptions occurring in that thread; e.g. the bundle > >> >> classloader might not allow any new classes to be loaded, and calls > >> >> into OSGi using your BundleContext will probably throw > >> >> IllegalStateException. Generally these exceptions are not harmful > >> >> since you wanted the thread to die anyway, but they could cause > >> >> confusion if written to a log. > >> >> > >> > > >> > Just to be clear: you're preaching to the converted, I understand why > the > >> > threads should be stopped. The issue is that I am re-using other > projects > >> > that don't conform to these rules projects that were never > written as > >> > OSGi bundles. It's a bit like the class loading assumptions you see in > >> > other projects... except arguably more subtle. > >> > >> So you are using libraries which are not built with OSGi in mind. Still > >> you need OSGi manifests for the libraries to become bundles. So you at > >> least wrap the libraries somehow to generate the manifest. > >> > >> How about adding a BundleActivator as part of this manifest generation ? > >> That BundleActivator could in the stop method stop any running threads. > The > >> BundleActivator is part of the bundle so it may be aware of the library > >> internals and be able to stop any running threads. > >> > >> Regards > >> Felix > >> - > >> To unsubscribe, e-mail: users-unsubscr...@felix.apache.org > >> For additional commands, e-mail: users-h...@felix.apache.org > >> > >> > > - > To unsubscribe, e-mail: users-unsubscr...@felix.apache.org > For additional commands, e-mail: users-h...@felix.apache.org > >
Re: Giving up on in process update... suggestions for how to structure separate JVM update?
In one case (JNotify) I create straight wrappers so the JARs are 'OSGi-ified', in another case I have the JARs embedded in the bundle that uses them (Lift). Adding the bundle activator might work if the support to shutdown the threads is in the API for the code I am using. However, it isn't, and as you know Java threads are co-operative so I can't simply stop them. Dan On Tue, May 14, 2013 at 2:57 PM, Felix Meschberger wrote: > Hi Dan, > > Am 14.05.2013 um 07:16 schrieb Dan Gravell: > > >> With respect to when the thread has to stop, think about it the other > >> way around... what if you never stop any threads? This would mean that > >> objects allocated by the thread do not become candidates for garbage > >> collection; therefore neither do the classes that define those > >> objects; therefore, neither do the classloaders that loaded those > >> classes. So you're going to create a lot of garbage on the heap, > >> eventually resulting in OOME. Also, if a bundle's thread continues > >> running after the bundle has been stopped/updated then you could get > >> unexpected exceptions occurring in that thread; e.g. the bundle > >> classloader might not allow any new classes to be loaded, and calls > >> into OSGi using your BundleContext will probably throw > >> IllegalStateException. Generally these exceptions are not harmful > >> since you wanted the thread to die anyway, but they could cause > >> confusion if written to a log. > >> > > > > Just to be clear: you're preaching to the converted, I understand why the > > threads should be stopped. The issue is that I am re-using other projects > > that don't conform to these rules projects that were never written as > > OSGi bundles. It's a bit like the class loading assumptions you see in > > other projects... except arguably more subtle. > > So you are using libraries which are not built with OSGi in mind. Still > you need OSGi manifests for the libraries to become bundles. So you at > least wrap the libraries somehow to generate the manifest. > > How about adding a BundleActivator as part of this manifest generation ? > That BundleActivator could in the stop method stop any running threads. The > BundleActivator is part of the bundle so it may be aware of the library > internals and be able to stop any running threads. > > Regards > Felix > - > To unsubscribe, e-mail: users-unsubscr...@felix.apache.org > For additional commands, e-mail: users-h...@felix.apache.org > >
Re: Giving up on in process update... suggestions for how to structure separate JVM update?
Ah yes, I see. I wasn't actually aware of START_TRANSIENT before, and a lot of head scratching in this area was how to cope with bundle state between invocations. Thanks. On Tue, May 14, 2013 at 2:43 PM, Neil Bartlett wrote: > I think that as an alternative approach to using start levels, you > could use transient starting. > > If (a) the management agent is the only bundle that ever starts > bundles besides itself, and (b) it always starts them transiently, > i.e. with Bundle.START_TRANSIENT, then you can be sure the management > agent will be the only bundle running after a framework restart. > > Neil > > On Tue, May 14, 2013 at 2:39 PM, Dan Gravell > wrote: > > Gotcha, thanks. > > > > > > On Tue, May 14, 2013 at 2:38 PM, Richard S. Hall >wrote: > > > >> > >> On 5/14/13 09:35 , Richard S. Hall wrote: > >> > >>> On 5/14/13 09:24 , Dan Gravell wrote: > >>> > >>>> Thanks Richard. > >>>> > >>>> Are start levels not... "bad"... from a conceptual point of view? Or, > in > >>>> this case, where start levels are used to separate "layers" (the > >>>> management > >>>> layer from the application layer) are they deemed ok? > >>>> > >>> > >>> This is pretty much why start levels exist, but regardless, we are > >>> talking about restarting the JVM because you have bundles that won't > >>> behave, so I think adding start levels doesn't really further soil the > >>> situation. :-) > >>> > >> > >> To further clarify, start levels are not intended as a poor man's > approach > >> to ordering bundle start up, since you shouldn't care about the order in > >> which bundles start. Using start levels for coarse grained "mode" > >> management is not unreasonable, but you shouldn't do much more than > that. > >> > >> -> richard > >> > >> > >> > >>> -> richard > >>> > >>> Dan > >>>> > >>>> > >>>> On Tue, May 14, 2013 at 2:07 PM, Richard S. Hall < > he...@ungoverned.org > >>>> >wrote: > >>>> > >>>> The simplest approach is once you decide some sort of restart is > needed, > >>>>> just stop the framework JVM and have your launcher relaunch it in > >>>>> "update > >>>>> mode" which would be a low start level in which no bundles but your > >>>>> "management" bundle can execute. > >>>>> > >>>>> In this mode, you know no other bundles have started, so your > management > >>>>> bundle can do whatever updates it wants, call refresh, then change > the > >>>>> start level to enter normal operating mode when it is done. > >>>>> > >>>>> -> richard > >>>>> > >>>>> > >>>>> On 5/14/13 07:17 , Dan Gravell wrote: > >>>>> > >>>>> Hi all. After giving it about a year of tweaks, I'm finally going to > >>>>>> give > >>>>>> up trying to update my OSGi app in process. The killer is the > >>>>>> requirement > >>>>>> to stop all threads... for my particular requirements this just > isn't > >>>>>> feasible. I have to maintain my own forks of projects, some complex > >>>>>> (the > >>>>>> Lift web framework) and some less so (JNotify) and this just takes > too > >>>>>> long. > >>>>>> > >>>>>> So I'm putting thought to how I can structure a solution that > restarts > >>>>>> the > >>>>>> JVM *at some point*. I am using Felix 'bundlerepository' bundle to > >>>>>> perform > >>>>>> the deployments of bundles. > >>>>>> > >>>>>> So first, the requirement to stop threads: is this a requirement > >>>>>> *before* > >>>>>> start(), stop() or update(URL) is called? > >>>>>> > >>>>>> If it's only something that has to be done before stop() then I > >>>>>> _could_ do > >>>>>> everything I do now, up to when start() is called on each bundle. At > >>>>>> that > >
Re: Giving up on in process update... suggestions for how to structure separate JVM update?
Thanks. I think I'm going to try this "restart in update mode" approach. Dan On Tue, May 14, 2013 at 2:40 PM, Neil Bartlett wrote: > On Tue, May 14, 2013 at 2:16 PM, Dan Gravell > wrote: > > Neil, > > > > Each bundle should be responsible for stopping any threads that it has > >> started itself, and it should do this from its BundleActivator.stop() > >> callback method (or if you have used DS, from the deactivate methods, > >> etc). The management agent should not care about bundle threads -- > >> that is an implementation detail that the agent should know nothing > >> about. It should just call Bundle.stop(). > >> > > > > Ok, so it's not safe to update() a stop()ped bundle which has threads > still > > running that it started itself? That means the update process would have > to > > occur in a separate JVM invocation. > > "Safe" is relative ;-) > > As I tried to explain in my previous email, the old bundle's classes > and classloader will probably be pinned in memory, so you will have a > memory leak. Also possibly the resource clashes that I talked about > (but you could also have these if you had another copy of the same JVM > process running). > > >> With respect to when the thread has to stop, think about it the other > >> way around... what if you never stop any threads? This would mean that > >> objects allocated by the thread do not become candidates for garbage > >> collection; therefore neither do the classes that define those > >> objects; therefore, neither do the classloaders that loaded those > >> classes. So you're going to create a lot of garbage on the heap, > >> eventually resulting in OOME. Also, if a bundle's thread continues > >> running after the bundle has been stopped/updated then you could get > >> unexpected exceptions occurring in that thread; e.g. the bundle > >> classloader might not allow any new classes to be loaded, and calls > >> into OSGi using your BundleContext will probably throw > >> IllegalStateException. Generally these exceptions are not harmful > >> since you wanted the thread to die anyway, but they could cause > >> confusion if written to a log. > >> > > > > Just to be clear: you're preaching to the converted, I understand why the > > threads should be stopped. The issue is that I am re-using other projects > > that don't conform to these rules projects that were never written as > > OSGi bundles. It's a bit like the class loading assumptions you see in > > other projects... except arguably more subtle. > > > > For "teh google", what I commonly see are NullPointerExceptions > (example): > > > > java.lang.NullPointerException > > at > > > org.apache.felix.framework.BundleRevisionImpl.calculateContentPath(BundleRevisionImpl.java:410) > > at > > > org.apache.felix.framework.BundleRevisionImpl.initializeContentPath(BundleRevisionImpl.java:347) > > at > > > org.apache.felix.framework.BundleRevisionImpl.getContentPath(BundleRevisionImpl.java:333) > > at > > > org.apache.felix.framework.BundleRevisionImpl.getResourceLocal(BundleRevisionImpl.java:472) > > at > > > org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1432) > > at > > > org.apache.felix.framework.BundleWiringImpl.getResourceByDelegation(BundleWiringImpl.java:1360) > > at > > > org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.getResource(BundleWiringImpl.java:2256) > > > > Also in JNotify's case threads are started in the static initalizers and > it > > means the native code ends up calling incorrect listeners in the bundle, > > meaning file notifications are missing. I believe Ferry Huberts wrote a > > port for the Linux part of JNotify, but I also need to support OS X and > > Windows. > > > > I also see various stack traces in static initalizers... ImageIO is a > > particular favourite: > > > > java.lang.NullPointerException > > at > > > org.apache.felix.framework.BundleRevisionImpl.getResourcesLocal(BundleRevisionImpl.java:510) > > at > > > org.apache.felix.framework.BundleWiringImpl.findResourcesByDelegation(BundleWiringImpl.java:1127) > > at > > > org.apache.felix.framework.BundleWiringImpl.getResourcesByDelegation(BundleWiringImpl.java:1037) > > at > > > org.apache.felix.framework.BundleWiringImpl$BundleClassLoaderJava5.getResources(BundleWirin
Re: Giving up on in process update... suggestions for how to structure separate JVM update?
Gotcha, thanks. On Tue, May 14, 2013 at 2:38 PM, Richard S. Hall wrote: > > On 5/14/13 09:35 , Richard S. Hall wrote: > >> On 5/14/13 09:24 , Dan Gravell wrote: >> >>> Thanks Richard. >>> >>> Are start levels not... "bad"... from a conceptual point of view? Or, in >>> this case, where start levels are used to separate "layers" (the >>> management >>> layer from the application layer) are they deemed ok? >>> >> >> This is pretty much why start levels exist, but regardless, we are >> talking about restarting the JVM because you have bundles that won't >> behave, so I think adding start levels doesn't really further soil the >> situation. :-) >> > > To further clarify, start levels are not intended as a poor man's approach > to ordering bundle start up, since you shouldn't care about the order in > which bundles start. Using start levels for coarse grained "mode" > management is not unreasonable, but you shouldn't do much more than that. > > -> richard > > > >> -> richard >> >> Dan >>> >>> >>> On Tue, May 14, 2013 at 2:07 PM, Richard S. Hall >> >wrote: >>> >>> The simplest approach is once you decide some sort of restart is needed, >>>> just stop the framework JVM and have your launcher relaunch it in >>>> "update >>>> mode" which would be a low start level in which no bundles but your >>>> "management" bundle can execute. >>>> >>>> In this mode, you know no other bundles have started, so your management >>>> bundle can do whatever updates it wants, call refresh, then change the >>>> start level to enter normal operating mode when it is done. >>>> >>>> -> richard >>>> >>>> >>>> On 5/14/13 07:17 , Dan Gravell wrote: >>>> >>>> Hi all. After giving it about a year of tweaks, I'm finally going to >>>>> give >>>>> up trying to update my OSGi app in process. The killer is the >>>>> requirement >>>>> to stop all threads... for my particular requirements this just isn't >>>>> feasible. I have to maintain my own forks of projects, some complex >>>>> (the >>>>> Lift web framework) and some less so (JNotify) and this just takes too >>>>> long. >>>>> >>>>> So I'm putting thought to how I can structure a solution that restarts >>>>> the >>>>> JVM *at some point*. I am using Felix 'bundlerepository' bundle to >>>>> perform >>>>> the deployments of bundles. >>>>> >>>>> So first, the requirement to stop threads: is this a requirement >>>>> *before* >>>>> start(), stop() or update(URL) is called? >>>>> >>>>> If it's only something that has to be done before stop() then I >>>>> _could_ do >>>>> everything I do now, up to when start() is called on each bundle. At >>>>> that >>>>> point, I could exit with an exit code and my launcher script checks >>>>> that >>>>> and, if it's a known value, restarts the same process. In this case, I >>>>> would have to re-start the bundles on restart. >>>>> >>>>> If threads have to be stopped before the update itself, then I suppose >>>>> I >>>>> can download the bundles to a holding area, and have a bootstrap JVM >>>>> that >>>>> picks them up and somehow performs the update, and then starts. >>>>> >>>>> If anyone has any wisdom or experience of this I would be grateful to >>>>> hear >>>>> it... >>>>> >>>>> Dan >>>>> >>>>> >>>>> >>>>> --**--**- >>>> >>>> To unsubscribe, e-mail: >>>> users-unsubscribe@felix.**apac**he.org<http://apache.org> >>>> >>>> > >>>> For additional commands, e-mail: users-h...@felix.apache.org >>>> >>>> >>>> >> > > --**--**- > To unsubscribe, e-mail: > users-unsubscribe@felix.**apache.org > For additional commands, e-mail: users-h...@felix.apache.org > >
Re: Giving up on in process update... suggestions for how to structure separate JVM update?
Thanks Richard. Are start levels not... "bad"... from a conceptual point of view? Or, in this case, where start levels are used to separate "layers" (the management layer from the application layer) are they deemed ok? Dan On Tue, May 14, 2013 at 2:07 PM, Richard S. Hall wrote: > The simplest approach is once you decide some sort of restart is needed, > just stop the framework JVM and have your launcher relaunch it in "update > mode" which would be a low start level in which no bundles but your > "management" bundle can execute. > > In this mode, you know no other bundles have started, so your management > bundle can do whatever updates it wants, call refresh, then change the > start level to enter normal operating mode when it is done. > > -> richard > > > On 5/14/13 07:17 , Dan Gravell wrote: > >> Hi all. After giving it about a year of tweaks, I'm finally going to give >> up trying to update my OSGi app in process. The killer is the requirement >> to stop all threads... for my particular requirements this just isn't >> feasible. I have to maintain my own forks of projects, some complex (the >> Lift web framework) and some less so (JNotify) and this just takes too >> long. >> >> So I'm putting thought to how I can structure a solution that restarts the >> JVM *at some point*. I am using Felix 'bundlerepository' bundle to perform >> the deployments of bundles. >> >> So first, the requirement to stop threads: is this a requirement *before* >> start(), stop() or update(URL) is called? >> >> If it's only something that has to be done before stop() then I _could_ do >> everything I do now, up to when start() is called on each bundle. At that >> point, I could exit with an exit code and my launcher script checks that >> and, if it's a known value, restarts the same process. In this case, I >> would have to re-start the bundles on restart. >> >> If threads have to be stopped before the update itself, then I suppose I >> can download the bundles to a holding area, and have a bootstrap JVM that >> picks them up and somehow performs the update, and then starts. >> >> If anyone has any wisdom or experience of this I would be grateful to hear >> it... >> >> Dan >> >> > > --**--**- > To unsubscribe, e-mail: > users-unsubscribe@felix.**apache.org > For additional commands, e-mail: users-h...@felix.apache.org > >
Re: Giving up on in process update... suggestions for how to structure separate JVM update?
Neil, Each bundle should be responsible for stopping any threads that it has > started itself, and it should do this from its BundleActivator.stop() > callback method (or if you have used DS, from the deactivate methods, > etc). The management agent should not care about bundle threads -- > that is an implementation detail that the agent should know nothing > about. It should just call Bundle.stop(). > Ok, so it's not safe to update() a stop()ped bundle which has threads still running that it started itself? That means the update process would have to occur in a separate JVM invocation. > With respect to when the thread has to stop, think about it the other > way around... what if you never stop any threads? This would mean that > objects allocated by the thread do not become candidates for garbage > collection; therefore neither do the classes that define those > objects; therefore, neither do the classloaders that loaded those > classes. So you're going to create a lot of garbage on the heap, > eventually resulting in OOME. Also, if a bundle's thread continues > running after the bundle has been stopped/updated then you could get > unexpected exceptions occurring in that thread; e.g. the bundle > classloader might not allow any new classes to be loaded, and calls > into OSGi using your BundleContext will probably throw > IllegalStateException. Generally these exceptions are not harmful > since you wanted the thread to die anyway, but they could cause > confusion if written to a log. > Just to be clear: you're preaching to the converted, I understand why the threads should be stopped. The issue is that I am re-using other projects that don't conform to these rules projects that were never written as OSGi bundles. It's a bit like the class loading assumptions you see in other projects... except arguably more subtle. For "teh google", what I commonly see are NullPointerExceptions (example): java.lang.NullPointerException at org.apache.felix.framework.BundleRevisionImpl.calculateContentPath(BundleRevisionImpl.java:410) at org.apache.felix.framework.BundleRevisionImpl.initializeContentPath(BundleRevisionImpl.java:347) at org.apache.felix.framework.BundleRevisionImpl.getContentPath(BundleRevisionImpl.java:333) at org.apache.felix.framework.BundleRevisionImpl.getResourceLocal(BundleRevisionImpl.java:472) at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1432) at org.apache.felix.framework.BundleWiringImpl.getResourceByDelegation(BundleWiringImpl.java:1360) at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.getResource(BundleWiringImpl.java:2256) Also in JNotify's case threads are started in the static initalizers and it means the native code ends up calling incorrect listeners in the bundle, meaning file notifications are missing. I believe Ferry Huberts wrote a port for the Linux part of JNotify, but I also need to support OS X and Windows. I also see various stack traces in static initalizers... ImageIO is a particular favourite: java.lang.NullPointerException at org.apache.felix.framework.BundleRevisionImpl.getResourcesLocal(BundleRevisionImpl.java:510) at org.apache.felix.framework.BundleWiringImpl.findResourcesByDelegation(BundleWiringImpl.java:1127) at org.apache.felix.framework.BundleWiringImpl.getResourcesByDelegation(BundleWiringImpl.java:1037) at org.apache.felix.framework.BundleWiringImpl$BundleClassLoaderJava5.getResources(BundleWiringImpl.java:1778) at org.eclipse.jetty.osgi.boot.internal.webapp.OSGiWebappClassLoader.getResources(OSGiWebappClassLoader.java:115) at java.util.ServiceLoader$LazyIterator.hasNext(ServiceLoader.java:340) at java.util.ServiceLoader$1.hasNext(ServiceLoader.java:432) at javax.imageio.spi.IIORegistry.registerApplicationClasspathSpis(IIORegistry.java:206) at javax.imageio.spi.IIORegistry.(IIORegistry.java:138) at javax.imageio.spi.IIORegistry.getDefaultInstance(IIORegistry.java:159) at javax.imageio.ImageIO.(ImageIO.java:64) These are often threads started *after* an update, by *updated* bundles. But conversations with Richard S Hall before suggested the underlying cause of the problems were threads that were still running at update. Anyway, the point is I have devoted quite a lot of time to trying to iron these kinks out and I'm not getting that far, so I want to go back to something I think will work. Therefore from a pure Java/OSGi standpoint it doesn't really matter > whether the threads stop before or after update, so long as they do > eventually stop. However a bigger problem is likely to be the internal > logic of the bundles... is it able to cope with two copies running > simultaneously? For example if you access a resource such as file, can > you cope with "somebody else" (actually, an old undead copy of > yourself!) accessing the same resource at the same time? > Thanks,
Re: Giving up on in process update... suggestions for how to structure separate JVM update?
Thanks Bruce. The trouble is that calling stop() does not stop all the threads started by some of the bundles I use, so using start levels isn't helpful at the part where the bundles are updated. However, it may be useful for restart to *attempt* to make sure some "bootstrap" bundle is started first. Dan On Tue, May 14, 2013 at 12:23 PM, Bruce Jackson wrote: > I'm not sure exactly what you're trying to do, but in the past I'm used an > embedded Felix instance with a single 'management' bundle running at start > level 1 which was then able to download and deploy all of the other bundles > in my system at start levels > 1. > > In this setup, all I needed to do was to drop the platform start level to > 1 which had the effect of calling stop() on all of the installed bundles. > In this state you can then uninstall and bundles to be updated, then just > set the start level back up to the default. > > On 14 May 2013, at 12:17, Dan Gravell wrote: > > > Hi all. After giving it about a year of tweaks, I'm finally going to give > > up trying to update my OSGi app in process. The killer is the requirement > > to stop all threads... for my particular requirements this just isn't > > feasible. I have to maintain my own forks of projects, some complex (the > > Lift web framework) and some less so (JNotify) and this just takes too > long. > > > > So I'm putting thought to how I can structure a solution that restarts > the > > JVM *at some point*. I am using Felix 'bundlerepository' bundle to > perform > > the deployments of bundles. > > > > So first, the requirement to stop threads: is this a requirement *before* > > start(), stop() or update(URL) is called? > > > > If it's only something that has to be done before stop() then I _could_ > do > > everything I do now, up to when start() is called on each bundle. At that > > point, I could exit with an exit code and my launcher script checks that > > and, if it's a known value, restarts the same process. In this case, I > > would have to re-start the bundles on restart. > > > > If threads have to be stopped before the update itself, then I suppose I > > can download the bundles to a holding area, and have a bootstrap JVM that > > picks them up and somehow performs the update, and then starts. > > > > If anyone has any wisdom or experience of this I would be grateful to > hear > > it... > > > > Dan > > > > > This e-mail is only intended for the person(s) to whom it is addressed and > may contain CONFIDENTIAL information. Any opinions or views are personal to > the writer and do not represent those of INQ Mobile Limited, Hutchison > Whampoa Limited or its group companies. If you are not the intended > recipient, you are hereby notified that any use, retention, disclosure, > copying, printing, forwarding or dissemination of this communication is > strictly prohibited. If you have received this communication in error, > please erase all copies of the message and its attachments and notify the > sender immediately. INQ Mobile Limited is a company registered in the > British Virgin Islands. www.inqmobile.com. > > > > > - > To unsubscribe, e-mail: users-unsubscr...@felix.apache.org > For additional commands, e-mail: users-h...@felix.apache.org > >
Giving up on in process update... suggestions for how to structure separate JVM update?
Hi all. After giving it about a year of tweaks, I'm finally going to give up trying to update my OSGi app in process. The killer is the requirement to stop all threads... for my particular requirements this just isn't feasible. I have to maintain my own forks of projects, some complex (the Lift web framework) and some less so (JNotify) and this just takes too long. So I'm putting thought to how I can structure a solution that restarts the JVM *at some point*. I am using Felix 'bundlerepository' bundle to perform the deployments of bundles. So first, the requirement to stop threads: is this a requirement *before* start(), stop() or update(URL) is called? If it's only something that has to be done before stop() then I _could_ do everything I do now, up to when start() is called on each bundle. At that point, I could exit with an exit code and my launcher script checks that and, if it's a known value, restarts the same process. In this case, I would have to re-start the bundles on restart. If threads have to be stopped before the update itself, then I suppose I can download the bundles to a holding area, and have a bootstrap JVM that picks them up and somehow performs the update, and then starts. If anyone has any wisdom or experience of this I would be grateful to hear it... Dan
Re: Shutdown deadlock on OS X while doing AWT stuff
Yeah, it worked. I had to write a dynamic proxy to access the API because Eclipse complains about access restrictions for com.apple.eawt but once I'd written the code, exported the package from my system bundle fragment and imported into the new bundle it all worked fine. On Tue, Mar 5, 2013 at 5:51 PM, Dan Gravell wrote: > Thanks everyone. I was unaware of the Apple Application library and so > I'll create a bundle for OS X which registers its own QuitHandler and see > if that helps things. > > I'll pursue other suggestions afterwards. > > Dan > > > On Tue, Mar 5, 2013 at 2:36 PM, Jan Willem Janssen < > janwillem.jans...@luminis.eu> wrote: > >> -BEGIN PGP SIGNED MESSAGE- >> Hash: SHA1 >> >> On 3/5/13 3:23 PM, Dan Gravell wrote: >> > Well, I could be explicitly stopping the framework, or the stop >> > could occur when the OS is shutdown and it *appears* this >> > com.apple.eawt._AppEventHandler kicks in and calls System.exit... >> > Does that count as an explicit stop? >> >> FWIW: The eawt application-quit hook calls System.exit(0) by default, >> see [1]. Either set another quit strategy or call >> QuitResponse#cancelQuit in your QuitHandler. >> >> Hope this helps, >> >> [1] >> >> http://developer.apple.com/library/mac/documentation/Java/Reference/JavaSE6_AppleExtensionsRef/api/com/apple/eawt/QuitStrategy.html >> >> - -- >> Met vriendelijke groeten | Kind regards >> >> Jan Willem Janssen | Software Architect >> +31 631 765 814 >> >> /My world is revolving around PulseOn and Amdatu/ >> >> Luminis Technologies B.V. >> J.C. Wilslaan 29 >> 7313 HK Apeldoorn >> +31 88 586 46 30 >> >> http://www.luminis-technologies.com >> http://www.luminis.eu >> >> KvK (CoC) 09 16 28 93 >> BTW (VAT) NL8169.78.566.B.01 >> -BEGIN PGP SIGNATURE- >> Version: GnuPG/MacGPG2 v2.0.17 (Darwin) >> Comment: GPGTools - http://gpgtools.org >> Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ >> >> iQIcBAEBAgAGBQJRNgL5AAoJEKF/mP2eHDc4EGsP/iWKEhx/EG9Gmu7iOO9XN05b >> prFlolILB+STYP3akDBIuaI973H6UFofqdlCAiBcrbJWV2doXYcXzEv7aBIzSCLI >> uZprA+z2dW9kaWp24QrOtNMH3bTR27a46/WSjiyAVEY3oYo+4GqKUwSzgTy4lFE0 >> P8eH1SzyFTZRwaa1engT8sieiEbgImR6o3GtFJlZqK9D0bBs28lF7U2kJFIvu+er >> JlerOPwLN4VKe2DZO2iA6gS7NatQTcjXL0tkwmYY890cJhW4/v9RU1VHZOstf2PA >> bWHN43dAE9J6r9MJY7fOdRx2uOYYM6rhlSZBqPIMMOInRcWHZ0SFuaqMpx9UzK/s >> ZY0A1GGkZ2o4aNCzyI91CM9xF9w3Q/q+TxH2SUP0xQyTJ3LOWf4GCmwXw5O8rd7H >> FAJK4ui6Pr98P2kmCWA/9wSrm5xVxuC3/pbzE5pYqT0wXvn00IIvlPF813fIszYC >> xpL/zsyLt+SPjV/N0HQ1JBVoDZC6u/sGwkbwMbsl2HC79C+hEt1ELBOE5+BHwGW0 >> dOAOn0b5Hkq3tCLzWIdwhuXHpn1fLNcTvoMQ1LbP9pHC0Nh6nz1GbclRTIu8jRMo >> zGGHJeltYPnGFLdAVUc10Mrq3O9abnWxDa1UB3KXLnr8GkzoGMVqS6/3142V/oTM >> 8m58tIyf47Z28IxreoGy >> =FS4a >> -END PGP SIGNATURE- >> >> >> - >> To unsubscribe, e-mail: users-unsubscr...@felix.apache.org >> For additional commands, e-mail: users-h...@felix.apache.org >> >> >
Re: Shutdown deadlock on OS X while doing AWT stuff
Thanks everyone. I was unaware of the Apple Application library and so I'll create a bundle for OS X which registers its own QuitHandler and see if that helps things. I'll pursue other suggestions afterwards. Dan On Tue, Mar 5, 2013 at 2:36 PM, Jan Willem Janssen < janwillem.jans...@luminis.eu> wrote: > -BEGIN PGP SIGNED MESSAGE- > Hash: SHA1 > > On 3/5/13 3:23 PM, Dan Gravell wrote: > > Well, I could be explicitly stopping the framework, or the stop > > could occur when the OS is shutdown and it *appears* this > > com.apple.eawt._AppEventHandler kicks in and calls System.exit... > > Does that count as an explicit stop? > > FWIW: The eawt application-quit hook calls System.exit(0) by default, > see [1]. Either set another quit strategy or call > QuitResponse#cancelQuit in your QuitHandler. > > Hope this helps, > > [1] > > http://developer.apple.com/library/mac/documentation/Java/Reference/JavaSE6_AppleExtensionsRef/api/com/apple/eawt/QuitStrategy.html > > - -- > Met vriendelijke groeten | Kind regards > > Jan Willem Janssen | Software Architect > +31 631 765 814 > > /My world is revolving around PulseOn and Amdatu/ > > Luminis Technologies B.V. > J.C. Wilslaan 29 > 7313 HK Apeldoorn > +31 88 586 46 30 > > http://www.luminis-technologies.com > http://www.luminis.eu > > KvK (CoC) 09 16 28 93 > BTW (VAT) NL8169.78.566.B.01 > -BEGIN PGP SIGNATURE- > Version: GnuPG/MacGPG2 v2.0.17 (Darwin) > Comment: GPGTools - http://gpgtools.org > Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ > > iQIcBAEBAgAGBQJRNgL5AAoJEKF/mP2eHDc4EGsP/iWKEhx/EG9Gmu7iOO9XN05b > prFlolILB+STYP3akDBIuaI973H6UFofqdlCAiBcrbJWV2doXYcXzEv7aBIzSCLI > uZprA+z2dW9kaWp24QrOtNMH3bTR27a46/WSjiyAVEY3oYo+4GqKUwSzgTy4lFE0 > P8eH1SzyFTZRwaa1engT8sieiEbgImR6o3GtFJlZqK9D0bBs28lF7U2kJFIvu+er > JlerOPwLN4VKe2DZO2iA6gS7NatQTcjXL0tkwmYY890cJhW4/v9RU1VHZOstf2PA > bWHN43dAE9J6r9MJY7fOdRx2uOYYM6rhlSZBqPIMMOInRcWHZ0SFuaqMpx9UzK/s > ZY0A1GGkZ2o4aNCzyI91CM9xF9w3Q/q+TxH2SUP0xQyTJ3LOWf4GCmwXw5O8rd7H > FAJK4ui6Pr98P2kmCWA/9wSrm5xVxuC3/pbzE5pYqT0wXvn00IIvlPF813fIszYC > xpL/zsyLt+SPjV/N0HQ1JBVoDZC6u/sGwkbwMbsl2HC79C+hEt1ELBOE5+BHwGW0 > dOAOn0b5Hkq3tCLzWIdwhuXHpn1fLNcTvoMQ1LbP9pHC0Nh6nz1GbclRTIu8jRMo > zGGHJeltYPnGFLdAVUc10Mrq3O9abnWxDa1UB3KXLnr8GkzoGMVqS6/3142V/oTM > 8m58tIyf47Z28IxreoGy > =FS4a > -END PGP SIGNATURE- > > > - > To unsubscribe, e-mail: users-unsubscr...@felix.apache.org > For additional commands, e-mail: users-h...@felix.apache.org > >
Re: Shutdown deadlock on OS X while doing AWT stuff
> How are you launching the framework? I'm just running felix.jar. > If you are using the standard Felix launcher, it registers a VM shutdown > hook to actually stop the framework which can sometimes cause issues. Since > you are explicitly stopping the framework, you could disable the launcher's > shutdown hook in conf/config.properties...look in that file and you'll see > how to disable it. > Well, I could be explicitly stopping the framework, or the stop could occur when the OS is shutdown and it *appears* this com.apple.eawt._AppEventHandler kicks in and calls System.exit... Does that count as an explicit stop? Note that my reading of the stack trace may not be correct. After all, I would've thought someone had noticed this before. Dan
Re: Shutdown deadlock on OS X while doing AWT stuff
Sorry, 'platform' is my code. Here's the full listing for platform.shutdown: public void shutdown() { if(null!=main) main.shutdown(); if(lastContext!=null) { try { lastContext.getBundle(0).stop(); } catch (BundleException e) { LOG.error("Failed to stop system bundle, attempting system.exit", e); System.exit(0); } } else { LOG.error("Failed to stop system bundle because had no BundleContext"); System.exit(0); } } As far as I can see, "main.shutdown" is not causing any trouble, because if @deactivate is being called on my Components, lastContext.getBundle(0).stop() must've been called. main.shutdown() performs some further shut down code, code that otherwise I guess could be part of another @deactivate. I don't receive any of the log messages. I'm beginning to wonder if this is just a interoperability problem with System.exit being called as a result of system shutdown. Dan On Tue, Mar 5, 2013 at 1:54 PM, Ferry Huberts wrote: > > > On 05/03/13 14:15, Dan Gravell wrote: > >> In my OSGi app (running on Felix 4.0.2) I use the Java SystemTray to add >> items to the system tray. One of these items is a 'quit' item: >> >> miQuit.addActionListener(new ActionListener() { >> @Override >> def actionPerformed(e:ActionEvent) { >> platform.shutdown(); >> } >> }); >> >> Then, PlatformImpl.shutdown does a: >> > > > Why do you delegate to 'platform'. > I think you can call bundleContext.getBundle(0).**stop() right there. > > See if that fixes your deadlock > Otherwise try removing the systray items before calling stop. > > >> lastContext.getBundle(0).stop(**); >> >> Where lastContext is the BundleContext for the containing bundle. The >> SystemTray code and PlatformImpl are in different bundles. Stopping the >> bundles has the effect of calling: >> >> @Deactivate def shutdown() { >> awt.SystemTray.getSystemTray.**getTrayIcons.foreach(**systemTray.remove); >> } >> >> This is back on the SystemTray component (I'm using bnd style DS here). >> >> I am seeing a deadlock occur, but fairly infrequently and only on OS X. >> I managed to get a stack trace last time. Here are two suspicious >> looking threads (I attached the entire thing): >> >> "FelixStartLevel" daemon prio=5 tid=109c2d800 nid=0x10f371000 in >> Object.wait() [10f36e000] >> java.lang.Thread.State: WAITING (on object monitor) >> at java.lang.Object.wait(Native Method) >> - waiting on <7eae23890> (a java.awt.EventQueue$**1AWTInvocationLock) >> at java.lang.Object.wait(Object.**java:485) >> at java.awt.EventQueue.**invokeAndWait(EventQueue.java:**1117) >> - locked <7eae23890> (a java.awt.EventQueue$**1AWTInvocationLock) >> at java.awt.Window.doDispose(**Window.java:1036) >> at java.awt.Window.dispose(**Window.java:974) >> at apple.awt.CTrayIconPeer.**disposeImpl(CTrayIconPeer.**java:58) >> at apple.awt.PeerImpl.dispose(**PeerImpl.java:30) >> at java.awt.TrayIcon.**removeNotify(TrayIcon.java:**701) >> at java.awt.SystemTray.remove(**SystemTray.java:273) >> - locked <7ed5e5968> (a java.awt.SystemTray) >> at >> com.elsten.bliss.ui.**systemtray.SystemTray$$**anonfun$shutdown$1.apply(* >> *SystemTray.scala:149) >> at >> com.elsten.bliss.ui.**systemtray.SystemTray$$**anonfun$shutdown$1.apply(* >> *SystemTray.scala:149) >> at >> scala.collection.**IndexedSeqOptimized$class.** >> foreach(IndexedSeqOptimized.**scala:34) >> at scala.collection.mutable.**ArrayOps.foreach(ArrayOps.**scala:38) >> at com.elsten.bliss.ui.**systemtray.SystemTray.** >> shutdown(SystemTray.scala:149) >> at sun.reflect.**NativeMethodAccessorImpl.**invoke0(Native Method) >> at >> sun.reflect.**NativeMethodAccessorImpl.**invoke(** >> NativeMethodAccessorImpl.java:**39) >> at >> sun.reflect.**DelegatingMethodAccessorImpl.**invoke(** >> DelegatingMethodAccessorImpl.**java:25) >> at java.lang.reflect.Method.**invoke(Method.java:597) >> [...] >> >> "AWT-EventQueue-0" prio=6 tid=105d82800 nid=0x11505f000 in Object.wait() >> [11505d000] >> java.lang.Thread.State: WAITING (on object monitor) >> at java.lang.Object.wait(Native Method) >> - waiting on <7ece2ed20> (a org.apache.felix.main.Main$1) >> at java.lang.Thread.join(Thread.**java:1210) >> - locked <7ece2ed20> (a org.apache.felix.main.Main$1) >> at java.lang.Thread.join(Thread.**java:1263) >> at >> java.lang.**ApplicationShutdownHooks.**runHooks(** >> ApplicationShutdownHooks.java:**79) >> at >> java.la
Shutdown deadlock on OS X while doing AWT stuff
In my OSGi app (running on Felix 4.0.2) I use the Java SystemTray to add items to the system tray. One of these items is a 'quit' item: miQuit.addActionListener(new ActionListener() { @Override def actionPerformed(e:ActionEvent) { platform.shutdown(); } }); Then, PlatformImpl.shutdown does a: lastContext.getBundle(0).stop(); Where lastContext is the BundleContext for the containing bundle. The SystemTray code and PlatformImpl are in different bundles. Stopping the bundles has the effect of calling: @Deactivate def shutdown() { awt.SystemTray.getSystemTray.getTrayIcons.foreach(systemTray.remove); } This is back on the SystemTray component (I'm using bnd style DS here). I am seeing a deadlock occur, but fairly infrequently and only on OS X. I managed to get a stack trace last time. Here are two suspicious looking threads (I attached the entire thing): "FelixStartLevel" daemon prio=5 tid=109c2d800 nid=0x10f371000 in Object.wait() [10f36e000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <7eae23890> (a java.awt.EventQueue$1AWTInvocationLock) at java.lang.Object.wait(Object.java:485) at java.awt.EventQueue.invokeAndWait(EventQueue.java:1117) - locked <7eae23890> (a java.awt.EventQueue$1AWTInvocationLock) at java.awt.Window.doDispose(Window.java:1036) at java.awt.Window.dispose(Window.java:974) at apple.awt.CTrayIconPeer.disposeImpl(CTrayIconPeer.java:58) at apple.awt.PeerImpl.dispose(PeerImpl.java:30) at java.awt.TrayIcon.removeNotify(TrayIcon.java:701) at java.awt.SystemTray.remove(SystemTray.java:273) - locked <7ed5e5968> (a java.awt.SystemTray) at com.elsten.bliss.ui.systemtray.SystemTray$$anonfun$shutdown$1.apply(SystemTray.scala:149) at com.elsten.bliss.ui.systemtray.SystemTray$$anonfun$shutdown$1.apply(SystemTray.scala:149) at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:34) at scala.collection.mutable.ArrayOps.foreach(ArrayOps.scala:38) at com.elsten.bliss.ui.systemtray.SystemTray.shutdown(SystemTray.scala:149) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) [...] "AWT-EventQueue-0" prio=6 tid=105d82800 nid=0x11505f000 in Object.wait() [11505d000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <7ece2ed20> (a org.apache.felix.main.Main$1) at java.lang.Thread.join(Thread.java:1210) - locked <7ece2ed20> (a org.apache.felix.main.Main$1) at java.lang.Thread.join(Thread.java:1263) at java.lang.ApplicationShutdownHooks.runHooks(ApplicationShutdownHooks.java:79) at java.lang.ApplicationShutdownHooks$1.run(ApplicationShutdownHooks.java:24) at java.lang.Shutdown.runHooks(Shutdown.java:79) at java.lang.Shutdown.sequence(Shutdown.java:123) at java.lang.Shutdown.exit(Shutdown.java:168) - locked <7faf9e240> (a java.lang.Class for java.lang.Shutdown) at java.lang.Runtime.exit(Runtime.java:90) at java.lang.System.exit(System.java:921) at com.apple.eawt._AppEventHandler.performQuit(_AppEventHandler.java:124) - locked <7ed6a2420> (a com.apple.eawt._AppEventHandler) at com.apple.eawt.QuitResponse.performQuit(QuitResponse.java:31) at com.apple.eawt._AppEventHandler$_QuitDispatcher.performDefaultAction(_AppEventHandler.java:382) at com.apple.eawt._AppEventHandler$_AppEventDispatcher$1.run(_AppEventHandler.java:487) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209) [...] Is there something I'm doing incorrectly? It looks like "_AppEventHandler.performQuit" is calling System.exit... but won't this be prone to deadlocks with OSGi? It's possible in this case that I chose to shutdown my app and this is what sent the event. If this is the case how can I work around this? I'm guessing that the removal of SystemTray items can't be done in this case, or has to be done in some managed thread context. Just wondering if anyone else has seen this. Dan - To unsubscribe, e-mail: users-unsubscr...@felix.apache.org For additional commands, e-mail: users-h...@felix.apache.org
ArrayStoreException when deserializing objects in a project with DynamicImport-Package:*
I am using the JDBM project in my application. To enable it to deserialize objects, I added DynamicImport-Package: * to its bundle headers. This appeared to work for a month or two. However in a recent build (which has undergone some restructuring) I've begun to get the following failure to deserialize: Message: java.lang.ArrayStoreException: com.elsten.bliss.music.policy.coverartpolicy.assessment.CoverArtAlternativesPart$CoverArtAlternativesPartSerialisationProxy java.io.ObjectInputStream.readArray(ObjectInputStream.java:1684) java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1340) java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1963) java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1887) java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1770) java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1346) java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1963) java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1887) java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1770) java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1346) java.io.ObjectInputStream.readArray(ObjectInputStream.java:1684) java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1340) java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1963) java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1887) java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1770) java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1346) java.io.ObjectInputStream.readObject(ObjectInputStream.java:368) jdbm.htree.HashBucket.readExternal(HashBucket.java:306) java.io.ObjectInputStream.readExternalData(ObjectInputStream.java:1809) java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1768) java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1346) java.io.ObjectInputStream.readObject(ObjectInputStream.java:368) jdbm.helper.Serialization.deserialize(Serialization.java:93) jdbm.helper.DefaultSerializer.deserialize(DefaultSerializer.java:102) jdbm.helper.DefaultSerializationHandler.deserialize(DefaultSerializationHandler.java:75) jdbm.recman.BaseRecordManager.fetch(BaseRecordManager.java:613) jdbm.recman.CacheRecordManager.fetch(CacheRecordManager.java:313) jdbm.recman.CacheRecordManager.fetch(CacheRecordManager.java:293) jdbm.htree.HashDirectory.get(HashDirectory.java:197) jdbm.htree.HashDirectory.get(HashDirectory.java:204) jdbm.htree.HashDirectory.get(HashDirectory.java:204) jdbm.htree.HashDirectory.get(HashDirectory.java:204) jdbm.htree.HTree.get(HTree.java:142) The class that is being loaded has not changed during the operation of the application. Furthermore, the JDBM database is cleared before running, so to my knowledge there's only one CoverArtAlternativesPartSerialisationProxy. I performed a Gogo 'which' which confirmed the class is loaded from the expected bundle. Any ideas on what is causing this or areas to investigate? Dan
Re: NoClassDefFoundError after update, caused by NPE in BundleRevisionImpl.calculateContentPath ?
Ok. So if the thread just ends up being parked and/or not executing any code that's in the bundle that was stopped for the rest of its life it's not going to cause a problem, although it is a leak and should obviously be avoided. Thanks, Dan On Wed, Aug 15, 2012 at 2:54 PM, Richard S. Hall wrote: > On Aug 15, 2012, at 05:02 , Dan Gravell > wrote: > > > A quick follow up to this... > > > > What is to be done with classes that start threads in their static > > initialisers? I've noticed some core Java API classes do this, for > example > > java.util.pref.FileSystemPreferences has a static Timer which is shutdown > > in the shutdown hook but otherwise runs every second. There's no way of > > shutting this timer downm (maybe some reflection magic but that's > obviously > > horrible). > > > > I wouldn't think you'd need to worry about a core class (the JRE may start > many shared threads), just make sure it isn't going to invoke any of your > code after your bundle stops. > > Technically, leaving threads running isn't the issue here. The issue is > that you've left threads running that are still trying to execute code from > a bundle that has been stopped and/or refreshed. You just need to make sure > that they stop trying to execute your bundle code. > > The fact that you leave a thread running becomes a second issue, since it > creates a resource leak. Some libraries assume their lifecycle is the same > as the JVM process, which is a bad assumption in an OSGi environment. > > -> richard > > > Dan > > > > On Thu, Aug 9, 2012 at 6:10 PM, Richard S. Hall >wrote: > > > >> Dan, > >> > >> I looked at your example and was able to recreate the issue. After > >> debugging it a little bit, it seems to be a fairly standard issue when > >> dealing with threads and OSGi: > >> > >> You must make sure that all threads created by a bundle have stopped > >> executing by the time the bundle's activator stop() method has returned. > >> > >> This can be complicated if you are using libraries that use threads and > >> don't give you a way to shut them all down. There is no way around this. > >> The start() method signals a bundle that it is ok to use resources and > the > >> stop() method signals that the bundle must stop using all resources. > >> > >> The NPE results because some thread is still trying to load classes on a > >> bundle wiring that has been discarded. > >> > >> -> richard > >> > >> p.s. Unrelated, I also noticed that your threads continually ask for the > >> bliss keystore resource when I'm just sitting idle at the update screen. > >> Not sure if that is intended or not. > >> > >> On Aug 9, 2012, at 10:48 , Richard S. Hall > wrote: > >> > >>> On Aug 9, 2012, at 10:44 , Dan Gravell > >> wrote: > >>> > >>>> I understand why you want it simplified but I don't think I can - part > >> of > >>>> the reason I think this is occurring is because it's a pretty complex > >> beast > >>>> with threads and bundles all over the place. > >>>> > >>>> I will send you some download instructions and instructions to run... > >> what > >>>> OS are you on? Is a plain folder structure in a ZIP easiest? > >>> > >>> Mac OS X. > >>> > >>> ZIP is fine. > >>> > >>> -> richard > >>> > >>>> > >>>> Dan > >>>> > >>>> On Thu, Aug 9, 2012 at 2:58 PM, Richard S. Hall >>> wrote: > >>>> > >>>>> Perhaps you can give me some way to download it and recreate > it…that's > >>>>> probably the quickest way. Of course, try to simplify it if you can… > >>>>> > >>>>> -> richard > >>>>> > >>>>> On Aug 9, 2012, at 06:29 , Dan Gravell < > elstensoftw...@googlemail.com> > >>>>> wrote: > >>>>> > >>>>>> Sorry: forgot to include my code... I am performing a refresh > >>>>>> (see blockingRefreshBundles()). Before this code runs I am using OBR > >> to > >>>>>> resolve a set of requirements. I then perform the update via the > >>>>> resolver. > >>>>>> 'startedBundles' are the bundles that were started at the time the &
Re: NoClassDefFoundError after update, caused by NPE in BundleRevisionImpl.calculateContentPath ?
A quick follow up to this... What is to be done with classes that start threads in their static initialisers? I've noticed some core Java API classes do this, for example java.util.pref.FileSystemPreferences has a static Timer which is shutdown in the shutdown hook but otherwise runs every second. There's no way of shutting this timer downm (maybe some reflection magic but that's obviously horrible). Dan On Thu, Aug 9, 2012 at 6:10 PM, Richard S. Hall wrote: > Dan, > > I looked at your example and was able to recreate the issue. After > debugging it a little bit, it seems to be a fairly standard issue when > dealing with threads and OSGi: > > You must make sure that all threads created by a bundle have stopped > executing by the time the bundle's activator stop() method has returned. > > This can be complicated if you are using libraries that use threads and > don't give you a way to shut them all down. There is no way around this. > The start() method signals a bundle that it is ok to use resources and the > stop() method signals that the bundle must stop using all resources. > > The NPE results because some thread is still trying to load classes on a > bundle wiring that has been discarded. > > -> richard > > p.s. Unrelated, I also noticed that your threads continually ask for the > bliss keystore resource when I'm just sitting idle at the update screen. > Not sure if that is intended or not. > > On Aug 9, 2012, at 10:48 , Richard S. Hall wrote: > > > On Aug 9, 2012, at 10:44 , Dan Gravell > wrote: > > > >> I understand why you want it simplified but I don't think I can - part > of > >> the reason I think this is occurring is because it's a pretty complex > beast > >> with threads and bundles all over the place. > >> > >> I will send you some download instructions and instructions to run... > what > >> OS are you on? Is a plain folder structure in a ZIP easiest? > > > > Mac OS X. > > > > ZIP is fine. > > > > -> richard > > > >> > >> Dan > >> > >> On Thu, Aug 9, 2012 at 2:58 PM, Richard S. Hall >wrote: > >> > >>> Perhaps you can give me some way to download it and recreate it…that's > >>> probably the quickest way. Of course, try to simplify it if you can… > >>> > >>> -> richard > >>> > >>> On Aug 9, 2012, at 06:29 , Dan Gravell > >>> wrote: > >>> > >>>> Sorry: forgot to include my code... I am performing a refresh > >>>> (see blockingRefreshBundles()). Before this code runs I am using OBR > to > >>>> resolve a set of requirements. I then perform the update via the > >>> resolver. > >>>> 'startedBundles' are the bundles that were started at the time the > update > >>>> runs: > >>>> > >>>> for (Bundle bundle : startedBundles) { > >>>> try { > >>>> if(!FelixObrUtils.isFragment(bundle)) > >>>> sysBundle.getBundleContext().getBundle(bundle.getBundleId()).stop(); > >>>> } catch (BundleException e) { > >>>> LOG.error("Failed to stop " + bundle.getSymbolicName(), e); > >>>> } > >>>> } > >>>> resolver.deploy(0); > >>>> blockingRefreshBundles(null, sysBundle.getBundleContext()); > >>>> for (Bundle bundle : startedBundles) { > >>>> try { > >>>> if(!FelixObrUtils.isFragment(bundle)) > >>>> sysBundle.getBundleContext().getBundle(bundle.getBundleId()).start(); > >>>> } catch (BundleException e) { > >>>> LOG.error("Failed to restart " + bundle.getSymbolicName(), e); > >>>> } > >>>> } > >>>> > >>>> protected void blockingRefreshBundles(Collection > >>> restartedBundles, > >>>> final BundleContext bundleContext) { > >>>> final FrameworkWiring frameworkWiring = > >>>> bundleContext.getBundle(0).adapt(FrameworkWiring.class); > >>>> if(null!=frameworkWiring) { > >>>> final CountDownLatch latch = new CountDownLatch(1); > >>>> frameworkWiring.refreshBundles(restartedBundles, new > FrameworkListener() > >>> { > >>>> @Override > >>>> public void frameworkEvent(FrameworkEvent arg0) { > >>>> if(arg0.getType()==FrameworkEvent.PACKAGES_REFRESHED) > latch.countDown(); > >>>> } > >>>> }); > >>>> try { &
Re: NoClassDefFoundError after update, caused by NPE in BundleRevisionImpl.calculateContentPath ?
Thanks Richard, I'll take another look at the thread situation. I suspect that it's mainly UI threads. Either way I'll try to find a way to stop them! Dan On Thu, Aug 9, 2012 at 6:10 PM, Richard S. Hall wrote: > Dan, > > I looked at your example and was able to recreate the issue. After > debugging it a little bit, it seems to be a fairly standard issue when > dealing with threads and OSGi: > > You must make sure that all threads created by a bundle have stopped > executing by the time the bundle's activator stop() method has returned. > > This can be complicated if you are using libraries that use threads and > don't give you a way to shut them all down. There is no way around this. > The start() method signals a bundle that it is ok to use resources and the > stop() method signals that the bundle must stop using all resources. > > The NPE results because some thread is still trying to load classes on a > bundle wiring that has been discarded. > > -> richard > > p.s. Unrelated, I also noticed that your threads continually ask for the > bliss keystore resource when I'm just sitting idle at the update screen. > Not sure if that is intended or not. > > On Aug 9, 2012, at 10:48 , Richard S. Hall wrote: > > > On Aug 9, 2012, at 10:44 , Dan Gravell > wrote: > > > >> I understand why you want it simplified but I don't think I can - part > of > >> the reason I think this is occurring is because it's a pretty complex > beast > >> with threads and bundles all over the place. > >> > >> I will send you some download instructions and instructions to run... > what > >> OS are you on? Is a plain folder structure in a ZIP easiest? > > > > Mac OS X. > > > > ZIP is fine. > > > > -> richard > > > >> > >> Dan > >> > >> On Thu, Aug 9, 2012 at 2:58 PM, Richard S. Hall >wrote: > >> > >>> Perhaps you can give me some way to download it and recreate it…that's > >>> probably the quickest way. Of course, try to simplify it if you can… > >>> > >>> -> richard > >>> > >>> On Aug 9, 2012, at 06:29 , Dan Gravell > >>> wrote: > >>> > >>>> Sorry: forgot to include my code... I am performing a refresh > >>>> (see blockingRefreshBundles()). Before this code runs I am using OBR > to > >>>> resolve a set of requirements. I then perform the update via the > >>> resolver. > >>>> 'startedBundles' are the bundles that were started at the time the > update > >>>> runs: > >>>> > >>>> for (Bundle bundle : startedBundles) { > >>>> try { > >>>> if(!FelixObrUtils.isFragment(bundle)) > >>>> sysBundle.getBundleContext().getBundle(bundle.getBundleId()).stop(); > >>>> } catch (BundleException e) { > >>>> LOG.error("Failed to stop " + bundle.getSymbolicName(), e); > >>>> } > >>>> } > >>>> resolver.deploy(0); > >>>> blockingRefreshBundles(null, sysBundle.getBundleContext()); > >>>> for (Bundle bundle : startedBundles) { > >>>> try { > >>>> if(!FelixObrUtils.isFragment(bundle)) > >>>> sysBundle.getBundleContext().getBundle(bundle.getBundleId()).start(); > >>>> } catch (BundleException e) { > >>>> LOG.error("Failed to restart " + bundle.getSymbolicName(), e); > >>>> } > >>>> } > >>>> > >>>> protected void blockingRefreshBundles(Collection > >>> restartedBundles, > >>>> final BundleContext bundleContext) { > >>>> final FrameworkWiring frameworkWiring = > >>>> bundleContext.getBundle(0).adapt(FrameworkWiring.class); > >>>> if(null!=frameworkWiring) { > >>>> final CountDownLatch latch = new CountDownLatch(1); > >>>> frameworkWiring.refreshBundles(restartedBundles, new > FrameworkListener() > >>> { > >>>> @Override > >>>> public void frameworkEvent(FrameworkEvent arg0) { > >>>> if(arg0.getType()==FrameworkEvent.PACKAGES_REFRESHED) > latch.countDown(); > >>>> } > >>>> }); > >>>> try { > >>>> latch.await(); > >>>> } catch (InterruptedException e) { > >>>> LOG.error("Interrupted while waiting for packages to refresh. Will > >>> continue > >>>> anywa
Re: NoClassDefFoundError after update, caused by NPE in BundleRevisionImpl.calculateContentPath ?
I understand why you want it simplified but I don't think I can - part of the reason I think this is occurring is because it's a pretty complex beast with threads and bundles all over the place. I will send you some download instructions and instructions to run... what OS are you on? Is a plain folder structure in a ZIP easiest? Dan On Thu, Aug 9, 2012 at 2:58 PM, Richard S. Hall wrote: > Perhaps you can give me some way to download it and recreate it…that's > probably the quickest way. Of course, try to simplify it if you can… > > -> richard > > On Aug 9, 2012, at 06:29 , Dan Gravell > wrote: > > > Sorry: forgot to include my code... I am performing a refresh > > (see blockingRefreshBundles()). Before this code runs I am using OBR to > > resolve a set of requirements. I then perform the update via the > resolver. > > 'startedBundles' are the bundles that were started at the time the update > > runs: > > > > for (Bundle bundle : startedBundles) { > > try { > > if(!FelixObrUtils.isFragment(bundle)) > > sysBundle.getBundleContext().getBundle(bundle.getBundleId()).stop(); > > } catch (BundleException e) { > > LOG.error("Failed to stop " + bundle.getSymbolicName(), e); > > } > > } > > resolver.deploy(0); > > blockingRefreshBundles(null, sysBundle.getBundleContext()); > > for (Bundle bundle : startedBundles) { > > try { > > if(!FelixObrUtils.isFragment(bundle)) > > sysBundle.getBundleContext().getBundle(bundle.getBundleId()).start(); > > } catch (BundleException e) { > > LOG.error("Failed to restart " + bundle.getSymbolicName(), e); > > } > > } > > > > protected void blockingRefreshBundles(Collection > restartedBundles, > > final BundleContext bundleContext) { > > final FrameworkWiring frameworkWiring = > > bundleContext.getBundle(0).adapt(FrameworkWiring.class); > > if(null!=frameworkWiring) { > > final CountDownLatch latch = new CountDownLatch(1); > > frameworkWiring.refreshBundles(restartedBundles, new FrameworkListener() > { > > @Override > > public void frameworkEvent(FrameworkEvent arg0) { > > if(arg0.getType()==FrameworkEvent.PACKAGES_REFRESHED) latch.countDown(); > > } > > }); > > try { > > latch.await(); > > } catch (InterruptedException e) { > > LOG.error("Interrupted while waiting for packages to refresh. Will > continue > > anyway"); > > } > > } else { > > LOG.warn("Couldn't adapt system bundle to framework wiring so will not > > refresh bundles"); > > } > > } > > > > Just a thought - might there be a problem in re-using the old references > to > > 'startedBundles'? Following the update, should I refresh these instances? > > > > Dan > > > > On Thu, Aug 9, 2012 at 11:19 AM, Felix Meschberger >wrote: > > > >> Hi > >> > >> I would assume you need to call PackageAdmin.refreshPackages() after > >> updating the bundles, such that all providers and consumers get to know > the > >> latest updates. > >> > >> If you just to Bundle.update the call to PackageAdmin.refreshPackages > must > >> also be done explicitly. If you are using installation tools such as > File > >> Install this call would be done automatically by the installation tool > >> along with updating the bundles. > >> > >> Regards > >> Felix > >> > >> Am 09.08.2012 um 11:59 schrieb Dan Gravell: > >> > >>> Hi all. I'm getting some NoClassDefFoundErrors and other > >> exceptions/errors > >>> after updating some bundles. The bundles work fine before. Restarting > >> Felix > >>> clears the problem (no more NCDFE) and the newly updating bundles work > >> fine > >>> once again. > >>> > >>> I'd like to be able to support updating while running, if possible. > >>> > >>> Here's a sample stacktrace: > >>> > >>> 2012-08-09 10:44:56,095 [ERROR] Error while executing > >>> AutomaticFixerCoverArtCommand (AggregatedPolic > >>> yCommand.java:65, thread policy pool 0) > >>> java.lang.ExceptionInInitializerError > >>> at > >>> > >> > com.elsten.bliss.music.policy.coverartpolicy.CoverArtUtils.dimensionsOf(CoverArtUtils.java > >>> :163) > >>> at > >>> > >> > com.elsten.bliss.music.policy.coverartpolicy.CoverArtUtils.openImageDimension(CoverArtUtil > >>
Re: NoClassDefFoundError after update, caused by NPE in BundleRevisionImpl.calculateContentPath ?
Sorry: forgot to include my code... I am performing a refresh (see blockingRefreshBundles()). Before this code runs I am using OBR to resolve a set of requirements. I then perform the update via the resolver. 'startedBundles' are the bundles that were started at the time the update runs: for (Bundle bundle : startedBundles) { try { if(!FelixObrUtils.isFragment(bundle)) sysBundle.getBundleContext().getBundle(bundle.getBundleId()).stop(); } catch (BundleException e) { LOG.error("Failed to stop " + bundle.getSymbolicName(), e); } } resolver.deploy(0); blockingRefreshBundles(null, sysBundle.getBundleContext()); for (Bundle bundle : startedBundles) { try { if(!FelixObrUtils.isFragment(bundle)) sysBundle.getBundleContext().getBundle(bundle.getBundleId()).start(); } catch (BundleException e) { LOG.error("Failed to restart " + bundle.getSymbolicName(), e); } } protected void blockingRefreshBundles(Collection restartedBundles, final BundleContext bundleContext) { final FrameworkWiring frameworkWiring = bundleContext.getBundle(0).adapt(FrameworkWiring.class); if(null!=frameworkWiring) { final CountDownLatch latch = new CountDownLatch(1); frameworkWiring.refreshBundles(restartedBundles, new FrameworkListener() { @Override public void frameworkEvent(FrameworkEvent arg0) { if(arg0.getType()==FrameworkEvent.PACKAGES_REFRESHED) latch.countDown(); } }); try { latch.await(); } catch (InterruptedException e) { LOG.error("Interrupted while waiting for packages to refresh. Will continue anyway"); } } else { LOG.warn("Couldn't adapt system bundle to framework wiring so will not refresh bundles"); } } Just a thought - might there be a problem in re-using the old references to 'startedBundles'? Following the update, should I refresh these instances? Dan On Thu, Aug 9, 2012 at 11:19 AM, Felix Meschberger wrote: > Hi > > I would assume you need to call PackageAdmin.refreshPackages() after > updating the bundles, such that all providers and consumers get to know the > latest updates. > > If you just to Bundle.update the call to PackageAdmin.refreshPackages must > also be done explicitly. If you are using installation tools such as File > Install this call would be done automatically by the installation tool > along with updating the bundles. > > Regards > Felix > > Am 09.08.2012 um 11:59 schrieb Dan Gravell: > > > Hi all. I'm getting some NoClassDefFoundErrors and other > exceptions/errors > > after updating some bundles. The bundles work fine before. Restarting > Felix > > clears the problem (no more NCDFE) and the newly updating bundles work > fine > > once again. > > > > I'd like to be able to support updating while running, if possible. > > > > Here's a sample stacktrace: > > > > 2012-08-09 10:44:56,095 [ERROR] Error while executing > > AutomaticFixerCoverArtCommand (AggregatedPolic > > yCommand.java:65, thread policy pool 0) > > java.lang.ExceptionInInitializerError > >at > > > com.elsten.bliss.music.policy.coverartpolicy.CoverArtUtils.dimensionsOf(CoverArtUtils.java > > :163) > >at > > > com.elsten.bliss.music.policy.coverartpolicy.CoverArtUtils.openImageDimension(CoverArtUtil > > s.java:187) > >[...] > > Caused by: java.lang.NullPointerException > >at > > > org.apache.felix.framework.BundleRevisionImpl.getResourcesLocal(BundleRevisionImpl.java:510) > >at > > > org.apache.felix.framework.BundleWiringImpl.findResourcesByDelegation(BundleWiringImpl.java:1127) > >at > > > org.apache.felix.framework.BundleWiringImpl.getResourcesByDelegation(BundleWiringImpl.java:1037) > >at > > > org.apache.felix.framework.BundleWiringImpl$BundleClassLoaderJava5.getResources(BundleWiringImpl.java:1778) > >at > > > org.eclipse.jetty.osgi.boot.internal.webapp.OSGiWebappClassLoader.getResources(OSGiWebappClassLoader.java:115) > >at > > java.util.ServiceLoader$LazyIterator.hasNext(ServiceLoader.java:340) > >at java.util.ServiceLoader$1.hasNext(ServiceLoader.java:432) > >at > > > javax.imageio.spi.IIORegistry.registerApplicationClasspathSpis(IIORegistry.java:206) > >at javax.imageio.spi.IIORegistry.(IIORegistry.java:138) > >at > > javax.imageio.spi.IIORegistry.getDefaultInstance(IIORegistry.java:159) > >at javax.imageio.ImageIO.(ImageIO.java:64) > > > > 2012-08-09 10:44:57,061 [ERROR] Error while executing > > AutomaticFixerCoverArtCommand (AggregatedPolicyCommand.java:65, thread > > policy pool 1) > > java.lang.NoClassDefFoundError: Could not initialize class > > javax.imageio.ImageIO > >
NoClassDefFoundError after update, caused by NPE in BundleRevisionImpl.calculateContentPath ?
Hi all. I'm getting some NoClassDefFoundErrors and other exceptions/errors after updating some bundles. The bundles work fine before. Restarting Felix clears the problem (no more NCDFE) and the newly updating bundles work fine once again. I'd like to be able to support updating while running, if possible. Here's a sample stacktrace: 2012-08-09 10:44:56,095 [ERROR] Error while executing AutomaticFixerCoverArtCommand (AggregatedPolic yCommand.java:65, thread policy pool 0) java.lang.ExceptionInInitializerError at com.elsten.bliss.music.policy.coverartpolicy.CoverArtUtils.dimensionsOf(CoverArtUtils.java :163) at com.elsten.bliss.music.policy.coverartpolicy.CoverArtUtils.openImageDimension(CoverArtUtil s.java:187) [...] Caused by: java.lang.NullPointerException at org.apache.felix.framework.BundleRevisionImpl.getResourcesLocal(BundleRevisionImpl.java:510) at org.apache.felix.framework.BundleWiringImpl.findResourcesByDelegation(BundleWiringImpl.java:1127) at org.apache.felix.framework.BundleWiringImpl.getResourcesByDelegation(BundleWiringImpl.java:1037) at org.apache.felix.framework.BundleWiringImpl$BundleClassLoaderJava5.getResources(BundleWiringImpl.java:1778) at org.eclipse.jetty.osgi.boot.internal.webapp.OSGiWebappClassLoader.getResources(OSGiWebappClassLoader.java:115) at java.util.ServiceLoader$LazyIterator.hasNext(ServiceLoader.java:340) at java.util.ServiceLoader$1.hasNext(ServiceLoader.java:432) at javax.imageio.spi.IIORegistry.registerApplicationClasspathSpis(IIORegistry.java:206) at javax.imageio.spi.IIORegistry.(IIORegistry.java:138) at javax.imageio.spi.IIORegistry.getDefaultInstance(IIORegistry.java:159) at javax.imageio.ImageIO.(ImageIO.java:64) 2012-08-09 10:44:57,061 [ERROR] Error while executing AutomaticFixerCoverArtCommand (AggregatedPolicyCommand.java:65, thread policy pool 1) java.lang.NoClassDefFoundError: Could not initialize class javax.imageio.ImageIO at com.elsten.bliss.music.policy.coverartpolicy.CoverArtUtils.dimensionsOf(CoverArtUtils.java:163) at com.elsten.bliss.music.policy.coverartpolicy.CoverArtUtils.openImageDimension(CoverArtUtils.java:187) [... no caused by trace here...] Immediately before that I get something I only see once I enable Felix debug logging: ERROR: Bundle com.elsten.bliss.ui [34] Unable to get module class path. (java.lang.NullPointerExcepti on) java.lang.NullPointerException at org.apache.felix.framework.BundleRevisionImpl.calculateContentPath(BundleRevisionImpl.java :410) at org.apache.felix.framework.BundleRevisionImpl.initializeContentPath(BundleRevisionImpl.jav a:347) at org.apache.felix.framework.BundleRevisionImpl.getContentPath(BundleRevisionImpl.java:333) at org.apache.felix.framework.BundleRevisionImpl.getResourcesLocal(BundleRevisionImpl.java:49 3) at org.apache.felix.framework.BundleWiringImpl.findResourcesByDelegation(BundleWiringImpl.jav a:1127) at org.apache.felix.framework.BundleWiringImpl.getResourcesByDelegation(BundleWiringImpl.java :1037) at org.apache.felix.framework.BundleWiringImpl$BundleClassLoaderJava5.getResources(BundleWiri ngImpl.java:1778) at org.eclipse.jetty.osgi.boot.internal.webapp.OSGiWebappClassLoader.getResources(OSGiWebappC lassLoader.java:115) at java.util.ServiceLoader$LazyIterator.hasNext(ServiceLoader.java:340) at java.util.ServiceLoader$1.hasNext(ServiceLoader.java:432) at javax.imageio.spi.IIORegistry.registerApplicationClasspathSpis(IIORegistry.java:206) at javax.imageio.spi.IIORegistry.(IIORegistry.java:138) at javax.imageio.spi.IIORegistry.getDefaultInstance(IIORegistry.java:159) at javax.imageio.ImageIO.(ImageIO.java:64) at com.elsten.bliss.music.policy.coverartpolicy.CoverArtUtils.dimensionsOf(CoverArtUtils.java :163) at com.elsten.bliss.music.policy.coverartpolicy.CoverArtUtils.openImageDimension(CoverArtUtil s.java:187) There are many of these NCDFEs but only one of those NPEs in BundleRevisionImpl. Once those have been thrown, "all hell seems to break loose" and I start getting NCDFEs for other classes including my own. Does the original exception cause these downstream ones or are they unrelated? During the update the Import-Package statements for javax.imageio.* remain stable. Let me know if more contextual logs are useful. I can provide the actual code that's running if it helps (it's large though). Dan
Re: Uses violations: cascading package version updates?
On Wed, Jul 25, 2012 at 4:07 PM, Richard S. Hall wrote: > On 7/25/12 10:57 , Dan Gravell wrote: > >> The best way to do this sort of stuff is to create a management agent that >>> records, deploys, and reinstates the proper state of your application >>> after >>> deployment operations. >>> >> >> So would the agent record the current state for each bundle, stop each >> bundle, update it, refresh, then restart? >> > > Pretty much. Ok! That works. I was a little intimidated by what you mean by 'management agent' but after several tries I got this working... at least with my current batch of updates. Here's what I do... I would appreciate a sanity review. https://gist.github.com/3177368 Some notes... The 'resourcesToUpdateExceptUpdater' is required because the updater bundle, where this code lives, cannot be stopped while this code works. That's because the bundle context becomes invalid. *Edit* actually, I now use the system bundle's context for some of this work... maybe I can use that instead? The 'sendUiStoppingMessageAndBlock' stuff is to instruct the UI to begin polling for the restart of the user interface after update. The Semaphore should return very quickly. It has to be a semaphore because the update sent to the UI occurs in a different thread - the UI is a comet web based UI. Dan
Re: Uses violations: cascading package version updates?
Thanks Richard... On Wed, Jul 25, 2012 at 3:52 PM, Richard S. Hall wrote: > > Would not be a good idea. Synchronous listeners are not supposed to change > the state of the bundle they receive an event about since the framework is > often in the middle of some operation on them. > Ok, makes sense. > The best way to do this sort of stuff is to create a management agent that > records, deploys, and reinstates the proper state of your application after > deployment operations. So would the agent record the current state for each bundle, stop each bundle, update it, refresh, then restart? If there are references for the best way of doing this do let me know (to avoid cluttering the mailing list!). Dan
Re: Uses violations: cascading package version updates?
On Wed, Jul 25, 2012 at 2:27 PM, Richard S. Hall wrote: > p.s. The constraint violation happens during deploy, I imagine, because > you are leaving your bundles in an active state, so OBR tries to restart > them (or you are telling OBR to start them when calling deploy()). The the > OBR patch I referenced, this will help since it refreshes before > restarting, but OBR is not intended to be a sophisticated management agent, > so you might need to write something better. > Ok, so the important thing here is that the refresh has to be done between update and start, correct? Could this be done with a SynchronousBundleListener? E.g. decide which bundles are being updated, then listen for the update event and when it occurs perform a refresh on that bundle? This would happen multiple times, for each bundle that is updated. I could potentially group all the updated bundles together given by taking a look at the state changes and trying to collect the bundles together somehow. It looks like resolveBundleRevision occurs before STARTING. Dan
Re: Uses violations: cascading package version updates?
> > If you refresh A after updating it, then both B and C should be refreshed > too since they depend on it. Then everyone will point to the same version > of 'a'. No? > Errr... I'm embarrassed to say I don't know. I'm using OBR and deploying a bunch of bundles (of which A, B and C are a subset) from a repository.xml. Basically I use a filter string to specify all of my bundles and then say deploy(START). _Then_ I do the refresh, but the uses constraints violation has already happened by then (when I did the deploy). Is there a better way? Should I take each resource and deploy, refresh, deploy, refresh? I thought refresh was supposed to be grouped to some extent? Dan
Uses violations: cascading package version updates?
I have the following bundles: bundle A { package a export-package:a } bundle B { package b.a package b.b package b.c package b.d package b.e import-package: a export-package:b.a;uses:=a, b.b;uses:=b.a, b.c;uses:=b.b, b.d;uses:=b.c, b.e;uses:=b.d } bundle C { package c import-package: b.e, a } Now, I update 'a' to a new version. C's required version of a is upped, but not B's. My understanding is that this would cause a 'uses' clause violation because C is exposed to the two versions of a direct from A (the new one) and via B (the old one). And so it proves: Chain 1: C [47.1] import: (&(osgi.wiring.package=a)(version>=1.1.0)) | export: osgi.wiring.package=a A [9.1] Chain 2: C [47.1] import: (&(osgi.wiring.package=b.e)(version>=1.0.0)) | export: osgi.wiring.package=b.e; uses:=a B [33.0] import: (&(osgi.wiring.package=a)(version>=1.0.0)) | export: osgi.wiring.package=a C [9.0] Now I don't have any beef with this, it makes sense. There are two versions of 'a' in the class space of C. Oddly (in my eyes anyway) if I merely restart Felix then it all appears to work. Surely if B was wired to version 1.0.0 of A it should remain so? Anyway, that's not really my question... My question is how to manage this. The only way I've found to avoid the uses constraint violation is to increase the version requirement to 'a' of every package that uses 'a', then increase version requirements for all those users of 'a' and versions of the packages that use those packages that use 'a' and so on. This doesn't scale in any non-trivial case so I'm assuming I'm doing something very wrong here. Hoping for some insight... Dan
Re: "No XPathFactory implementation found for the object model" when using XPath
Thanks Jeremias. I considered that although initially discounted it because I didn't want to change my own code too much to cater for different environments (being in an OSGi container versus just running in a 'vanilla' class loading context). I didn't go back to it, but it's definitely another option. Dan
Re: "No XPathFactory implementation found for the object model" when using XPath
Long story short: I just used org.osgi.framework.bootdelegation. I tried using the XPath API for specifying the classloader. My initial attempt was this: XPathFactory xpathFactory = XPathFactory.newInstance(XPathFactory.DEFAULT_OBJECT_MODEL_URI, "com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl", XPathFactory.class.getClassLoader()); Which is horrible because I have to specify the impl as I said in my previous email. Anyway, this didn't work because XPathFactory.class.getClassLoader() resolves to null, I guess because XPathFactory is loaded by the boot classpath class loader. I'm not sure on the best way to get the boot classpath class loader in an OSGi environment. Because the class loader is null, XPathFactory falls back to using the context class loader again. I decided that the improvement gleaned from using the specific ClassLoader API was reduced significantly by having to specify the XPathFactoryImpl name anyway, and so I am just going to use bootdelegation. Dan
Re: "No XPathFactory implementation found for the object model" when using XPath
Apologies, I was just abbreviating. And to be honest, I didn't actually trace it in a debugger. I'll do that later... unfortunately the webservice I was accessing has gone down so integration tests cannot be run just now. What's annoying in this case is that the XPathFactoryFinder is package private which means it cannot be reused by code looking to specify *just* the classloader. The XPathFactory forces you to specify a stringified class name. Dan
Re: "No XPathFactory implementation found for the object model" when using XPath
Looking at the OpenJDK (I'm not sure on whether impls are shared by different JREs... anyway...) it appears to prefer the thread context classloader, if it is not null. Otherwise. it uses the XPathFactory class's classloader (which should work, but I suspect the context class loader is non-null). To be fair, I missed before that there is a way of doing this by specifying the class loader. I assume setting this to the XPathFactory's class's class loader is correct, rather than my bundle class's classloader. For boot delegation, "com.sun.*" can be used rather than all package names right? I have no idea what classes might be loaded in the depths of the 3rd party libraries I use. This could blow up at any time. Dan On Wed, Jul 11, 2012 at 12:34 PM, Neil Bartlett wrote: > Well... it depends what the XPathFactory.newInstance() method actually > does in order to load the class. For example it may try to walk up the > stack and load from the calling classloader. This is the JRE we're > talking about, so you have to expect it to be batshit crazy and as > complicated as possible! > > I think in this scenario you should probably add the package > "com.sun.org.apache.xpath.internal.jaxp" to bootdelegation, since it > isn't a real dependency of your bundle, and the JRE is assuming that > it's always visible. I'd like to hear the opinion of others on this > though. > > Neil > > On Wed, Jul 11, 2012 at 12:29 PM, Dan Gravell > wrote: > > I'm a little puzzled about this. I have the following piece of code: > > > > XPathFactory xpathFactory = XPathFactory.newInstance(); > > > > I have the following import in the manifest for the bundle containing the > > above code: > > > > Import-Package: javax.xml.xpath > > > > When I run, I get: > > > > java.lang.RuntimeException: XPathFactory#newInstance() failed to create > an > > XPathFactory for the default object model: > > http://java.sun.com/jaxp/xpath/dom with the > > XPathFactoryConfigurationException: > > javax.xml.xpath.XPathFactoryConfigurationException: No XPathFactory > > implementation found for the object model: > > http://java.sun.com/jaxp/xpath/dom > > at javax.xml.xpath.XPathFactory.newInstance(XPathFactory.java:98) > > > > It looks like XPath tries to load the class > > "com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl". > > > > Shouldn't this work? I only need to import the package for the API I use, > > not the impl too right? > > > > Do I need to add com.sun.org.apache.xpath.internal.jaxp to the > > Export-Packages on my system bundle fragment? If so, why? I thought this > > was only required if I was directly > > accessing com.sun.org.apache.xpath.internal.jaxp (with a requisite > > Import-Package) from my bundle. > > > > Dan > > - > To unsubscribe, e-mail: users-unsubscr...@felix.apache.org > For additional commands, e-mail: users-h...@felix.apache.org > >
"No XPathFactory implementation found for the object model" when using XPath
I'm a little puzzled about this. I have the following piece of code: XPathFactory xpathFactory = XPathFactory.newInstance(); I have the following import in the manifest for the bundle containing the above code: Import-Package: javax.xml.xpath When I run, I get: java.lang.RuntimeException: XPathFactory#newInstance() failed to create an XPathFactory for the default object model: http://java.sun.com/jaxp/xpath/dom with the XPathFactoryConfigurationException: javax.xml.xpath.XPathFactoryConfigurationException: No XPathFactory implementation found for the object model: http://java.sun.com/jaxp/xpath/dom at javax.xml.xpath.XPathFactory.newInstance(XPathFactory.java:98) It looks like XPath tries to load the class "com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl". Shouldn't this work? I only need to import the package for the API I use, not the impl too right? Do I need to add com.sun.org.apache.xpath.internal.jaxp to the Export-Packages on my system bundle fragment? If so, why? I thought this was only required if I was directly accessing com.sun.org.apache.xpath.internal.jaxp (with a requisite Import-Package) from my bundle. Dan
Re: Help me understand ClassCastException after update
Gah, I've just seen it again. Please bear with me. This time I got a list of the BundleEvents concerning the two bundles. Remember: com.elsten.bliss.bundle invokes code in com.elsten.bliss.platform and then uses the return types to register services. STOPPED com.elsten.bliss.platform [25] UNRESOLVED com.elsten.bliss.platform [25] UPDATED com.elsten.bliss.platform [25] STOPPED com.elsten.bliss.bundle [31] UNRESOLVED com.elsten.bliss.bundle [31] UPDATED com.elsten.bliss.bundle [31] RESOLVED com.elsten.bliss.platform [25] STARTED com.elsten.bliss.platform [25] RESOLVED com.elsten.bliss.bundle [31] STOPPED com.elsten.bliss.bundle [31]ERROR: Resolver: Start error - com.elsten.bliss.bundle org.osgi.framework.BundleException: Activator start error in bundle com.elsten.bliss.bundle [31]. at org.apache.felix.framework.Felix.activateBundle(Felix.java:2027) at org.apache.felix.framework.Felix.startBundle(Felix.java:1895) at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:944) at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:931) at org.apache.felix.bundlerepository.impl.ResolverImpl.deploy(ResolverImpl.java:630) at com.elsten.bliss.updater.OnlineUpdater$2.run(OnlineUpdater.java:62) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) at java.lang.Thread.run(Thread.java:679) Caused by: java.lang.ClassCastException: com.elsten.bliss.music.policy2.PerFixLicensedPolicyCommandExecutor cannot be cast to com.elsten.bliss.music.policy2.PerFixLicensedPolicyCommandExecutor at com.elsten.osgi.Activator.start(Activator.java:39) at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:641) at org.apache.felix.framework.Felix.activateBundle(Felix.java:1977) ... 8 more I'll refer to com.elsten.bliss.bundle as .bundle and com.elsten.bliss.platform as .platform from now... What I don't understand is that the BundleEvents show that both bundles went through the stop, update, start (only for .bundle to fail to start) cycle. So I don't understand why .bundle would have a reference to an old version of the class in .platform, thus causing the CCE. If .platform did its own service registration I guess this wouldn't happen because then there's no real wiring to do? Dan
Re: Help me understand ClassCastException after update
Well that's interesting. I added a bundle listener before my deploy call, and also changed the deploy to run inside a thread. And now it works. Every time. I guess it's running it in a separate thread that works? I do still get these NPEs: Exception in thread "pool-66-thread-2" java.lang.NullPointerException at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1432) at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:72) at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1843) at java.lang.ClassLoader.loadClass(ClassLoader.java:266) at net.liftweb.actor.LAScheduler$$anonfun$9$$anon$2$$anon$3.run(LiftActor.scala:66) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) at java.lang.Thread.run(Thread.java:679) Exception in thread "pool-66-thread-4" java.lang.NullPointerException at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1432) at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:72) at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1843) at java.lang.ClassLoader.loadClass(ClassLoader.java:266) at net.liftweb.actor.LAScheduler$$anonfun$9$$anon$2$$anon$3.run(LiftActor.scala:66) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) at java.lang.Thread.run(Thread.java:679) ... however I think they may be related to old threads from the closed-down old instance of the UI. They appear to be benign if unsightly. For the refresh call, I have written my BundleListener so that it counts up the Bundles that go into STOPPED state and then once each of them are STARTED again I run the refresh. I suppose another way of doing it would be to get the Requirements from the Resolver and wait for them to be UPDATED. The way I'm currently doing it may conflict if other bundles were being STARTED and STOPPED at the same time, but this is a simple, single-user-and-app environment rather than an app server or anything like that so I'm happy with that for now (unless anyone sees any obvious flaws I'm missing). Dan On Tue, Jul 3, 2012 at 9:17 AM, Dan Gravell wrote: > Thanks for the offer Richard. I'm going to do some more digging on the > threading side of things, as you advised in your follow up. At the same > time I also discovered > http://blog.osgi.org/2007/07/best-practice-with-depressed-bundles.html last > night which made me think I need to think more about the threading going > on. There are a number of threads in my app including from the UI which the > source of the deploy() call. The UI is web based; the actual call comes > from a Scala actor (it's using the Lift framework). > > If I make no further progress I'll try to create a few bundle for you to > take a look at. Assume you need the source too... > > Dan > > > On Mon, Jul 2, 2012 at 8:46 PM, Richard S. Hall wrote: > >> Seems like this could take forever...perhaps you can create a scaled down >> example you can email me to reproduce the issue. >> >> -> richard > >
Re: Update all bundles, or update one that is dependent on the rest?
Thanks Felix. Just to clarify, you answered my question by saying "update just bundle C". I need to move to updating all bundles, rather than just one. Also thanks for the guidance on incrementing the micro level. Dan
Re: Help me understand ClassCastException after update
Thanks for the offer Richard. I'm going to do some more digging on the threading side of things, as you advised in your follow up. At the same time I also discovered http://blog.osgi.org/2007/07/best-practice-with-depressed-bundles.html last night which made me think I need to think more about the threading going on. There are a number of threads in my app including from the UI which the source of the deploy() call. The UI is web based; the actual call comes from a Scala actor (it's using the Lift framework). If I make no further progress I'll try to create a few bundle for you to take a look at. Assume you need the source too... Dan On Mon, Jul 2, 2012 at 8:46 PM, Richard S. Hall wrote: > Seems like this could take forever...perhaps you can create a scaled down > example you can email me to reproduce the issue. > > -> richard
Re: Help me understand ClassCastException after update
Oh I'm ~95% certain I'm doing something wrong ;) I haven't seen a walkthrough yet of writing this kind of code, so I've been going by the OSGi spec, Javadocs and piecing together other mailing list posts to try to work out what I need to call. Hence my other question about how update is "meant to be done" in multi bundle environments. Any link to non trivial examples are gratefully appreciated. Anyway, these errors appear before refreshBundles is called... they are as a result of the OBR deploy call. Although I refactored the updater into its own bundle, the update routine is being called from a bundle that is being updated, specifically the user interface where the user clicks 'Update'. The NPE stack trace shows the UI being used before update. The same thread from the old UI has updated the bundle and started the new bundle, but I guess that means the same classes for the old UI are being used, hence the casting problems? However, I can't *not* update the UI, it's a core part of my app that I want to update, but the UI has to be used to perform the update. How would one go about this? Apologies for such noob questions. Dan On Mon, Jul 2, 2012 at 4:45 PM, Richard S. Hall wrote: > I would venture to guess you are still doing something wrong...keep in > mind that the call to refreshBundles() is asynchronous, so you shouldn't > immediately try to start or do anything with your bundles. You need to give > a listener to refresh so you know when it is done. > > -> richard > > > On 7/2/12 11:35, Dan Gravell wrote: > >> So, I refactored the updater to a different bundle. Unfortunately I get >> the >> same problem. In two different runs I observed two different issues, one >> the CCE shown before, the other the LinkageError also shown before: >> >> ERROR: Resolver: Start error - com.elsten.bliss.bundle >> org.osgi.framework.**BundleException: Activator start error in bundle >> com.elsten.bliss.bundle [42]. >> at org.apache.felix.framework.**Felix.activateBundle(Felix.**java:2027) >> at org.apache.felix.framework.**Felix.startBundle(Felix.java:**1895) >> at org.apache.felix.framework.**BundleImpl.start(BundleImpl.**java:944) >> at org.apache.felix.framework.**BundleImpl.start(BundleImpl.**java:931) >> at >> org.apache.felix.**bundlerepository.impl.**ResolverImpl.deploy(** >> ResolverImpl.java:630) >> at com.elsten.bliss.updater.**OnlineUpdater.updateTo(** >> OnlineUpdater.java:48) >> at com.elsten.bliss.ui.model.**Updater$.update(Updater.scala:**17) >> at >> com.elsten.bliss.ui.comet.**Update$$anonfun$lowPriority$1$** >> $anonfun$apply$1.apply$mcV$sp(**Update.scala:75) >> at >> com.elsten.bliss.ui.comet.**Update$$anonfun$lowPriority$1$** >> $anonfun$apply$2.apply$mcV$sp(**Update.scala:72) >> at >> com.elsten.bliss.ui.comet.**Update$$anonfun$lowPriority$1$** >> $anonfun$apply$2.apply(Update.**scala:72) >> at >> com.elsten.bliss.ui.comet.**Update$$anonfun$lowPriority$1$** >> $anonfun$apply$2.apply(Update.**scala:72) >> at >> scala.concurrent.ThreadRunner$**$anon$1$$anonfun$run$1.apply(** >> ThreadRunner.scala:37) >> at >> scala.concurrent.ThreadRunner.**scala$concurrent$ThreadRunner$** >> $tryCatch(ThreadRunner.scala:**31) >> at scala.concurrent.ThreadRunner$**$anon$1.run(ThreadRunner.**scala:37) >> at java.lang.Thread.run(Thread.**java:679) >> Caused by: java.lang.LinkageError: loader constraint violation: when >> resolving method >> "com.elsten.bliss.main.Main.**getLicenceStore()Lcom/elsten/** >> bliss/licence/**PerFixLicenceStore;" >> the class loader (instance of >> org/apache/felix/framework/**BundleWiringImpl$**BundleClassLoaderJava5) >> of the >> current class, com/elsten/osgi/Activator, and the class loader (instance >> of >> org/apache/felix/framework/**BundleWiringImpl$**BundleClassLoaderJava5) >> for >> resolved class, com/elsten/bliss/main/Main, have different Class objects >> for the type com/elsten/bliss/licence/**PerFixLicenceStore used in the >> signature >> at com.elsten.osgi.Activator.**start(Activator.java:38) >> at >> org.apache.felix.framework.**util.SecureAction.** >> startActivator(SecureAction.**java:641) >> at org.apache.felix.framework.**Felix.activateBundle(Felix.**java:1977) >> ... 14 more >> >> I also get this NPE just before which doesn't appear to be related to >> anything directly called by *me*: >> >> Exception in thread "pool-43-thread-5" java.lang.NullPointerException >> at >> org.apache.felix.framework.**BundleWiringImpl.** >> findClassOrResourceByDelegatio**n(
Re: Help me understand ClassCastException after update
So, I refactored the updater to a different bundle. Unfortunately I get the same problem. In two different runs I observed two different issues, one the CCE shown before, the other the LinkageError also shown before: ERROR: Resolver: Start error - com.elsten.bliss.bundle org.osgi.framework.BundleException: Activator start error in bundle com.elsten.bliss.bundle [42]. at org.apache.felix.framework.Felix.activateBundle(Felix.java:2027) at org.apache.felix.framework.Felix.startBundle(Felix.java:1895) at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:944) at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:931) at org.apache.felix.bundlerepository.impl.ResolverImpl.deploy(ResolverImpl.java:630) at com.elsten.bliss.updater.OnlineUpdater.updateTo(OnlineUpdater.java:48) at com.elsten.bliss.ui.model.Updater$.update(Updater.scala:17) at com.elsten.bliss.ui.comet.Update$$anonfun$lowPriority$1$$anonfun$apply$1.apply$mcV$sp(Update.scala:75) at com.elsten.bliss.ui.comet.Update$$anonfun$lowPriority$1$$anonfun$apply$2.apply$mcV$sp(Update.scala:72) at com.elsten.bliss.ui.comet.Update$$anonfun$lowPriority$1$$anonfun$apply$2.apply(Update.scala:72) at com.elsten.bliss.ui.comet.Update$$anonfun$lowPriority$1$$anonfun$apply$2.apply(Update.scala:72) at scala.concurrent.ThreadRunner$$anon$1$$anonfun$run$1.apply(ThreadRunner.scala:37) at scala.concurrent.ThreadRunner.scala$concurrent$ThreadRunner$$tryCatch(ThreadRunner.scala:31) at scala.concurrent.ThreadRunner$$anon$1.run(ThreadRunner.scala:37) at java.lang.Thread.run(Thread.java:679) Caused by: java.lang.LinkageError: loader constraint violation: when resolving method "com.elsten.bliss.main.Main.getLicenceStore()Lcom/elsten/bliss/licence/PerFixLicenceStore;" the class loader (instance of org/apache/felix/framework/BundleWiringImpl$BundleClassLoaderJava5) of the current class, com/elsten/osgi/Activator, and the class loader (instance of org/apache/felix/framework/BundleWiringImpl$BundleClassLoaderJava5) for resolved class, com/elsten/bliss/main/Main, have different Class objects for the type com/elsten/bliss/licence/PerFixLicenceStore used in the signature at com.elsten.osgi.Activator.start(Activator.java:38) at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:641) at org.apache.felix.framework.Felix.activateBundle(Felix.java:1977) ... 14 more I also get this NPE just before which doesn't appear to be related to anything directly called by *me*: Exception in thread "pool-43-thread-5" java.lang.NullPointerException at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1432) at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:72) at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1843) at java.lang.ClassLoader.loadClass(ClassLoader.java:266) at net.liftweb.actor.LAScheduler$$anonfun$9$$anon$2$$anon$3.run(LiftActor.scala:66) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) at java.lang.Thread.run(Thread.java:679) I also observed my bundles being stopped and restarted several times after these problems arise. I'm beginning to wonder whether forcing a restart of the VM might be easier? Maybe the number of packages I have is too large, thereby making version clashes more likely? Dan
Re: Host Application cannot call Exported Class in OSGI Bundle
I think you can use OSGi services for this. See http://njbartlett.name/2011/03/07/embedding-osgi.html#dsq-comment-300916839. Dan
Re: Update all bundles, or update one that is dependent on the rest?
Cheers Neil, clarifications inline... On Mon, Jul 2, 2012 at 2:35 PM, Neil Bartlett wrote: > > Imagine the following package dependencies: > > > > A -> B -> C > > > > That is, A is dependent on B, B is dependent on C. A, B and C are all in > > different bundles. For the sake of discussion, the bundles are also > called > > A, B and C. The package dependencies are declared in the respective > > manifests for each bundle > > > > Now, I am running C and I notice a CNFE. So I add the required package to > > C's manifest. > > This is not a very precise description of the problem... "add the > required package to C's manifest" could be interpreted in many ways. > Are you adding the package as a new export of C? > Sorry. I meant the package required to avoid the CNFE. In this case, javax.xml.parsers (I think). This isn't really relevant to my question though, I was just thinking up "some change" to my bundle. It could've been a code change... > Also, why did the CNFE happen, and from which bundle? It sounds like > you were missing an Import-Package somewhere, but that kind of problem > would need to be fixed in A or B, not in C. > >From bundle C, because javax.xml.parsers wasn't in Import-Package. I added this and it worked. I don't know why PDE didn't pick this up nor why I didn't see it running under Equinox. But as I said above, this isn't related to my posting, it's just an example of a change which means versions have to be updated. > Assuming it's a new export then it's a new feature of the bundle, > therefore the Bundle-Version should be incremented in its minor (i.e. > second segment). However, semantic versioning of Bunde-Version can be > a little looser than package versions because they're not actually > used in resolution (if we ignore Require-Bundle!). No, just an Import-Package. > > 1) Choose an arbitrary package in bundle C and incremement the version > > Why? > Because... (deep breath) C is a dependency of B which is a dependency of A, and I am only updating A as a result of the strategy I outlined in my very first paragragh. To get C to update so it works, given I only update A, I need to update the versions so that the correct versions get pulled through when I update A. OBR sees that A has a new version, so it looks at its requirements, and sees a req for package B version n' which in turn is in bundle B which has a req for package C version n'. That's how I think it's working anyway. > > 2) In the import for the package chosen in (1) in bundle B, increment the > > version so the new version will be pulled in upon update. > > This doesn't make sense since B could not have an existing import for > the package (assuming I understood correctly that you are adding a new > Export to C). > No, so maybe ignore that. > > 3) Now increment an arbitrary package in B > > Why? Does B actually need to change at all? If not, why update it? > Because I am only updating A, my "psuedo feature". To get C to update, A has to have requirements to update down the chain. > > 4) In the import for the package chosen in (3) in bundle A, increment the > > version so the new version will be pulled in upon update > > 5) Increment the version of bundle A so that OBR will update it > > Why? Again it looks like A doesn't need to change, so there's no need > to update it. > See the answer for B. > > If I update all extant bundles then I don't need to do this, but how do I > > remove bundles that are no longer required? > > I don't *think* that OBR currently supports "garbage collection" for > bundles that are no longer needed. However it sounds like you don't > need to create anywhere near as much garbage as you're currently > creating, so this is probably less of a problem than you think it is. > Agreed. I think I am answering myself that the other way of doing it, updating all extant rather than one which has dependencies, is the best way. Are there any recommended approaches or best practices to this process for instance covering getting rid of bundles no longer needed? If I update each bundle that exists, does ordering matter? For example, with service registration and other implicit dependencies. I think that's why I decided against that approach originally. Dan
Update all bundles, or update one that is dependent on the rest?
When updating bundles, is the best strategy to update all extant bundles or update one bundle which is a little like an eclipse feature, having dependencies to the rest? I've been doing the latter but the resulting workflow seems pretty crazy to me. Imagine the following package dependencies: A -> B -> C That is, A is dependent on B, B is dependent on C. A, B and C are all in different bundles. For the sake of discussion, the bundles are also called A, B and C. The package dependencies are declared in the respective manifests for each bundle Now, I am running C and I notice a CNFE. So I add the required package to C's manifest. Bear in mind first of all that this isn't actually an API change and not really a package level code change either, so I'm not 100% sure where that sits in 'semantic versioning', but anyway here's what I do after adding the dependency: 1) Choose an arbitrary package in bundle C and incremement the version 2) In the import for the package chosen in (1) in bundle B, increment the version so the new version will be pulled in upon update. 3) Now increment an arbitrary package in B 4) In the import for the package chosen in (3) in bundle A, increment the version so the new version will be pulled in upon update 5) Increment the version of bundle A so that OBR will update it If I update all extant bundles then I don't need to do this, but how do I remove bundles that are no longer required? Dan
Re: Help me understand ClassCastException after update
> > Your code below is doing a "resolveBundles()", not "refreshBundles()"... :-X And yes, that's what I said below. You cannot do this code in the bundle > being updated. You need to be doing it from a separate bundle that is NOT > being updated. > Bundles are not supposed to change their own state. I'll factor this stuff out. My plan is to expose the ability to update my app in a Service, which is then looked up in my UI. I'll create a separate bundle purely for the updater which registers itself in its Activator upon start. Thanks for your time! Dan
Re: Help me understand ClassCastException after update
Thanks. That makes sense, but the call to refresh via the 'context' occurs after the deploy, and so after where all the CCE and LinkageErrors occur. I just realised I hadn't pasted that stack trace yet...: ERROR: Resolver: Start error - com.elsten.bliss.bundle org.osgi.framework.BundleException: Activator start error in bundle com.elsten.bliss.bundle [42]. at org.apache.felix.framework.Felix.activateBundle(Felix.java:2027) at org.apache.felix.framework.Felix.startBundle(Felix.java:1895) at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:944) at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:931) at org.apache.felix.bundlerepository.impl.ResolverImpl.deploy(ResolverImpl.java:630) at com.elsten.osgi.OnlineUpdater.updateTo(OnlineUpdater.java:48) [...] Caused by: java.lang.ClassCastException: com.elsten.bliss.music.policy2.PerFixLicensedPolicyCommandExecutor cannot be cast to com.elsten.bliss.music.policy2.PerFixLicensedPolicyCommandExecutor at com.elsten.osgi.Activator.start(Activator.java:42) at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:641) at org.apache.felix.framework.Felix.activateBundle(Felix.java:1977) ... 14 more Or is it also the case that the bundle cannot update (deploy) itself by running the update code within itself? Dan On Sun, Jul 1, 2012 at 2:50 PM, Richard S. Hall wrote: > > On 7/1/12 9:38, Dan Gravell wrote: > >> Thanks Richard... >> >> On Sun, Jul 1, 2012 at 2:15 PM, Richard S. Hall > >wrote: >> >> I have to imagine the simple solution for your scenario is to deploy your >>> client and your server (with OBR or not), then to perform a refresh >>> afterwards. >>> >>> ... but this is what I'm doing isn't it? Here's my actual code to >> deploy: >> >> final Resource bundleResource = >> FelixObrUtils.**getLatestBundleResource(**repoAdminSupplier); >> Resolver resolver = repoAdminSupplier.get().**resolver(); >> resolver.add(bundleResource); >> if (resolver.resolve()) { >> listener.installBundleStart(); >> resolver.deploy(Resolver.**START); >> // null to resolve all unresolved bundles >> context.getBundle(0).adapt(**FrameworkWiring.class).** >> resolveBundles(null); >> listener.**installBundleComplete(); >> } else { >> // handling code... >> } >> >> FelixObrUtils.**getLatestBundleResource looks inside the RepositoryAdmin >> and >> returns the highest versioned Resource with the symbolic name >> "com.elsten.bliss.bundle". This is resolved (which should bring in the new >> dependencies) and then deployed. >> >> This code is itself running inside com.elsten.bliss.bundle. >> >> Thanks for the info about refreshing and the BundleContext. I always >> guessed that approach was a bit suspect. What is the correct way of >> retrieving the FrameworkWiring without the BundleContext? >> > > For the above to work, the "context" must be from a bundle that hasn't > been updated. So, if you have three bundles: updater, client, and server. > And updater is doing the above code to update server and client, then it > should work. > > -> richard > > >> Dan >> >> >> If we release a modified version of OBR that automatically refreshes, >>> then >>> you shouldn't need to manually perform the refresh afterwards. >>> >>> -> richard >>> >>> I'm using OBR, and the Client is marked as >>> >>>> requiring a package on Server that was updated. Therefore I expected >>>> Server >>>> to be updated before Client (although this assumption might be wrong). >>>> In >>>> OBR API terms I am *only* calling deploy() on the Client BundleResource. >>>> >>>> The other, separate, package named 'server' within the Server bundle >>>> that >>>> contains type A was not updated and the requirement was not updated. >>>> >>>> When one package is updated but the other isn't within a bundle I >>>> assumed >>>> the classloader would be refreshed for the entire bundle, so affecting >>>> both >>>> packages, by virtue of the bundle being updated. >>>> >>>> So I ran an experiment. In bundle "Server", I updated the exported >>>> version >>>> of package "server". I then updated bundle "Server"'s version to ensure >>>> it >>>> would be updated. In "Client"'s manifest I changed the version &g
Re: Help me understand ClassCastException after update
Client") has packages: >> com.elsten.osgi [the actual name for the 'client' package. The package >> containing the Activator that runs a class in com.elsten.bliss.main and >> uses the result to register services] >> >> Bundle com.elsten.bliss.platform (nee "Server") has packages: >> com.elsten.bliss.main [the package containing the class that provides the >> services to 'client'] >> com.elsten.bliss.licence [the package containing the type showing the new >> problem] >> com.elsten.bliss.music.policy2 [the actual name for the 'server' package] >> >> So then I updated com.elsten.bliss.licence's version, containing bundle >> version, import version, and containing bundle of the import's version. I >> ran the update again. This time there were no errors! Although refresh >> still failed: >> >> java.lang.**IllegalStateException: Invalid BundleContext. >> at >> org.apache.felix.framework.**BundleContextImpl.**checkValidity(** >> BundleContextImpl.java:514) >> at >> org.apache.felix.framework.**BundleContextImpl.getBundle(** >> BundleContextImpl.java:173) >> at com.elsten.osgi.OnlineUpdater.**updateTo(OnlineUpdater.java:**51) >> >> This suggests the bundle did not restart. But I stopped the JVM and didn't >> note whether the application was still usable, so I ran the test again, >> removing felix-cache and performing the update against the same bundles. >> This time I get a *different* result: >> >> ERROR: Resolver: Start error - com.elsten.bliss.bundle >> org.osgi.framework.**BundleException: Uses constraint violation. Unable >> to >> resolve bundle revision com.elsten.bliss.platform [11.1] because it is >> exposed to package 'com.elsten.musicbrainz' from bundle revisions >> com.elsten.musicbrainz [30.1] and com.elsten.musicbrainz [30.0] via two >> dependency chains. >> >> Chain 1: >>com.elsten.bliss.platform [11.1] >> import: (&(osgi.wiring.package=com.**elsten.musicbrainz)(version>=** >> 1.0.2)) >> | >> export: osgi.wiring.package=com.**elsten.musicbrainz >>com.elsten.musicbrainz [30.1] >> >> Chain 2: >>com.elsten.bliss.platform [11.1] >> import: >> (&(osgi.wiring.package=com.**elsten.musicbrainz.model)(**version>=1.0.1)) >> | >> export: osgi.wiring.package=com.**elsten.musicbrainz.model; >> uses:=com.elsten.musicbrainz >> export: osgi.wiring.package=com.**elsten.musicbrainz >>com.elsten.musicbrainz [30.0] >> at org.apache.felix.framework.**Felix.resolveBundleRevision(** >> Felix.java:3832) >> at org.apache.felix.framework.**Felix.startBundle(Felix.java:**1868) >> at org.apache.felix.framework.**BundleImpl.start(BundleImpl.**java:944) >> at org.apache.felix.framework.**BundleImpl.start(BundleImpl.**java:931) >> at >> org.apache.felix.**bundlerepository.impl.**ResolverImpl.deploy(** >> ResolverImpl.java:630) >> >> Crap. So now I am getting different errors on different invocations too. >> Maybe it was a timing issue - on the re-run I probably ran the update >> sooner after starting. These "Uses constraint violation"s are normally >> fixed by package versioning, or so I thought, but in this case all >> versions >> of these bundles dictate package versions. So I don't know where to go >> from >> there. >> >> I'm also beginning to think using Require-Bundle may be better for my >> sanity, assuming it allows coarser grained control of versioning. >> >> Serves me right for working on a Sunday I suppose. >> >> Dan >> >> On Sat, Jun 30, 2012 at 5:46 PM, Richard S. Hall > >wrote: >> >> Updating the service doesn't completely get rid of its old exports, you >>> need to refresh it to do that. Most likely if you updated the client >>> first, >>> then it gets wired to the old export and stays that way after you update >>> the server. Regardless, if you want to make sure you don't have any old >>> "stale" versions causing you confusion, you have to do a "refresh" after >>> a >>> series of updates and uninstalls. >>> >>> -> richard >>> >>> >>> On 6/30/12 12:09, Dan Gravell wrote: >>> >>> My OSGi adventure continues... >>>> >>>> I have a bundle "Client" and bundle "Server". In Client's activator it >>>> invokes code in
Re: Help me understand ClassCastException after update
en.musicbrainz com.elsten.musicbrainz [30.1] Chain 2: com.elsten.bliss.platform [11.1] import: (&(osgi.wiring.package=com.elsten.musicbrainz.model)(version>=1.0.1)) | export: osgi.wiring.package=com.elsten.musicbrainz.model; uses:=com.elsten.musicbrainz export: osgi.wiring.package=com.elsten.musicbrainz com.elsten.musicbrainz [30.0] at org.apache.felix.framework.Felix.resolveBundleRevision(Felix.java:3832) at org.apache.felix.framework.Felix.startBundle(Felix.java:1868) at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:944) at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:931) at org.apache.felix.bundlerepository.impl.ResolverImpl.deploy(ResolverImpl.java:630) Crap. So now I am getting different errors on different invocations too. Maybe it was a timing issue - on the re-run I probably ran the update sooner after starting. These "Uses constraint violation"s are normally fixed by package versioning, or so I thought, but in this case all versions of these bundles dictate package versions. So I don't know where to go from there. I'm also beginning to think using Require-Bundle may be better for my sanity, assuming it allows coarser grained control of versioning. Serves me right for working on a Sunday I suppose. Dan On Sat, Jun 30, 2012 at 5:46 PM, Richard S. Hall wrote: > Updating the service doesn't completely get rid of its old exports, you > need to refresh it to do that. Most likely if you updated the client first, > then it gets wired to the old export and stays that way after you update > the server. Regardless, if you want to make sure you don't have any old > "stale" versions causing you confusion, you have to do a "refresh" after a > series of updates and uninstalls. > > -> richard > > > On 6/30/12 12:09, Dan Gravell wrote: > >> My OSGi adventure continues... >> >> I have a bundle "Client" and bundle "Server". In Client's activator it >> invokes code in Server, returning an object from Server, let's call it >> server.A. A is defined in Server. Client then registers A as a service: >> >> context.registerService(A.**class, (A) serverClass.getA(), new >> Hashtable()); >> >> This works when it is first run. >> >> If I then update Client and Server bundles, the Client Activator gets run >> again. This time I get a ClassCastException saying "server.A cannot be >> cast >> to server.A". >> >> So I guess the classloaders are different for the A that is returned by >> Server to the one Client sees. Given both bundles were updated at the same >> time, why is this? >> >> I make use of package versioning, if this is important. A's package, >> server, was not updated, and its version was not incremented. Was the code >> in Client using the old version of server.A? >> >> I guess registering A as a service in Client, rather than Server, is >> opposed to most sample code I see but is it the cause of the problem? If >> classloaders work on a per package level then it won't help will it? >> >> Thanks, >> Dan >> >> > --**--**- > To unsubscribe, e-mail: > users-unsubscribe@felix.**apache.org > For additional commands, e-mail: users-h...@felix.apache.org > >
Re: Help me understand ClassCastException after update
Yeah, I think it must be something like that. As posted above, I do a refresh, but after the update. The update is performed by OBR to deploy() the latest bundle, which sucks in the dependencies and performs the Activator restart which then fails with the original CCE. The bundle appears not to be a STARTED state after the Activator failure, and so when I try to do the refresh: context.getBundle(0).adapt(FrameworkWiring.class).resolveBundles(null); That fails with: java.lang.IllegalStateException: Invalid BundleContext. at org.apache.felix.framework.BundleContextImpl.checkValidity(BundleContextImpl.java:514) at org.apache.felix.framework.BundleContextImpl.getBundle(BundleContextImpl.java:173) But I might be doing this wrong. This is called from a bundle that is itself updated, so maybe that BundleContext is now stale? Or maybe it's just the fact that the newly updated bundle is not STARTED because of the CCE. Dan On Sat, Jun 30, 2012 at 5:46 PM, Richard S. Hall wrote: > Updating the service doesn't completely get rid of its old exports, you > need to refresh it to do that. Most likely if you updated the client first, > then it gets wired to the old export and stays that way after you update > the server. Regardless, if you want to make sure you don't have any old > "stale" versions causing you confusion, you have to do a "refresh" after a > series of updates and uninstalls. > > -> richard > > > On 6/30/12 12:09, Dan Gravell wrote: > >> My OSGi adventure continues... >> >> I have a bundle "Client" and bundle "Server". In Client's activator it >> invokes code in Server, returning an object from Server, let's call it >> server.A. A is defined in Server. Client then registers A as a service: >> >> context.registerService(A.**class, (A) serverClass.getA(), new >> Hashtable()); >> >> This works when it is first run. >> >> If I then update Client and Server bundles, the Client Activator gets run >> again. This time I get a ClassCastException saying "server.A cannot be >> cast >> to server.A". >> >> So I guess the classloaders are different for the A that is returned by >> Server to the one Client sees. Given both bundles were updated at the same >> time, why is this? >> >> I make use of package versioning, if this is important. A's package, >> server, was not updated, and its version was not incremented. Was the code >> in Client using the old version of server.A? >> >> I guess registering A as a service in Client, rather than Server, is >> opposed to most sample code I see but is it the cause of the problem? If >> classloaders work on a per package level then it won't help will it? >> >> Thanks, >> Dan >> >> > --**--**- > To unsubscribe, e-mail: > users-unsubscribe@felix.**apache.org > For additional commands, e-mail: users-h...@felix.apache.org > >
Re: Help me understand ClassCastException after update
I think you might be right. Could this be a package versioning problem? A is in a package that was *not* updated (although its holding bundle was), and Client's version requirement for Import-Package for A's package had not changed. When I do a full VM restart it works fine, the versions are all updated. Currently I update using OBR: resolver.deploy(Resolver.START) If it *is* a packaging problem and I need to increment the version of A's package and the version requirements on all Import-Package declarations for A's package... I'm beginning to wonder how on earth one can keep on top of this. Granted: this is a legacy app converted to OSGi, so it is not modularised perfectly. But it feels like it will be an enormous pain to keep on top of package versioning. Hopefully bndtools can help with this... To make it more confusing: A extends SuperA which is in a separate bundle again. This separate bundle was also not updated. Furthermore, another bundle again uses A, as I mentioned to Neil. Dan On Sat, Jun 30, 2012 at 5:30 PM, Christian Schneider < ch...@die-schneider.net> wrote: > The service should not be involved in the problem. I think the client is > still using the old class that was created by the classloader of the old > server bundle. As it comes from a different classloader it is of course > incompatible. > > Have you tried uninstalling client and server and then installing the new > bundles. Then it should work. How exactly do you do the update at the > moment? > > Christian > > Am 30.06.2012 18:09, schrieb Dan Gravell: > > My OSGi adventure continues... >> >> I have a bundle "Client" and bundle "Server". In Client's activator it >> invokes code in Server, returning an object from Server, let's call it >> server.A. A is defined in Server. Client then registers A as a service: >> >> context.registerService(A.**class, (A) serverClass.getA(), new >> Hashtable()); >> >> This works when it is first run. >> >> If I then update Client and Server bundles, the Client Activator gets run >> again. This time I get a ClassCastException saying "server.A cannot be >> cast >> to server.A". >> >> So I guess the classloaders are different for the A that is returned by >> Server to the one Client sees. Given both bundles were updated at the same >> time, why is this? >> >> I make use of package versioning, if this is important. A's package, >> server, was not updated, and its version was not incremented. Was the code >> in Client using the old version of server.A? >> >> I guess registering A as a service in Client, rather than Server, is >> opposed to most sample code I see but is it the cause of the problem? If >> classloaders work on a per package level then it won't help will it? >> >> Thanks, >> Dan >> >> > > -- > Christian Schneider > http://www.liquid-reality.de > > Open Source Architect > Talend Application Integration Division http://www.talend.com > > > --**--**- > To unsubscribe, e-mail: > users-unsubscribe@felix.**apache.org > For additional commands, e-mail: users-h...@felix.apache.org > >
Re: Help me understand ClassCastException after update
Thanks for answering Neil! I've been referring to your blog a lot the past few weeks and we also talked on the bndtools group the other day. The CCE occurs in the activator for Client. It's the line I pasted above: context.registerService(A.class, (A) serverClass.getA(), new Hashtable()); So it's that cast: (A) - sorry I guess having one letter class names probably obscured this. Yes, another bundle uses this service. Let's call this... Client2 (sorry). That bundle was *not* updated. That uses both a ServiceTracker and in a few places a simple getService(). I did try to refresh after the update, but got another exception: java.lang.IllegalStateException: Invalid BundleContext. at org.apache.felix.framework.BundleContextImpl.checkValidity(BundleContextImpl.java:514) at org.apache.felix.framework.BundleContextImpl.getBundle(BundleContextImpl.java:173) I am refreshing using a bundle context of one of the bundles that was updated. This might be a bad thing to do. It throws the ISE I guess because the of the previous CCE, as the bundle is in STARTING mode, not STARTED. My code to refresh is: context.getBundle(0).adapt(FrameworkWiring.class).resolveBundles(null); In other words: get the system bundle, adapt it and then resolve all. I didn't know another way of getting the FrameworkBinding instance from just the BundleContext. Dan On Sat, Jun 30, 2012 at 5:39 PM, Neil Bartlett wrote: > Where does the ClassCastException happen? You said that Client registers > the service, does any other bundle access and use the service? If so, what > kind of method did you use to obtain the service (eg ServiceTracker, DS, > etc)? > > Also did you refresh after updating the bundles? Note that bundles cannot > really be updated "at the same time", ie there is no atomic multi-bundle > update. This is why you need to refresh after a series of updates. > > Rgds > Neil > > -- > Neil Bartlett > Sent from a phone > > > On Saturday, 30 June 2012 at 17:09, Dan Gravell wrote: > > > My OSGi adventure continues... > > > > I have a bundle "Client" and bundle "Server". In Client's activator it > > invokes code in Server, returning an object from Server, let's call it > > server.A. A is defined in Server. Client then registers A as a service: > > > > context.registerService(A.class, (A) serverClass.getA(), new > Hashtable()); > > > > This works when it is first run. > > > > If I then update Client and Server bundles, the Client Activator gets run > > again. This time I get a ClassCastException saying "server.A cannot be > cast > > to server.A". > > > > So I guess the classloaders are different for the A that is returned by > > Server to the one Client sees. Given both bundles were updated at the > same > > time, why is this? > > > > I make use of package versioning, if this is important. A's package, > > server, was not updated, and its version was not incremented. Was the > code > > in Client using the old version of server.A? > > > > I guess registering A as a service in Client, rather than Server, is > > opposed to most sample code I see but is it the cause of the problem? If > > classloaders work on a per package level then it won't help will it? > > > > Thanks, > > Dan > > > > > > >
Help me understand ClassCastException after update
My OSGi adventure continues... I have a bundle "Client" and bundle "Server". In Client's activator it invokes code in Server, returning an object from Server, let's call it server.A. A is defined in Server. Client then registers A as a service: context.registerService(A.class, (A) serverClass.getA(), new Hashtable()); This works when it is first run. If I then update Client and Server bundles, the Client Activator gets run again. This time I get a ClassCastException saying "server.A cannot be cast to server.A". So I guess the classloaders are different for the A that is returned by Server to the one Client sees. Given both bundles were updated at the same time, why is this? I make use of package versioning, if this is important. A's package, server, was not updated, and its version was not incremented. Was the code in Client using the old version of server.A? I guess registering A as a service in Client, rather than Server, is opposed to most sample code I see but is it the cause of the problem? If classloaders work on a per package level then it won't help will it? Thanks, Dan
Re: Guidance on using auto deploy, OBR or something else for initial provisioning and updates
Thanks all. I added it to JIRA anyway so that a decision can be made through that 'official', formalised channel. https://issues.apache.org/jira/browse/FELIX-3566 Dan On Wed, Jun 20, 2012 at 5:30 PM, Marcel Offermans < marcel.offerm...@luminis.nl> wrote: > On Jun 20, 2012, at 18:23 , Richard S. Hall wrote: > > On 6/20/12 12:15 , Dan Gravell wrote: > >> On Wed, Jun 20, 2012 at 4:06 PM, Richard S. Hall >wrote: > >> > >>> (make sure you refresh too) > >>> > >> The Resolver doesn't refresh after deploy? Well I suppose that's a > >> different conceptual level of behaviour so ok, thanks. > > > > Looking at the code quickly, it looks like it doesn't...it probably > should if it updates a bundle...perhaps you can open an RFE issue in JIRA > for this… > > Question remains if it should refresh automatically. Suppose you want to > do multiple deploys sequentially and when all are done, do a refresh. So an > option to refresh would be nice, but I would make that explicit. > > Greetings, Marcel > > > - > To unsubscribe, e-mail: users-unsubscr...@felix.apache.org > For additional commands, e-mail: users-h...@felix.apache.org > >
Re: Guidance on using auto deploy, OBR or something else for initial provisioning and updates
On Wed, Jun 20, 2012 at 4:06 PM, Richard S. Hall wrote: > (make sure you refresh too) > The Resolver doesn't refresh after deploy? Well I suppose that's a different conceptual level of behaviour so ok, thanks. So, you have to just look for the "version" prefix and largely ignore the > X.Y... > Ok, already done this. The code for this workaround - https://bugs.eclipse.org/bugs/show_bug.cgi?id=372656 - largely works. However, there's no coping with versions. From what I can see the version directory is not numbered after the bundle version, it's numbered after the revision that has been applied in this Felix instance. So how do I know which version to use? Can I just use the latest? Dan
Progress of download/update using OBR
Anyone using OBR... have you found a way to communicate to the user the download progress and update for a group of bundles? There's nothing in the API I can see that supports this... although there is a 'size' attribute on Resource. Just wondered how others might have achieved this... Dan
Re: Guidance on using auto deploy, OBR or something else for initial provisioning and updates
On Wed, Jun 20, 2012 at 3:33 PM, Richard S. Hall wrote: > On 6/20/12 10:20 , Dan Gravell wrote: > >> That's ok - I know we are using Felix. And this worked before I used OBR, >> because bundle.getLocation would return a file URL. However the OBR URL >> returned by getLocation is totally abstracted. How might I find the >> location in the bundle cache? >> > > Just to be clear, we are talking about two different locations: > > 1. The bundle.getLocation() method was returning the original location > from which the framework made a copy of the bundle to install into > its bundle cache. > 2. The bundle in the bundle cache is the copy made from the original > location above. > > So, in your old solution you were getting it from the source. Now you will > be getting it from the copy. Hmmm, interesting. So it sounds like updating that bundle (from a different source) wouldn't work because it would just point back to the original location. I thought I'd observed it work, but maybe my test wasn't satisfactory... > Well, you can configure the location of the bundle cache using the > org.osgi.framework.storage property, so you can look up this property. > After that, then yes you'll need to know the structure of the cache to find > the bundle you want. You shouldn't need to read any of the files, though, > you just need to know the structure so you can find what you want. > Of course! I forgot about the property. I thought I would need to read bundle.info though so I can find out which bundle ("bundle0" - "bundleNN") is the one I want to return the location for. > You could hide all of this behind some method, but it is still ugly... > Agreed! Dan
Re: Guidance on using auto deploy, OBR or something else for initial provisioning and updates
On Wed, Jun 20, 2012 at 3:10 PM, Richard S. Hall wrote: > The bundle, as provided by OBR, has a location of "obr://[bundle >> name]/[some string]". Jetty doesn't know how to interpret that. Is there >> any way of finding the filesystem location from the OBR provided bundle? >> > No, there is no way of determining it other than knowing the bundle cache > format of the framework and calculating it yourself. That's ok - I know we are using Felix. And this worked before I used OBR, because bundle.getLocation would return a file URL. However the OBR URL returned by getLocation is totally abstracted. How might I find the location in the bundle cache? Other than explicitly finding it on the filesystem - new File("felix-cache") and going through the bundle.infos... or is that what you meant? If so, this might be a show-stopper unless I can think of some other way. Dan
Re: Guidance on using auto deploy, OBR or something else for initial provisioning and updates
Thanks Richard. I've started work on this. I just want to document one problem with a workaround (should anyone run into the same problem), and then my latest problem. First problem I encountered almost immediately was with a fragment I have re-exporting extra sun.* internal packages from the system bundle. The issue is registered here https://issues.apache.org/jira/browse/FELIX-2465 but I didn't see my workaround. bindex generated:
Re: Guidance on using auto deploy, OBR or something else for initial provisioning and updates
Thanks Richard, You can, although you can also use OBR to deploy from a local repository > too. Regarding location, it isn't too important. For example, OBR just > generates one based on the symbolic name and a timestamp. The main issue is > that the location is used as a key to uniquely identify a bundle, so if you > use a different location for the same bundle, the framework will treat it > different than if you use the same location. > Sounds like OBR is generally the way to go. I'll take a more in depth look. Other than https://cwiki.apache.org/confluence/display/FELIX/Apache+Felix+OSGi+Bundle+Repository#ApacheFelixOSGiBundleRepository-OBRRepositoryFile are there any other resources or examples you happen to know of? > Yeah, you don't need to do that. You can package the initial bundles with > the install package. Of course, once you update the installed bundles, you > may want another mechanism to save the updates overtop of the bundles in > the install package (i.e., outside the framework) so if the user ever > restarts from scratch (i.e., deletes their framework cache) they will start > with the latest bundles. Of course, this is not completely necessary, since > you could just deploy the old bundles and update them again, but it's > something to think about. Yeah, already thought about that, I wasn't going to overwrite the initially-installed bundles for now. There are security implications for Windows Vista+ platforms (write access to Program Files/**) technical issues with the Mac (updating a DMG image possibly beyond its size) and finally in many ways it may be a nice feature being able to roll back to the original version just by removing felix-cache. > You don't need to write your own AutoProcessor, just your own launcher > that massages the auto-deploy directory bundles to be what you want, then > the existing AutoProcessor would install, update, and delete as appropriate. I guess I don't understand this... Considering possibly already installed bundles in felix-cache I still have the problem with the version numbers differentiating the bundles and so more than one version of the bundle may be started. i.e... after first install and before first run: bundle/ my_web_app-1.0.1.jar jetty-xyz.jar Run it: bundle/ my_web_app-1.0.1.jar jetty-xyz.jar felix-cache/ my_web_app-1.0.1.jar jetty-xyz.jar Update it: bundle/ my_web_app-1.0.1.jar jetty-xyz.jar felix-cache/ my_web_app-1.0.2.jar jetty-xyz.jar Re-install later version: bundle/ my_web_app-1.0.3.jar jetty-xyz.jar felix-cache/ my_web_app-1.0.2.jar jetty-xyz.jar Because my_web_app-1.0.3.jar has a different URL to my_web_app-1.0.2.jar (whose location is my_web_app-1.0.1.jar) it will be started. Dan
Re: Guidance on using auto deploy, OBR or something else for initial provisioning and updates
Thanks so much for answering Richard... replies inline: On Tue, Jun 19, 2012 at 3:01 PM, Richard S. Hall wrote: > It does that because that's all it has. To get the symbolic name, it would > have to crack open the JAR file and parse its manifest to get its symbolic > name. > Ok, it just seemed pretty easy to do this with JarFile and so on (I already do it for the update code). But never mind, it is what it is. You overestimate the level of sophistication of auto-deploy. It was only > intended to get you going, mostly for development purposes. It is in no way > an attempt to implement a management agent. You need to do that yourself or > use something else like OBR (which is also fairly simple and may or may not > work exactly like you need). > Well I'd like to use OBR in general because I think I can also replace my custom updating code with it. With OBR, is it possible to start with a set of already-downloaded bundles (i.e. those supplied by the installer), and then use an online repository to update? Or, really, should all installation/updating be online? I suppose I'm a bit confused about the significance of bundle location. The issue with online 'initial provisioning' (quoted to avoid association with the OSGi concept) is that there's further downloading to do, even after the user thinks they've installed the software. This would need to be communicated, and it might also dissuade use. However, you might be able to get close using auto-deploy if you made a > custom launcher that created/recreated the auto-deploy directory each time > you started the framework and then set the auto-deploy actions to > "install,update,delete" which would install any new bundles, update and > existing bundles, and uninstall any missing bundles. > Yeah, I considered writing my own AutoProcessor but wanted to stick with launching felix.jar if possible for now. My build, exes and so on depend on it. Another approach I considered was a 'bootstrap' bundle which did what AutoProcessor/OBR does, and then maybe uninstalled itself once the first-run was complete? Dan
Guidance on using auto deploy, OBR or something else for initial provisioning and updates
Hi. I've converted an application to run on OSGi and it works nicely inside Felix. I've got to the point where I need to consider the user's experience with installation and first-use of my product. The product itself is a consumer oriented piece of software which is installable on the user's computer. Therefore, the 'profile' here is an application installed many times. Because this is a consumer piece of software, installation -> start needs to be one step. For Windows and Linux users there is an installer, built using IzPack. Currently, the installer installs all the bundles into a bundle/ directory and Felix does its auto deploy thing over that directory, auto deploying each bundle. This works, but only the very first time the application is installed. If the user happens to install a later version over the top, you get multiple JARs for the same bundle, because the version number is in the JAR file. This doesn't work with the auto deployer which appears to use the bundle location as the identifying characteristic of a bundle, rather than its symbolic name. I'm not why it does that, but anyway it means I get all sorts of problems with multiple instances of Jetty running. I notice the felix-cache has different bundleN entries for the same bundle. Later on, in-app update provisions updated versions of the bundle from a source online. This is just my code downloading bundles and installing them. Therefore, different versions of the bundle will end up in felix-cache. Later re-installations of the product may mean even more versions lying about. This scares me! This seems a fairly flawed approach so I'm beginning to wonder whether I understand the implications of Felix auto deploy and updating in the way I am suggesting. I'm wondering if I'm approaching this in completely the wrong way. I can see other solutions for provisioning (in the sense of finding, downloading, resolving and installing bundles) such as OBR. Would it be better to use that? Has anyone else got any advice or done something similar? Thanks, Dan
Classloading differences between Felix and Eclipse OSGI framework - running embedded Jetty
I'll start by saying I'm trying to port my application to OSGI to benefit from in-app update and the potential for auto update. Other benefits from using OSGI are purely theoretical at this point: they look like nice-to-haves but I'm concentrating on one thing at a time. I need to explain that because no doubt what I've done so far is not the OSGI 'way'. My app traditionally worked using JAR manifests to setup the classpath and declare the main class. The app embeds Jetty and points it to a web app which is used to control the application. My first attempt at OSGI-ing this (with a nod to the purpose outlined in my opening paragraph) has been to build a monolithic bundle, where the Activator calls the traditional Main method, which in turn sets up Jetty. Jetty is imported in the normal Jetty JARs, NOT as an OSGI bundle. I deployed it in Eclipse's OSGI framework runner (with an empty target platform, other than the osgi bundle). It worked - I was able to run the app and even update it by pointing it to a newer version of the bundle. Then I tried deploying it in Felix, but the Jetty integration doesn't work. When I start the Jetty server I get some classloading issue loading HttpServlet. servlet-api-2.5.jar is declared in the Bundle-Classpath and is present. I tried adding javax.servlet.http to the Import-Package but that appears to make no difference. I attached the manifest. How can I get Jetty up and running? Here's the full gory exception: MultiException[java.lang.NoClassDefFoundError: javax/servlet/http/HttpServlet, java.lang.IllegalStateException: !Selecting] at org.eclipse.jetty.server.Server.doStart(Server.java:254) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59) at com.elsten.bliss.main.Main.startJetty(Main.java:591) at com.elsten.bliss.main.Main.(Main.java:263) at com.elsten.bliss.main.Main.(Main.java:211) at com.elsten.bliss.main.Main.startup(Main.java:199) at com.elsten.osgi.Activator.start(Activator.java:27) at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:641) at org.apache.felix.framework.Felix.activateBundle(Felix.java:1977) at org.apache.felix.framework.Felix.startBundle(Felix.java:1895) at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:944) at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:931) at com.elsten.bliss.runtime.osgi.Main.installAndStartBundles(Main.java:76) at com.elsten.bliss.runtime.osgi.Main.main(Main.java:32) java.lang.NoClassDefFoundError: javax/servlet/http/HttpServlet at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:634) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) at java.net.URLClassLoader.defineClass(URLClassLoader.java:277) at java.net.URLClassLoader.access$000(URLClassLoader.java:73) at java.net.URLClassLoader$1.run(URLClassLoader.java:212) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:205) at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:415) at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:377) at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:634) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) at java.net.URLClassLoader.defineClass(URLClassLoader.java:277) at java.net.URLClassLoader.access$000(URLClassLoader.java:73) at java.net.URLClassLoader$1.run(URLClassLoader.java:212) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:205) at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:415) at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:377) at org.eclipse.jetty.util.Loader.loadClass(Loader.java:92) at org.eclipse.jetty.util.Loader.loadClass(Loader.java:71) at org.eclipse.jetty.servlet.Holder.doStart(Holder.java:84) at org.eclipse.jetty.servlet.ServletHolder.doStart(ServletHolder.java:262) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59) at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:770) at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:249) at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1214) at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:676) at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:455) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59) at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:224) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59) at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:90) at org.eclipse.jetty.se