You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@uima.apache.org by "Marshall Schor (JIRA)" <de...@uima.apache.org> on 2019/07/02 13:04:00 UTC

[jira] [Comment Edited] (UIMA-6057) Avoid falsely switching classloader

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

Marshall Schor edited comment on UIMA-6057 at 7/2/19 1:03 PM:
--------------------------------------------------------------

Hi, thanks for responding; classloader things I find take a lot of thinking :).

Here's a failing use case that I'm worried about:

1) you have a main pipeline, it defines some JCas class Foo.

2) you have some other "special" pipeline, it too defines some JCas class foo, but is run in such a way that it has its own classloader.  
 Assuming it's using a Uima class loader, these have the property that they first check if a class being requested to be loaded can be found in its set of URLs, and then only if it is not, does it delegate to its parent (which typically would be the main pipeline's class loader.  This behavior is intentional, to allow the special components to have its own versions of classes that supersede those that might be found through its parent.

3) Now suppose the special pipeline makes some instances of Foo and puts them in the CAS

4) Now suppose the main pipeline wants to use those "results" - so it iterates over the cas looking for that type, and attempts to assign any instance it finds to its JCas class Foo,  e.g.  Foo myFoo = iterator.getNext();  The assignment will fail, saying class cast error cannot cast "Foo" to "Foo", which, besides being true, is a hard-to-understand error!

This all can be avoided, if the intent is to share a common class loader, by intentionally creating the "special" pipelines in a way that shares the class loader, so it seems (since as far as I can tell, that is the intent), that would be the much better approach to fixing this issue.

I think I do see one sub-case where the proposed change would work out - but it seem fragile to me.  It's this case:

Same 1 and 2, but then add one more caveat - the main pipeline makes no reference at all to any JCas class that will be loaded by the "special" pipeline, before calling it.  In that case, the main pipeline has not loaded the shared JCas class, so when it finally gets around to loading it, it will load the same one.   Another way to say this: the special pipeline cannot define and load any JCas class that the main pipeline might have referred to before running the special pipeline.

My current summary:
 * I think doing this change would be dangerous, and it would depend on behaviors in other pipelines that might or might not be present.
 * There seems to be an easy, viable alternative (namely, letting the simple-pipeline run with the same classloader as the main, if sharing is wanted.)

But I'm willing to be convinced depending on learning more about other use cases...


was (Author: schor):
Hi, thanks fore responding; classloader things I find take a lot of thinking :).

Here's a failing use case that I'm worried about:

1) you have a main pipeline, it defines some JCas class Foo.

2) you have some other "special" pipeline, it too defines some JCas class foo, but is run in such a way that it has its own classloader.  
Assuming it's using a Uima class loader, these have the property that they first check if a class being requested to be loaded can be found in its set of URLs, and then only if it is not, does it delegate to its parent (which typically would be the main pipeline's class loader.  This behavior is intentional, to allow the special components to have its own versions of classes that supersede those that might be found through its parent.

3) Now suppose the special pipeline makes some instances of Foo and puts them in the CAS

4) Now suppose the main pipeline wants to use those "results" - so it iterates over the cas looking for that type, and attempts to assign any instance it finds to its JCas class Foo,  e.g.  Foo myFoo = iterator.getNext();  The assignment will fail, saying class cast error cannot cast "Foo" to "Foo", which, besides being true, is a hard-to-understand error!

This all can be avoided, if the intent is to share a common class loader, by intentionally creating the "special" pipelines in a way that shares the class loader, so it seems (since as far as I can tell, that is the intent), that would be the much better approach to fixing this issue.

I think I do see one sub-case where the proposed change would work out - but it seem fragile to me.  It's this case:

Same 1 and 2, but then add one more caveat - the main pipeline makes no reference at all to any JCas class that will be loaded by the "special" pipeline, before calling it.  In that case, the main pipeline has not loaded the shared JCas class, so when it finally gets around to loading it, it will load the same one.   Another way to say this: the special pipeline cannot define and load any JCas class that the main pipeline might have referred to before running the special pipeline.

My current summary:
 * I think doing this change would be dangerous, and it would depend on behaviors in other pipelines that might or might not be present.
 * There seems to be an easy, viable alternative (namely, letting the simple-pipeline run with the same classloader as the main, if sharing is wanted.)

But I'm willing to be convinced depending on learning more about other use cases...

> Avoid falsely switching classloader
> -----------------------------------
>
>                 Key: UIMA-6057
>                 URL: https://issues.apache.org/jira/browse/UIMA-6057
>             Project: UIMA
>          Issue Type: Bug
>          Components: Core Java Framework
>            Reporter: Matthias Koch
>            Priority: Major
>         Attachments: UIMA-6057.diff
>
>
> In some cases the classloader is switched back, although it hasn't be switched before processing.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)