[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[equinox-dev] Re: EclipseAppLauncher v. Declarative Services -- race condition?

Thomas Watson <tjwatson@xxxxxxxxxx> writes:

> Sorry for the late response.  This mail got buried in the midst of
> EclipseCon week.  Just catching up.

No problem. I appreciate the input, no matter when.

[...]

> When the org.eclispe.equinox.app bundle is activated

Well, keep in mind that I'm only using Equinox as it's packaged in the
org.eclipse.osgi bundle/JAR, which does not include anything in the
org.eclipse.equinox.app package. Which bundles would I need to take
advantage of the org.eclispe.equinox.app package?

> it discovers the installed applications and registers an
> org.osgi.service.application.ApplicationDescriptor service for each
> application.

I don't see this package in the Compendium documentation, so I guess
it must be a later addition? Looking around now I found the Javadoc
and source in the Equinox CVS repository. This is some new material to
study.

> The ApplicationLauncher service should not be used by clients, it is
> meant to be used the eclipse application container.  Up to this
> point the ApplicationLauncher service has been considered internal
> API between the launcher which is in control of the main thread and
> the Eclipse application container.

My goal was to stop EclipseAppLauncher.start() from throwing an
exception when called upon by EclipseStarter.run(), and in
investigating that I saw that there was an interaction between Equinox
registering an ApplicationLauncher and optionally it looking for a
registered ParamaterizedRunnable to use as the "default
application". Using either approach works, but apparently I'm digging
into depths I shouldn't be.

> I'm not sure why you are needing to call this method to solve a
> timing issue.  Do you need your application to be launched later
> after some other operation has occurred?

As EclipseAppLauncher and EclipseStarter are written, after the
framework has started and loaded its initial bundles, one of two
things must have occurred in order for an "application" (given my
limited view) to be started: Either a ParamaterizedRunnable must have
been registered by a bundle, or one of the bundles must have found a
registered ApplicationLauncher and called its launch() method.

If some of these initial bundles are assisted by Declarative Services
(or iPOJO, or Spring OSGi), their "boot up" may happen asynchronously
to the bundles having started, so that by the time they register a
ParamaterizedRunnable or find a registered ApplicationLauncher (on a
separate thread), EclipseAppLauncher.start() has already been called
by EclipseStarter.run().

The only way out of this race condition is to set the
eclipse.application.launchDefault property to false¹, which will force
EclipseAppLauncher.start() to wait until ApplicationLauncher.launch()
gets called on eventually, providing EclipseAppLauncher the
ParamaterizedRunnable it needs to run as "the application".


Speaking more broadly, I came to Equinox testing whether I could use
it as an alternative to Felix, embedded in my larger application. I'm
not looking to create an "Eclipse application", so I've been trying to
bite off the smallest possible parts of Equinox while still using it
as intended. Would you still advocate me pursuing the
org.eclipse.core.runtime.applications extension point idea you
sketched?


Footnotes: 
¹ It is treated as true by default on line 347 in EclipseStarter.java.

-- 
Steven E. Harris