Why is AbstractClientConnector throwing checkForComodification exception

What causes a ConcurrentModificationException during the setting of panel contents? What do I have to look for in the component I am adding to avoid this?

Here’s my code:

[code]
private Panel mBodyPanel = new Panel();

private HashMap<String, VerticalLayout> allViews = new HashMap<String, VerticalLayout>();

… create several verticalLayout and store in allViews…

    Button statbtn = new Button(name, new ClickListener()
    {
        @Override
        public void buttonClick(ClickEvent event) {
             VerticalLayout vl = allViews.get("Stats");
             if (vl != null) mBodyPanel.setContent(vl);   <--- Exception thrown here!
        }
    });   

[/code]And I am getting this exception:

java.util.ConcurrentModificationException: null
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859) ~[na:1.7.0_51]

    at java.util.ArrayList$Itr.next(ArrayList.java:831) ~[na:1.7.0_51]

    at com.vaadin.server.AbstractClientConnector.attach(AbstractClientConnector.java:589) ~[AbstractClientConnector.class:7.4.6]

    at com.vaadin.ui.AbstractComponent.attach(AbstractComponent.java:621) ~[AbstractComponent.class:7.4.6]

    at com.vaadin.server.AbstractClientConnector.attach(AbstractClientConnector.java:590) ~[AbstractClientConnector.class:7.4.6]

    at com.vaadin.ui.AbstractComponent.attach(AbstractComponent.java:621) ~[AbstractComponent.class:7.4.6]

    at com.vaadin.server.AbstractClientConnector.attach(AbstractClientConnector.java:590) ~[AbstractClientConnector.class:7.4.6]

    at com.vaadin.ui.AbstractComponent.attach(AbstractComponent.java:621) ~[AbstractComponent.class:7.4.6]

    at com.vaadin.ui.AbstractComponent.setParent(AbstractComponent.java:528) ~[AbstractComponent.class:7.4.6]

    at com.vaadin.ui.AbstractSingleComponentContainer.setContent(AbstractSingleComponentContainer.java:149) ~[AbstractSingleComponentContainer.class:7.4.6]

    at com.ixiacom.project.gui.component.ports.MultiViewPanel$1.buttonClick(MultiViewPanel.java:70) ~[MultiViewPanel$1.class:na]

    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_51]

    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_51]

    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_51]

    at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_51]

    at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:508) ~[ListenerMethod.class:7.4.6]

    at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:198) ~[EventRouter.class:7.4.6]

    at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:161) ~[EventRouter.class:7.4.6]

    at com.vaadin.server.AbstractClientConnector.fireEvent(AbstractClientConnector.java:977) ~[AbstractClientConnector.class:7.4.6]

    at com.vaadin.ui.Button.fireClick(Button.java:393) ~[Button.class:7.4.6]

    at com.vaadin.ui.Button$1.click(Button.java:61) ~[Button$1.class:7.4.6]

    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_51]

    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_51]

    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_51]

    at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_51]

    at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:168) ~[ServerRpcManager.class:7.4.6]

    at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:118) ~[ServerRpcManager.class:7.4.6]

    at com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:291) [ServerRpcHandler.class:7.4.6]

    at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:184) [ServerRpcHandler.class:7.4.6]

    at com.vaadin.server.communication.PushHandler$3.run(PushHandler.java:176) [PushHandler$3.class:7.4.6]

    at com.vaadin.server.communication.PushHandler.callWithUi(PushHandler.java:255) [PushHandler.class:7.4.6]

    at com.vaadin.server.communication.PushHandler.access$200(PushHandler.java:58) [PushHandler.class:7.4.6]

    at com.vaadin.server.communication.PushHandler$1.onRequest(PushHandler.java:78) [PushHandler$1.class:7.4.6]

    at org.atmosphere.cpr.AsynchronousProcessor.action(AsynchronousProcessor.java:205) [AsynchronousProcessor.class:2.2.4.vaadin5]

    at org.atmosphere.cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.java:104) [AsynchronousProcessor.class:2.2.4.vaadin5]

    at org.atmosphere.container.Servlet30CometSupport.service(Servlet30CometSupport.java:66) [Servlet30CometSupport.class:2.2.4.vaadin5]

    at org.atmosphere.cpr.AtmosphereFramework.doCometSupport(AtmosphereFramework.java:2075) [AtmosphereFramework.class:2.2.4.vaadin5]

    at org.atmosphere.websocket.DefaultWebSocketProcessor.dispatch(DefaultWebSocketProcessor.java:570) [DefaultWebSocketProcessor.class:2.2.4.vaadin5]

    at org.atmosphere.websocket.DefaultWebSocketProcessor$3.run(DefaultWebSocketProcessor.java:332) [DefaultWebSocketProcessor$3.class:2.2.4.vaadin5]

    at org.atmosphere.util.VoidExecutorService.execute(VoidExecutorService.java:101) [VoidExecutorService.class:2.2.4.vaadin5]

    at org.atmosphere.websocket.DefaultWebSocketProcessor.dispatch(DefaultWebSocketProcessor.java:327) [DefaultWebSocketProcessor.class:2.2.4.vaadin5]

    at org.atmosphere.websocket.DefaultWebSocketProcessor.invokeWebSocketProtocol(DefaultWebSocketProcessor.java:424) [DefaultWebSocketProcessor.class:2.2.4.vaadin5]

    at org.atmosphere.container.JSR356Endpoint$1.onMessage(JSR356Endpoint.java:206) [JSR356Endpoint$1.class:2.2.4.vaadin5]

    at org.atmosphere.container.JSR356Endpoint$1.onMessage(JSR356Endpoint.java:203) [JSR356Endpoint$1.class:2.2.4.vaadin5]

    at org.apache.tomcat.websocket.WsFrameBase.sendMessageText(WsFrameBase.java:375) [tomcat-websocket.jar:8.0.5]

    at org.apache.tomcat.websocket.WsFrameBase.processDataText(WsFrameBase.java:472) [tomcat-websocket.jar:8.0.5]

    at org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:275) [tomcat-websocket.jar:8.0.5]

    at org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:116) [tomcat-websocket.jar:8.0.5]

    at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:55) [tomcat-websocket.jar:8.0.5]

    at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler$WsReadListener.onDataAvailable(WsHttpUpgradeHandler.java:194) [tomcat-websocket.jar:8.0.5]

    at org.apache.coyote.http11.upgrade.AbstractServletInputStream.onDataAvailable(AbstractServletInputStream.java:194) [tomcat-coyote.jar:8.0.5]

    at org.apache.coyote.http11.upgrade.AbstractProcessor.upgradeDispatch(AbstractProcessor.java:95) [tomcat-coyote.jar:8.0.5]

    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:650) [tomcat-coyote.jar:8.0.5]

    at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222) [tomcat-coyote.jar:8.0.5]

    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1575) [tomcat-coyote.jar:8.0.5]

    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1533) [tomcat-coyote.jar:8.0.5]

    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_51]

    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_51]

    at java.lang.Thread.run(Thread.java:744) [na:1.7.0_51]

I am running Vaadin 7.4.6 with Java 7

Any ideas or pointers on how to track down this issue?

Hmmm… Is statbtn inside mBodyPanel’s content? If yes that is the problem.

No. The button is in a control section (a CssLayout) that sits on the top of the page that has multiple buttons that control switching the contents of the lower panel. Here’s the hierarchy:

[code]

  • VerticalLayout
    • CssLayout
      • Button ← statBtn
    • Panel ← mBodyLayout
      [/code]Is this potentially a problem?

I am essentially trying to mimick the behavior of a tabbed pane. And this has been working for a while, but only recently it started breaking and I can’t figure out why or how to work around it.

Can you attach here the MultiViewPanel codes? Code snippet above can’t show why this is happening.

Hi, do you have any overridden attach() methods or added attach listeners that change the component hierarch (add/remove components)? For instance, something like this is not going to work:

class MyLabel extends Label() {
    @Override
    public void attach() {
        super.attach();
        getParent().addComponent(new Button());
    }
}

layout.addComponent(new MyLabel());
panel.setContent(layout);

I don’t override any attach() method myself. However, I have a CustomField and I am using the MasonryLayout addon and one of them may be causing this issue.

I traced the problem down to a valueChange that gets fired during a call to addComponent.

In short:
A Custom field’s attach() is calling setInternalValue() which is firing a valueChange event. I have a listener on the field that updates the parent layout when a change happens. I believe the exception occurs in that chain of events.

In detail:
I am using MasonryLayout to display a dashboard of blocks of editable objects in a panel. Each block size and visibility may change due to the user modifying its fields. So all fields are wired to to fire a “dirty” event when any of their values is changed. The listener to the event tells the layout to re-layout the blocks to accomodate for any changes.

This all worked fine until I found that MasonryLayout does not properly detect block size changes and causes blocks to overlap or leave empty gaps. This seems like a bug in MasonryLayout. To get around this issue I found that adding (or removing) an empty (fake) block forces a relayout. This worked well but apparently introduced this error in one of my views (I use this pattern in multiple views).

The error occurs when the first block that contains a CustomField is added. The attach() method is causing setInternalValue() to be invoked and firing a value change event which causes an attempt to add the fake component.