Hi Kirk,

On 4/2/07, Kirk True <[EMAIL PROTECTED]> wrote:
Hi all,

I have some general questions about how to create an
application that can run arbitrary annotators,
including how to set up the ClassLoader, the proper
timing for setting the thread context ClassLoader, and
so forth.

1. In an application in which an arbitrary aggregate
annotator is executed, isn't it possible that the
annotators may include versions of a given library
that conflict either with each other and/or the host
application?


The ResourceManager.setExtensionClassPath method is supposed to
provide a solution for when an annotator's libraries conflict with the
host application.  More on that below.

Unfortunately we don't currently have a solution for the case where
two annotators in an aggregate need conflicting versions of a library.
You can only set one extension ClassLoader for the whole aggregate.

2. Are there any examples of how to create
applications that *don't* have a priori knowledge of
the annotators it will be running?


Well, there's the PEAR Installer.. it uses the ClassLoader information
in the PEAR file to set up the extension ClassLoader.  But trying to
look at its source code may be overkill.

3. Is it possible to have an annotator-specific
ClassLoader, or is there just one ClassLoader for all
annotators in a given aggregate analysis engine?


Just one for all annotators, sorry.

4. Should I or should I not be using
Thread.setContextClassLoader to the ClassLoader
returned by ResourceManager? If so, when should I set
it? Before creating the AnalysisEngine or afterward?


You should call ResourceManager.setExtensionClassPath, before creating
the AnalysisEngine.  Then pass the ResourceManager into the
produceAnalysisEngine method.  This will cause your annotator class to
be loaded under the extension class loader you specify (but the UIMA
framework won't use this, say, for Xerces).  But it sounds like you
are already doing this.

I'm not that familiar with the thread context ClassLoader concept.
UIMA doesn't use the context ClassLoader AFAIK.

Some details...

In my application I allow for running an arbitrary
aggregate annotator, where in the descriptor is passed
in at runtime. I'm creating the appropriate aggregate
class path by concatenating the individual UIMA
annotator's class paths as detailed in
metadata/install.xml. I then call ResourceManager's
setExtensionClasspath method with that string and then
set the thread's ClassLoader (via Thread's
setContextClassLoader) to that returned by the
ResourceManager's getExtensionClassLoader. I create
the AnalysisEngine object via UIMAFramework's
produceAnalysisEngine method, passing in my
ResourceManager to ensure that my annotators use the
extension class path.

However, there's a timing issue. produceAnalysisEngine
parses all the relevant descriptors and then calls the
initialize method on each of the annotators.

That is not quite accurate.  Descriptors are parsed by
UIMAFramework.getXMLParser().parseXXX methods.  The initialize method
isn't called until you call UIMAFramework.produceAnalysisEngine().
Maybe this gives you a window in which to set your ClassLoader?  But I
don't completely understand the nature of this issue so I'm not sure.
Or maybe there are a few stray calls into Xerces that are done in
produceAnalysisEngine that I forgot about.

Because a
given annotator's initialize method may perform logic
that uses a given library, I had been setting the
Thread's context ClassLoader before calling
produceAnalysisEngine. However, when
produceAnalysisEngine is then run, it references a
ClassLoader that may offer a newer version of a
certain library which causes problems. Specifically,
one annotator requires (and includes) and newer
version of  Xerces which causes a
java.lang.LinkageError to be thrown by
produceAnalysisEngine. However, if I don't set the
context ClassLoader before calling
produceAnalysisEngine, the annotator's initialize
method fails with a different error because it's
expecting the newer version. So I'm kind of stuck
between a rock and a hard place, so to speak.


Who is using the thread context ClassLoader?  Do your annotators
specifically use it?  Or is it Xerces that does?  Since I'm not aware
of UIMA using the context ClassLoader, I'm somewhat surprised that it
could cause a failure inside the UIMA framework.

Regards,
 -Adam

Reply via email to