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 <[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]
>
>

Reply via email to