Anytime that a thread might end up being the one to download code, you need 
that threads CCL to be set.   The AWTEvent thread(s) in particular are a 
sticking point.  I have a class which I use for managing threading in 
AWT/Swing.  It’s called ComponentUpdateThread.  It works as follows.

new ComponentUpdateThread<List<Item>>( itemList, actionButton1, actionButton2, 
checkbox1 ) {
        public void setup() {
                // In event thread
                setBusyCursorOn( itemList );
        }
        public List<Item>construct() {
                try {
                        return service.getListOfItems( filterParm1 );
                } catch( Exception ex ) {
                        reportException(ex);
                }
                return null;
        }
        public void finished() {
                List<Item> let;
                if( (lst = get()) != null ) {
                        itemList.getModel().setContents( lst );
                }
        }
}.start();

This class will make the passed components disabled to keep them from being 
clicked on again, setup for processing use a non AWTEvent thread for getting 
data with other components of the UI still working, and finally mark the 
disabled components back to enabled, and load the list with the returned items, 
if there where any returned.

There is the opportunity for 3 or more threads to be involved here.  First, 
there is the calling thread.  It doesn’t do anything but start the work.  Next, 
there is an AWTEvent thread which will invoke setup().  Next there is a worker 
thread which will invoke construct().   Finally, there is (possible another) 
AWTEventThread which will invoke finished().

In total there could be up to four different threads involved, all of which 
must have TCCL set to the correct class loader.  My convention in the 
implementation, is that that will be this.getClass().getClassLoader().

This is all managed inside of the implementation of ComponentUpdateThread so 
that I don’t have to worry about it, any more.  But it’s important to 
understand that if you don’t do that, then the classes that the calling thread 
can resolve, and Item in this specific case in particular, and you would thus 
potentially see Item come from another class loader than you intended (the 
services class loader with “null” as the parent), and this will result in 
either a CNFE or CCE.

Gregg

> On Feb 6, 2017, at 11:28 AM, Michał Kłeczek (XPro Sp. z o. o.) 
> <michal.klec...@xpro.biz> wrote:
> 
> What I was specifically asking for is whether this is needed during 
> deserialization or after deserialization.
> 
> In other words - if I can lock the TCCL to an instance of MarshalInputStream 
> existing for the duration of a single remote call.
> 
> Thanks,
> Michal
> 
> Gregg Wonderly wrote:
>> The predominant place where it is needed is when you download a serviceUI 
>> component from a proxy service which just advertises some kind of “browsing” 
>> interface to find specific services and interact with them, and that 
>> serviceUI is embedded in another application with it’s own codebase
>> 
>> appl->serviceUI-for-browsing->Service-to-use->That-Services-ServiceUI
>> 
>> In this case, TCCL must be set to the serviceui classes classloader so that 
>> the “serviceui-for-browsing” will have a proper parent class pointer.
>> 
>> Anytime that downloaded code might download more code, it should always set 
>> TCCL to its own class loader so that the classes it downloads reflect 
>> against the existing class definitions.
>> 
>> Gregg
>> 
>>> On Feb 6, 2017, at 12:03 AM, Michał Kłeczek (XPro Sp. z o. o.) 
>>> <michal.klec...@xpro.biz> <mailto:michal.klec...@xpro.biz> wrote:
>>> 
>>> Hi,
>>> 
>>> During my work on object based annotations I realized it would be more 
>>> efficient not to look for TCCL upon every call to "load class" (when 
>>> default loader does not match the annotation).
>>> It might be more effective to look it up upon stream creation and using it 
>>> subsequently for class loader selection.
>>> 
>>> But this might change semantics of deserialization a little bit - it would 
>>> not be possible to change the context loader during deserialization.
>>> My question is - are there any scenarios that require that?
>>> I cannot think of any but...
>>> 
>>> Thanks,
>>> Michal
>> 
> 

Reply via email to