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]

Reply via email to