You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

Approaches to generating and loading JCas classes for V3

The JCas generation is particular to a merged type system.  A single JVM may have multiple merged type systems running simultaneously; these can only(?) be handled using separate class loaders per different merged type system.  Furthermore, the class loader used to load the generate JCas classes must also be used for any Application, Annotator, or External resource code that references by name the JCas generated classes. (Note: UIMA provides an ability to reference "generically" via Type and Feature objects).

When to Generate

  • Dynamic - at type system "commit"
    • Pros:
      • guaranteed exact match, no need for code to check this
      • can be done lazily - a large type system with most types unused need not generate most types
        • requires a custom class loader (I think)
    • Cons:
      • user code must commit the type system before any reference to a named JCas type.  This "error" can be checked for, if a special class loader is used.
  • preexisting - by the user externally, ahead of time, running JCasGen on a fully merged type system
    • Pros:
      • Maybe less complex
    • Cons:
      • may be out of sync, need to have more runtime checks
  • preexisting at JVM startup time (via -javaagent).  This is not practical because
    • the merged type system computed might be different - users can write UIMA app code to do custom merging.
    • uses one classpath; in embedded apps there may be multiple classpaths. 
    • is not "lazy" - does whole type system generation

Setup for Type System class loader

We can imagine a new version of UIMAClassLoader, called UIMATypeSystemLoader, which has no URL and only serves to lazily generate and load JCas types.  This loader would have a reference to a committed type system, and would need to be in the parent chain of anything that referenced the generated types by name.  This class loader would be associated with a TypeSystem instance.

This might be setup using UIMAFramework.withUIMATypeSystemContext("a top level class to load and run"); this would load that named class under an instance of UIMATypeSystemLoader.

It would be nice to also run if no such context was set up - in this case, only one type system might be supported (and exceptions thrown if it was redefined).  If no UIMATypeSystemLoader was in the parent path, then type system commit would need to batch generate and load (using that arbitrary class loader) all the types (lazy not supported).  

If there was an instance UIMATypeSystemLoader in the parent chain, then this would support lazy loading.

The UIMATypeSystemLoader has a ref to the committed type system, which is null before a commit.  Type system commit walks up the class loader chain looking for an instance of UIMATypeSystemLoader, and the first one found has its ref changed from null to the committed type system. If it was not null, compare the commited type system with the previous value - if equal, OK, and leave things as is.  If not, throw exception: can't change merged type system using same UIMATypeSystemLoader.

Approach - outside of UIMA framework

The UIMA framework could take an approach which says a particular UIMA application (imagine it running as a servlet) has its own classpath, set up and managed outside of the UIMA framework (e.g., by the J2EE servlet APIs).  Using the preexisting alternative, the user would generate the JCas classes, and include them in the servlet's classpath.

  • supports lazy loading trivially, but not lazy generation
  • restricts particular UIMA app to one type system.

Generation notes

Need to package ASM embedded within new prefix in project (ASM requirement?)

Need to insure package-name is defined before doing class definition

Need to avoid circular refs or see if they can be handled by delaying resolution in the class loader

  • No labels