Hi Anton,

UISession is not thread safe and it is not expected to be accessed from
multiple threads.

Adding and flushing of DirtyDataOwners is done from the AWT thread and
should be done from the AWT thread only. 

Accessing ULC's client-side proxies and basic components should also be
done from AWT thread, just as you would do in Swing.

Thanks and regards,

Janak

-----------------------------------------
Janak Mulani

email: [EMAIL PROTECTED]
url: http://www.canoo.com <http://www.canoo.com/> 

Beyond AJAX - Java Rich Internet Applications

http://www.canoo.com/ulc
----------------------------------------- 

 


________________________________

        From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of Anton Karmanov
        Sent: Monday, July 14, 2008 6:24 PM
        To: [email protected]; [email protected]
        Subject: RE: [ULC-developer] ArrayIndexOutOfBoundsException
        
        

        I use exactly ULC 6.2.

         

        Below  is the source code of class UIWorkplaceInternalFrame, but I
think that it will not help you. I can't send you the full source code.
There are places in our source code, where UISession#addDirtyDataOwner()
is called. May be from different threads.

         

        import java.awt.Component;

        import java.util.Comparator;

         

        import javax.swing.JComponent;

        import javax.swing.LayoutFocusTraversalPolicy;

        import javax.swing.event.InternalFrameAdapter;

        import javax.swing.event.InternalFrameEvent;

        import javax.swing.event.InternalFrameListener;

         

        import com.ulcjava.base.client.UIInternalFrame;

         

        public class UIWorkplaceInternalFrame extends UIInternalFrame

        {

              private int modal =
WorkplaceInternalFrameConstants.NON_MODAL;

         

              private static final Comparator<Component> comparator = new
TabOrderComparator();

         

              @Override

              protected void preInitializeState()

              {

                    super.preInitializeState();

                    TabOrderFocusTraversalPolicy policy = new
TabOrderFocusTraversalPolicy();

                    policy.setComparator(comparator);

        
getBasicInternalFrame().setFocusTraversalPolicy(policy);

              }

         

              public void setModal(int modal)

              {

                    this.modal = modal;

        
getBasicInternalFrame().putClientProperty(WorkplaceInternalFrameConstants.
PROPERTY_MODAL, modal);

              }

         

              public int getModal()

              {

                    return this.modal;

              }

         

              protected void postInitializeState()

              {

                    super.postInitializeState();

        
getBasicInternalFrame().putClientProperty(WorkplaceInternalFrameConstants.
PROPERTY_MODAL,

                                modal);

        
getBasicInternalFrame().addInternalFrameListener(ifListener);

              }

         

              public void dispose()

              {

                    getBasicInternalFrame().dispose();

                    super.dispose();

              }

         

              private InternalFrameListener ifListener = new
InternalFrameAdapter()

              {

                    public void internalFrameActivated(InternalFrameEvent
e)

                    {

        
fireEventULC(WorkplaceInternalFrameConstants.WORKPLACE_INTERNAL_FRAME_EVEN
T,

        
WorkplaceInternalFrameConstants.FRAME_ACTIVATED,

                                      EMPTY_ARGUMENTS);

                    }

         

                    public void internalFrameClosed(InternalFrameEvent e)

                    {

        
fireEventULC(WorkplaceInternalFrameConstants.WORKPLACE_INTERNAL_FRAME_EVEN
T,

        
WorkplaceInternalFrameConstants.FRAME_CLOSED,

                                      EMPTY_ARGUMENTS);

                    }

         

                    public void
internalFrameDeactivated(InternalFrameEvent e)

                    {

        
fireEventULC(WorkplaceInternalFrameConstants.WORKPLACE_INTERNAL_FRAME_EVEN
T,

        
WorkplaceInternalFrameConstants.FRAME_DEACTIVATED,

                                      EMPTY_ARGUMENTS);

                    }

         

                    public void
internalFrameDeiconified(InternalFrameEvent e)

                    {

        
fireEventULC(WorkplaceInternalFrameConstants.WORKPLACE_INTERNAL_FRAME_EVEN
T,

        
WorkplaceInternalFrameConstants.FRAME_DEICONIFIED,

                                      EMPTY_ARGUMENTS);

                    }

         

                    public void internalFrameIconified(InternalFrameEvent
e)

                    {

        
fireEventULC(WorkplaceInternalFrameConstants.WORKPLACE_INTERNAL_FRAME_EVEN
T,

        
WorkplaceInternalFrameConstants.FRAME_ICONIFIED,

                                      EMPTY_ARGUMENTS);

                    }

         

                    public void internalFrameOpened(InternalFrameEvent e)

                    {

        
fireEventULC(WorkplaceInternalFrameConstants.WORKPLACE_INTERNAL_FRAME_EVEN
T,

        
WorkplaceInternalFrameConstants.FRAME_OPENED,

                                      EMPTY_ARGUMENTS);

                    }

              };

        }

         

        I wrote a simple program that reproduces the error with ArrayList:

         

        package tests;

         

        import java.util.ArrayList;

        import java.util.List;

         

        public class ArrayListConcurrencyCheck

        {

              private final Object obj = new Object();

              private final int n = 10000;

              private final int maxSize = 10000;

              private final List<Object> list = new ArrayList<Object>();

         

              private final Thread t1 = new Thread() {

                    @Override

                    public void run()

                    {

                          run1();

                    }

              };

              

              private final Thread t2 = new Thread() {

                    @Override

                    public void run()

                    {

                          run2();

                    }

              };

              

              ArrayListConcurrencyCheck() throws InterruptedException

              {

                    t1.start();

                    t2.start();

                    t2.join();

              }

              

              public static void main(String[] args) throws
InterruptedException

              {

                    new ArrayListConcurrencyCheck();

              }

              

              void run1()

              {

                    System.out.println("T1 STARTED");

                    for (int i = 0; i < n; i++) {

                          list.add(obj);

                          if (list.size() > maxSize) {

                                list.clear();

                          }

                    }

                    System.out.println("T1 FINISHED");

              }

              

              void run2()

              {

                    System.out.println("T2 STARTED");

                    while (t1.isAlive()) {

                          for (int i = 0; i < n; i++) {

                                list.toArray(new Object[list.size()]);

                          }

                    }

                    System.out.println("T2 FINISHED");

              }

        }

         

        Error isn't reproduced for small "n" (n<1000 on my machine) but
it's reproduced for large "n". I think that while one thread invoked
DirtyDataOwnerList#getDirtyDataOwner(), an another thread calls
DirtyDataOwnerList#addDirtyDataOwner(.) or
DirtyDataOwnerList#removeDirtyDataOwner(.), which causes an exception. As
I have already said, the error isn't reproduced any more - the probability
is too small.

         

        From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of Janak Mulani
        Sent: Monday, July 14, 2008 3:25 PM
        To: [email protected]
        Subject: RE: [ULC-developer] ArrayIndexOutOfBoundsException

         

        Hi Anton,

         

        Can you please give me the exact version of ULC i.e. 6.2.x.?

         

        Also send me a small snippet with the code of the InternalFrame
extension?

         

        Thanks and regards,
        
        Janak
        
        -----------------------------------------
        Janak Mulani
        
        email: [EMAIL PROTECTED]
        url: http://www.canoo.com <http://www.canoo.com/> 
        
        Beyond AJAX - Java Rich Internet Applications
        
        http://www.canoo.com/ulc
        ----------------------------------------- 

         

                 

                ________________________________

                                From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of Anton Karmanov
                Sent: Monday, July 14, 2008 2:40 PM
                To: ([email protected])
                Subject: [ULC-developer] ArrayIndexOutOfBoundsException

                Hello.

                 

                Following exception occurred when I called
fireEventULC(.):

                 

                from client: java.lang.ArrayIndexOutOfBoundsException: 1

                            at java.util.ArrayList.toArray(Unknown Source)

                            at
com.ulcjava.base.client.DirtyDataOwnerList.getDirtyDataOwners(DirtyDataOwn
erList.java:6)

                            at
com.ulcjava.base.client.UISession$m_.b(UISession$m_.java:114)

                            at
com.ulcjava.base.client.UISession$m_.addPendingRequest(UISession$m_.java:1
12)

                            at
com.ulcjava.base.client.UISession.a(UISession.java:128)

                            at
com.ulcjava.base.client.UISession.send(UISession.java:269)

                            at
com.ulcjava.base.client.UISession.sendBlocking(UISession.java:281)

                            at
com.ulcjava.base.client.UIProxy.invokeULC(UIProxy.java:181)

                            at
com.ulcjava.base.client.UIProxy.fireMandatoryEventULC(UIProxy.java:144)

                            at
com.ulcjava.base.client.UIProxy.fireEventULC(UIProxy.java:204)

                            at
workplace.ui.components.UIWorkplaceInternalFrame.access$200(UIWorkplaceInt
ernalFrame.java:26)

                            at
workplace.ui.components.UIWorkplaceInternalFrame$2.internalFrameActivated(
UIWorkplaceInternalFrame.java:131)

                            at
javax.swing.JInternalFrame.fireInternalFrameEvent(Unknown Source)

                            at
javax.swing.JInternalFrame.setSelected(Unknown Source)

                            at javax.swing.JInternalFrame.show(Unknown
Source)

                            at java.awt.Component.show(Unknown Source)

                            at java.awt.Component.setVisible(Unknown
Source)

                            at javax.swing.JComponent.setVisible(Unknown
Source)

                            at
com.ulcjava.base.client.UIInternalFrame$BasicInternalFrame.setVisible(UIIn
ternalFrame.java:2)

                            at
com.ulcjava.base.client.UIInternalFrame.setVisible(UIInternalFrame.java:37
)

                            at
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

                            at
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

                            at
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

                            at java.lang.reflect.Method.invoke(Unknown
Source)

                            at
com.ulcjava.base.client.UIProxy.processInvokeUI(UIProxy.java:55)

                            at
com.ulcjava.base.client.UIProxy.a(UIProxy.java:103)

                            at
com.ulcjava.base.client.UIProxy.handleRequest(UIProxy.java:203)

                            at
com.ulcjava.base.client.UISession.b(UISession.java:302)

                            at
com.ulcjava.base.client.UISession.access$1700(UISession.java:298)

                            at
com.ulcjava.base.client.UISession$3.run(UISession$3.java:2)

                            at
java.awt.event.InvocationEvent.dispatch(Unknown Source)

                            at java.awt.EventQueue.dispatchEvent(Unknown
Source)

                            at
com.ulcjava.base.client.FilteringEventQueue.dispatchEvent(FilteringEventQu
eue.java:23)

                            at
java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)

                            at
java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)

                            at
java.awt.EventDispatchThread.pumpEvents(Unknown Source)

                            at
java.awt.EventDispatchThread.pumpEvents(Unknown Source)

                            at java.awt.EventDispatchThread.run(Unknown
Source)

                 

                workplace.ui.components.UIWorkplaceInternalFrame extends
UIInternalFrame. The fireEventULC(.) method was called from
InternalFrameListener#internalFrameActivated(.) method of internal frame's
listener attached to the corresponding BasicInternalFrame.

                 

                It seems to be concurrency problem with ArrayList. I can't
reproduce this exception (it occurred only once).

                 

                I use ULC 6.2.

                 

                Best regards,

                Anton Karmanov

                Mirasoft Group

                 

                 

_______________________________________________
ULC-developer mailing list
[email protected]
http://lists.canoo.com/mailman/listinfo/ulc-developer

Reply via email to