On Aug 15, 2012, at 09:58 , Dan Gravell <[email protected]> wrote:
> 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. In core JRE classes, it may not be a leak per se. It could just be a shared resource that gets lazily created on first use and then hangs around until the process exits. If it creates a new thread that never goes away every time you create a timer, then you have an issue…but one for everyone isn't an issue. -> richard > > Thanks, > Dan > > On Wed, Aug 15, 2012 at 2:54 PM, Richard S. Hall <[email protected]>wrote: > >> On Aug 15, 2012, at 05:02 , Dan Gravell <[email protected]> >> 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 <[email protected] >>> 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 <[email protected]> >> wrote: >>>> >>>>> On Aug 9, 2012, at 10:44 , Dan Gravell <[email protected]> >>>> 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 <[email protected] >>>>> 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 < >> [email protected]> >>>>>>> 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<Bundle> >>>>>>> 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 < >>>> [email protected] >>>>>>>> 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.<init>(IIORegistry.java:138) >>>>>>>>>> at >>>>>>>>>> >>>> javax.imageio.spi.IIORegistry.getDefaultInstance(IIORegistry.java:159) >>>>>>>>>> at javax.imageio.ImageIO.<clinit>(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.<init>(IIORegistry.java:138) >>>>>>>>>> at >>>>>>>>>> >>>> javax.imageio.spi.IIORegistry.getDefaultInstance(IIORegistry.java:159) >>>>>>>>>> at javax.imageio.ImageIO.<clinit>(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 >>>>>>>>> >>>>>>>>> >>>>>>>>> >> --------------------------------------------------------------------- >>>>>>>>> To unsubscribe, e-mail: [email protected] >>>>>>>>> For additional commands, e-mail: [email protected] >>>>>>>>> >>>>>>>>> >>>>>>> >>>>>>> >>>>>>> --------------------------------------------------------------------- >>>>>>> To unsubscribe, e-mail: [email protected] >>>>>>> For additional commands, e-mail: [email protected] >>>>>>> >>>>>>> >>>>> >>>> >>>> >>>> --------------------------------------------------------------------- >>>> To unsubscribe, e-mail: [email protected] >>>> For additional commands, e-mail: [email protected] >>>> >>>> >> >> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: [email protected] >> For additional commands, e-mail: [email protected] >> >> --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]

