Hi Greg,

Yes, I think the main use case for OSGi bundles for UIMA is as you describe -
just a bundle for the component itself, not including the UIMA framework.

The only reason for including the UIMA framework, IIRC, is to get around the
issue that UIMA is not OSGi aware, and will try to load things using its
classloader strategies, which don't know about OSGi classloaders.

I think it's worthwile to examine the previous attempt at doing something here,
which you gave a pointer to, below.  It takes advantage of standard UIMA
facilities (ResourceManager) to specify that the UIMA Framework use an OSGi
classloader to load classes. 

Here are what I think are the major concepts of that OSGi design:

1) Each primitive and aggregate became a bundle, with some special activator
code (boiler plate - added to every bundle).  The activator code was used when
the bundle was installed to update the OSGi registry.

2) aggregates were wired to (by depending on / importing) their delegates.

With each aggregate/primitive, one or more XML descriptors were included
(similar to how PEAR files include a descriptor) in the bundle.  An assembler
wanting to have a different descriptor (perhaps changing some configuration
parameter, for example) would need to edit / rebuild the bundle.

With each aggregate/primitive, boiler plate code to export new "services" needs
to be added.  One new service, in particular, returns the classloader that OSGi
is using for the component.  Remember that this classloader is set up by OSGi to
include access to the components classes/resources + access to all
imported/depended-on other packages from other bundles.

This classpath is then passed to resourceManager.setExtensionClassPath method -
as the "parent" classloader to use for an "empty" classloader - a slight misuse
of the intended use of this method, but one which makes the OSGi classloader the
one to use. 

3) TypeSystem JCas-gen'd classes and shared resources were put into individual
bundles; the aggregate and primitive components that depended on them would need
to depend on/ import these bundles / packages.

4) Scaffolding to get things set up.  This seems to involve:

a) making bundles specific to *primitives* that include parameters and
dependencies (for wiring) to JCas type system classes and resources

b) making bundles specific to the *aggregates*, including dependencies (for
wiring) as above + all delegates

Note: a) and b) have to include boilerplate for a new return-my-classloader 
service.

c) making a bundle representing the "application".

d) making bundles specific to all JCas type collections and other resources
(these are depended on by a & b & c)

e) The "application" has to be able to load the top aggregate, using its XML
descriptor.  There are 2 ways this could be done. 
e1) The application could depend on (be OSGi-wired to) the aggregate bundle.
e2) The application could take a string "name" of the aggregate to run, and then
"look it up" in the OSGi registry. This would require that some other process
"install" the aggregate into OSGi and Register it.

Once the application has some kind of "handle" to the top level aggregate, it
would use the boilerplate "return-my-classloader" service to return the
classloader for the top level aggregate (which includes all dependencies), and
then use this in UIMA's setExtensionClassLoader method.

=====================

This kind of OSGi design has the UIMA Framework kept in a separate bundle, and
not packaged with the individual annotators, and seems more closely aligned with
the modularity intents of OSGi.

The main drawback to this kind of design, I think, is the perceived complexity
of properly preparing all the parts, with the right boiler plate code, etc. 
Perhaps some new tooling would address this?

-Marshall






On 8/21/2011 8:57 PM, Greg Holmberg wrote:
> Hi Marshall--
>
>
> | Re: 1b) alternative.
> |
> | After some more thought, I don't think 1b) will quite do what I thought it
> | would.  Consider a bundle C wanting to use bundle A containing the UIMA
> | framework (exported from A) and the annotator in bundle A.  Bundle C would 
> get
> | "wired" to the UIMA framework classes to produce Analysis Engines in bundle 
> A,
> | and call these classes, which would successfully instantiate / run 
> annotator A.
> |
> | So far so good.
> |
> | Now consider bundle B - another annotator, plus the Exported UIMA
> framework.  If
> | Bundle C wants to also be wired to bundle B, because it wants to also run
> | annotator B, the OSGi framework would have to pick just one of bundle A or
> | bundle B to provide the classes for the UIMA framework.  If it picked 
> bundle A,
> | then it would call produceAnalysisEngine using classes from bundle A, which
> | would not be able to see the classes for bundle B.
> |
> | So this would not work, I think.
>
>
> Hmm.  I had never imagined UIMA OSGI bundles as stand-alone deployables (i.e.
> without any additional UIMA libraries).  I'd always imagined them as a
> packaging for annotators and analysis engines that can be plugged into a UIMA
> container (like CPM, for example).  In the same way that Eclipse extensions
> plug into Eclipse.  They would only contain their own implementation classes. 
> In other words, a replacement for PEAR files.
>
> I suppose that deploying the UIMA container itself as an OSGi bundle would be
> nice too, but not as important as the annotators and analysis engines.  Those
> represent the level of re-usability and modularity that I really want.
>
> From this page [1], it seems like IBMers Yurdaer Doganata and Mirko Jahn
> solved this problem back in 2007.
>
> As fellow employees, is anyone here in touch with them?  Can we get them to
> donate their code to Apache?  Better than re-inventing the wheel, right?
>
>
> Greg
>
> [1] https://cwiki.apache.org/UIMA/uima-osgi-enablement.html
>

Reply via email to