[ 
https://issues.apache.org/jira/browse/UIMA-5554?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16162932#comment-16162932
 ] 

Marshall Schor commented on UIMA-5554:
--------------------------------------

Thanks for the response; I think this dialog is helping to clarify some details 
(even in my mind) :-)

First, re: the mental picture, in both v2 and v3, type systems (including 
committed ones) *can* be shared among CASes - there's a concept of CAS Pools 
that supports this; it's useful when running multiple copies of the same 
pipeline.

Ignoring that for the moment, and assuming 1 class loader, it is true that you 
can have multiple pipelines, each with their own particular type system 
definition, installed into different CASes.
If you're not using JCas, then there is a "sharing" of the *built-in JCas 
classes*, like TOP and Annotation and FSArray, etc.  These are arranged to be 
constant and sharable among the various CAS's type systems.

Now, if you have some JCas classes, because of the above assumption of 1 class 
loader, these are loaded *globally*.  If you want/need isolation, then you run 
with classLoaders (like servlets) providing the isolation.  

Commit is an action done per type system, but it has a potentially global 
effect in that it also loads the JCas classes it can find for those types.  
These are loaded *globally* into the current classloader - there's no mechanism 
in Java (other than using classloaders) to isolate these..  I note that this is 
how v2 works, also.  

re: "In the call you have above, I somehow miss a reference to the CAS instance 
from which the type system is obtained": 

You are correct - This is done using a hidden parameter, which is the type 
system whose data is used when running the static initializers in JCas class 
being loaded.  This hidden parameter is passed via a ThreadLocal, which is set 
during the type system commit, before calling the code to find and load JCas 
classes associated with that type system.

Re: leaking information between CAS instances.  

There's no leaking of slot info in the type system information.  And, the JCas 
class for a type, "Foo", only gets loaded once (globally) (again, per class 
loader).  This loading is done with the "first" type system commit that has a 
type that corresponds to this particular JCas class. This is also how v2 
worked. 

In your scenario, if you do a type system commit in " a CAS with type X having 
feature x and another CAS with type X having feature y":
  - if no JCas classes match type X, no JCas classes are loaded for it
  - if there's a JCas class definition in the classpath for type X, then the 
*first* typesystem commit loads the JCas class, and it get initialized for that 
type system.
    -- When the 2nd type system is committed, the Java will find that JCas 
class already loaded, and not load it again.

This was also the case in version 2.  Trying to use the same JCas class for 
multiple different type systems having different definitions of the 
corresponding type is in the realm of undefined behavior, depending a lot on 
specifics, ordering, etc.  It might partially work in some case, not in others. 

One thing that would work, always, is the scenario where there are 
  - different type systems, 
  - different JCas classes, 
  - but no JCas name collisions (other than for classes which would be the same 
among all the CASes, like Annotation, or MyTopLevelConcept, for instance).  

When CAS 1's type system was committed, it would load its JCas classes, and 
when CAS 2's type system was committed, those (differently named) JCas classes 
would be loaded.

> Strange exception when trying to get JCas FS class through reflection
> ---------------------------------------------------------------------
>
>                 Key: UIMA-5554
>                 URL: https://issues.apache.org/jira/browse/UIMA-5554
>             Project: UIMA
>          Issue Type: Bug
>          Components: Core Java Framework
>    Affects Versions: 3.0.0SDK-beta
>            Reporter: Richard Eckart de Castilho
>
> I am trying to get a class object for a JCas FS type using reflection:
> {noformat}
> Class.forName(typeName);
> {noformat}
> However, it produces this strange error.
> {noformat}
> java.lang.ExceptionInInitializerError
>       at java.lang.Class.forName0(Native Method)
>       at java.lang.Class.forName(Class.java:264)
> ...
> Caused by: org.apache.uima.cas.CASRuntimeException: A JCas class field "sofa" 
> is being initialized by non-framework (user) code before Type System Commit 
> for a type system with a corresponding type. Either change the user load code 
> to not do initialize, or to defer it until after the type system commit.
>       at 
> org.apache.uima.cas.impl.TypeSystemImpl.getAdjustedFeatureOffset(TypeSystemImpl.java:2575)
>       at 
> org.apache.uima.jcas.cas.AnnotationBase.<clinit>(AnnotationBase.java:71)
>       ... 27 more
> {noformat}
> Is it considered harmful to try getting a class object for a JCas FS class?



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to