Issue Details (XML | Word | Printable)

Key: OSGI-616
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Costin Leau
Reporter: Olof Jönsson
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
Spring OSGi

Concurrency issue when waiting for dependencies

Created: 03/Sep/08 10:56 AM   Updated: 06/Sep/08 01:06 PM
Component/s: EXTENDER
Affects Version/s: 1.1, 1.1.1
Fix Version/s: 1.2 M1, 1.1.2

Time Tracking:
Original Estimate: 0.12d
Original Estimate - 0.12d
Remaining Estimate: 0.12d
Remaining Estimate - 0.12d
Time Spent: Not Specified
Remaining Estimate - 0.12d

File Attachments: 1. Text File OSGI-616 (2).patch (2 kB)
2. Text File OSGI-616.patch (2 kB)

Environment: MacOS X


 Description  « Hide
An application context can start and be active just to be closed with a timeout message such as this:
307243 [Timer-0] WARN org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor - Timeout occured before finding service dependencies for [OsgiBundleXmlApplicationContext(bundle=http_api_osgi, config=osgibundle:/META-INF/spring/*.xml)]
307249 [Timer-0] INFO org.springframework.osgi.context.support.OsgiBundleXmlApplicationContext - Application Context service already unpublished
307250 [Timer-0] INFO org.springframework.osgi.context.support.OsgiBundleXmlApplicationContext - Closing org.springframework.osgi.context.support.OsgiBundleXmlApplicationContext@be5978: display name [OsgiBundleXmlApplicationContext(bundle=http_api_osgi, config=osgibundle:/META-INF/spring/*.xml)]; startup date [Wed Sep 03 17:47:52 CEST 2008]; root of context hierarchy
307250 [Timer-0] INFO org.springframework.beans.factory.support.DefaultListableBeanFactory - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@4f9c6d: defining beans [httpServerProviderProxy,com.sun.net.httpserver.spi.HttpServerProvider$ProxyRegistration#0]; root of factory hierarchy
339730 [Timer-0] ERROR org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor - Unable to create application context for [http_api_osgi], unsatisfied dependencies: none
org.springframework.context.ApplicationContextException: Application context initializition for 'http_api_osgi' has timed out

This is due to a concurrency issue when the service is available just after the dependency is checked but before the actual wait is started.

I'll supply a patch to fix this

 All   Comments   Work Log   Change History   FishEye   Builds      Sort Order: Ascending order - Click to sort in descending order
Olof Jönsson added a comment - 03/Sep/08 11:04 AM
A patch that synchronizes / serializes the registering of the dependency listener and the completion of the tasks

Olof Jönsson added a comment - 04/Sep/08 04:04 AM
The previous update didn't take into account that reference might be resolved when registering the dependency listener in the same thread (i. e. with the same monitor). This is exactly what happens in OsgiListenerUtils.addServiceListener().

This new patch handles this by checking (again) if the dependencies are resolved after the registration and within the synchronized block.

Costin Leau added a comment - 04/Sep/08 11:20 AM
Hi Olof. I had to look at the patch since from the issue description, I wasn't sure what the bug was all about. I think the case that might have affected you was that the watchdog task might have started after it was stopped. I've addressed this.
Note that checking for a status (pooling) isn't really an option since the status can change between two statements. The approach taken in Spring-DM is to use a simple counter (barrier) that indicates if the dependencies have been satisfied no matter the order.

The fix has been committed and is available in the TRUNK. It would be swell if you could give this a try today at some point (or by tomorrow morning) before 1.2.x is released.
I'll trigger a nightly build later on to have the snapshot ready just in case - ofc, you can build the sources yourself.
Thanks,

Costin Leau added a comment - 04/Sep/08 02:28 PM
Olof, I've triggered the nightly build - it should be available in 30 minutes or so. See this link (http://build.springframework.org/browse/OSGI-NIGHTLY/latest) for more info (or the issue build tab for more info).
Cheers,

Olof Jönsson added a comment - 04/Sep/08 02:58 PM
Hello Costin,

Sorry for being overly terse, and you were right on the mark on what the problem was. I'll download the nightly build as soon as it is ready, I'm at a bad internet connection right now (3G that disconnects intermittently) and I'm having some serious problems getting the source from SVN.

I've done an ocular review through the changes and they seem to handle this issue correctly. However, the refresh()-method doesn't seem to handle multiple invocations anymore since the watchdogTask is only created once (in the constructor). That's not a problem for me though.

Anyway, as soon as tested the nightly build for this issue I'll update here with my results.
Thanks for the great work, and especially for getting 1.2 ready so quickly!


Costin Leau added a comment - 04/Sep/08 03:56 PM
Olof, the nightly build was completed - if you'll update now the snapshot should contain the change. You are right about multiple invocations not being supported but this was never the plan. Since the context is handled by the extender, double creation never occurs (it's always create -> refresh -> close).

P.S. Tomorrow 1.2.0 M1 is scheduled for release - there is still some work to be done before 1.2.0 final :)

Olof Jönsson added a comment - 04/Sep/08 04:19 PM
I haven't been able to reproduce this issue with the latest nightly snapshot so I'd way we're good to go!

Regarding the multiple invocations, I thought mainly of the fact that the application context is published as an OSGi service under the ConfigurableApplicationContext interface which would make it possible that client code could invoke refresh() on it multiple times.

Looking forward to the release tomorrow (even if it's not final :) ), good night!

Costin Leau added a comment - 05/Sep/08 01:20 AM
Thanks for the report Olof. refresh() contract doesn't imply multiple invocations - each implementation can throw an IllegalStateException if this is not the case.
The Delegated ApplicationContext uses that since it's considerably easier and nicer to just create another object rather then refresh the existing context due to the number of locks, synchronization and management issues that arrise from supporting multiple refresh.
Additionally, with a delegated context, the execution and creation is driven by the extender and not by the user.
Nevertheless, if there is a case where multiple refresh make sense, let me know and we'll see what we can do about it.
Cheers,