There are some places in UIMA that check for the existence of the thread local
context class loader, and make use of it if not null.

Frequently, these places assume that if this is set, that's the *only* class
loader to use for the particular task, as opposed to a philosophy which would
try other class loaders if a resource/class is not found.  This idea was based
on a mistaken belief that normally, the thread local context class loader is not
set, that is, it is not set by default when a JVM starts up. 

I recently observed that both Java 8 and Java 11 do set the thread local context
class loader to point to the "application" loader - the loader that loads the
initial Java application.

This led to changing UIMA-5802/5902 to handle failures to find a class in the
thread local context loader, to then try the loader associated with loading UIMA
core classes.

One consequence of this is a change in how applications launched with the
UimaBootstrap class need to work, if they make use of the thread local context
loader.  The UimaBootstrap class has been used to launch various uima
applications.  In UIMA-AS, it is used, for example, to launch runRemoteAsyncAE. 

This class's purpose is to set up the Java class path for running the
application.  Before https://issues.apache.org/jira/browse/UIMA-5754, it did
this by adding specified Jars from folders of Jars, to the classpath that the
Java application class loader was using.

But this broke with Java 9 and later.  So this was changed in UIMA-5754, and it
no longer augments the classpath of the application classloader (which can no
longer be done).  What it does instead is to merely create a new URLClassLoader,
and set it up with the classpath, and then use that to load the initial class of
the application.  This causes all subsequent class loading that occur due to
references to be loaded using this same class loader.

But if the loaded code itself does class loading, specifying a class loader, the
following is now true, if running from the UimaBootstrap class

1) The classloader of the running application will have the application's loaded
classes as set up by UimaBootstrap

2) The ThreadLocal context classloader will have the original application class
loader, which will *not* have the classpaths set up by UimaBootstrap.

Applications making use of the ThreadLocal may need to change to accommodate
this.  One such accommodation might be to have a class / resource loading
strategy that tries the ThreadLocal context classloader, and if it fails to find
the class/resource, to fall back on the classloader of the loading code.  This
change was done in UIMA-5802 and UIMA-5902. 

UIMA-AS's Dd2spring class needs this change, because it is using the thread
local context class loader assuming that it has all of the uima classes on it
from the BootstrapClassloader. I created UIMA-5907, and will work on fixing it.

-Marshall


Reply via email to