Unhandled JavaScript exception @ addon

I have created a addon to refresh a component at regular frequency (initiated from the client side using gwt Timer), this addon works well for a while, however after a few mins it gets in to trouble… below is the console msgs from the debug window…

13:09:32:372 Retrieved a hierarchy update for a connector (1166) that is not a ComponentContainerConnector
.... above err msg repeated multiple times....
13:09:32:373 Retrieved a hierarchy update for a connector (1183) that is not a ComponentContainerConnector
13:09:32:376  * Update of connector hierarchy completed: 23 ms
13:09:32:376  * Sending hierarchy change events
13:09:32:394 ClassCastException
13:09:32:427 ClassCastException
.... above err msg repeated multiple times....
13:09:32:670 ClassCastException
13:09:32:677 ClassCastException
13:09:32:695  * Hierarchy state change event processing completed: 319 ms
13:09:32:704  * Sending state change events
13:09:32:752 ClassCastException
13:09:32:787 ClassCastException
13:09:32:795 JavaScriptException: (TypeError): Cannot read property 'e' of null
13:09:32:802 JavaScriptException: (TypeError): Cannot read property 'e' of null
13:09:32:809 JavaScriptException: (TypeError): Cannot read property 'e' of null
13:09:32:816 ClassCastException
13:09:32:823 ClassCastException
13:09:32:831 JavaScriptException: (TypeError): Cannot read property 'e' of null
13:09:32:838 JavaScriptException: (TypeError): Cannot read property 'e' of null
... above err msg repeated multiple times....
13:09:33:424 ClassCastException
13:09:33:429 Parent of connector HorizontalLayoutConnector (1263) is null. This is typically an indication of a broken component hierarchy
13:09:33:432 Parent of connector HorizontalLayoutConnector (1265) is null. This is typically an indication of a broken component hierarchy
13:09:33:434 ClassCastException
13:09:33:440 ClassCastException
13:09:33:447 ClassCastException
... above err msg repeated multiple times....

And below is code for the addon

Server side component:

public class Refresher extends AbstractComponent {

	private int milliseconds;

	public interface UpdateHandler extends Serializable {
		public void update();
	}

	private UpdateHandler updateHandler = null;

	public UpdateRPC rpc = new UpdateRPC() {
		@Override
		public void update() {
			updateHandler.update();
		}
	};

	public Refresher() {
		registerRpc(rpc);
	}

	public void setMilliseconds(int milliseconds) {
		this.milliseconds = milliseconds;
		getState().setMilliseconds(milliseconds);
		requestRepaint();
	}

	@Override
	protected RefresherState createState() {
		return new RefresherState(this.milliseconds);
	}

	@Override
	public RefresherState getState() {
		return (RefresherState) super.getState();
	}

	public void setUpdateHandler(UpdateHandler updateHandler) {
		this.updateHandler = updateHandler;
	}

	public UpdateHandler getUpdateHandler() {
		return updateHandler;
	}
}

Connector:

@Connect(Refresher.class)
public class RefresherConnector extends AbstractComponentConnector {
	private UpdateRPC rpc;

	public interface UpdateRPC extends ServerRpc {
		public void update();
	}

	@Override
	public void init() {
		rpc = RpcProxy.create(UpdateRPC.class, this);
		VRefresher widget = getWidget();
		widget.setUpdateHandler(new UpdateHandler() {
			@Override
			public void update() {
				rpc.update();
			}
		});
	}

	@Override
	public RefresherState getState() {
		return (RefresherState) super.getState();
	}

	@Override
	protected Widget createWidget() {
		return GWT.create(VRefresher.class);
	}

	@Override
	public VRefresher getWidget() {
		return (VRefresher) super.getWidget();
	}

	@Override
	public void onStateChanged(StateChangeEvent stateChangeEvent) {
		super.onStateChanged(stateChangeEvent);
		getWidget().setMilliseconds(getState().getMilliseconds());
	}
}

State:

public class RefresherState extends ComponentState {
	private int milliseconds;

	public RefresherState() {
	}

	public RefresherState(int milliseconds) {
		this.milliseconds = milliseconds;
	}

	public int getMilliseconds() {
		return milliseconds;
	}

	public void setMilliseconds(int milliseconds) {
		this.milliseconds = milliseconds;
	}

}

Client:

public class VRefresher extends Widget {

	/** Set the CSS class name to allow styling. */
	public static final String CLASSNAME = "v-mycomponent";
	private Timer timer;

	// /** The client side widget identifier */
	// protected String paintableId;

	// /** Reference to the server connection object. */
	// ApplicationConnection client;

	/**
	 * The constructor should first call super() to initialize the component and
	 * then handle any initialization relevant to Vaadin.
	 */
	public VRefresher() {
		// TODO Example code is extending GWT Widget so it must set a root
		// element.
		// Change to proper element or remove if extending another widget
		setElement(Document.get().createDivElement());

		// This method call of the Paintable interface sets the component
		// style name in DOM tree
		setStyleName(CLASSNAME);
		timer = createTimer();
	}

	private Timer createTimer() {
		Timer timer = new Timer() {
			@Override
			public void run() {
				update();
			}

		};
		return timer;
	}

	private void update() {
		updateHandler.update();
	}

	private int milliseconds;

	public int getMilliseconds() {
		return milliseconds;
	}

	public void setMilliseconds(int milliseconds) {
		this.milliseconds = milliseconds;
		timer.scheduleRepeating(milliseconds);
	}

	private UpdateHandler updateHandler = null;

	public interface UpdateHandler extends Serializable {
		public void update();
	}

	public void setUpdateHandler(UpdateHandler updateHandler) {
		this.updateHandler = updateHandler;
	}

	public UpdateHandler getUpdateHandler() {
		return updateHandler;
	}
}

And this is how this addon is added as a component

Refresher refresher = new Refresher();
		refresher.setUpdateHandler(new UpdateHandler() {
			@Override
			public void update() {
				//refresh();//do the update stuffs here...
			}
		});
		refresher.setMilliseconds(120000);
		addComponent(refresher);

Not sure about the cause of the issue, any advice on this will be really helpful.

Just to add some more info… The component that I try to refresh is huge (say 1 VerticalLayout containing around 50+ VerticalLayouts & each containing around 8+ coponents) so is there a possibility that the response from the server is stripped out due to its size? In other words does the client always receive the entire data from the server irrespective of the size of the response?

And one more thing… on page refresh the entire components are restored properly (continues from where it broke previously)… refresh starts working fine… in a while it breaks again… :frowning:

Also there seems to be some more issue here… If I added two refreshers like below

Refresher refresher1 = new Refresher();
        refresher1.setUpdateHandler(new UpdateHandler() {
            @Override
            public void update() {
                //update component 1...
            }
        });
        refresher1.setMilliseconds(120000);
        addComponent(refresher1);

Refresher refresher2 = new Refresher();
        refresher2.setUpdateHandler(new UpdateHandler() {
            @Override
            public void update() {
                //update component 2...
            }
        });
        refresher2.setMilliseconds(120000);
        addComponent(refresher2);

The refresher works fine for a while and then suddenly the updates of component 1 are shown in the component 2 in the screen! Though both the component’s state in the server side are fine (ie. on refresh the updates are in their corresponding components.)… I’m new to GWT & addon stuffs… I think there is some issue in my addon code itself (something like rpc is not aware of which ui component to update)… Scratching my head… :frowning:

It seems like app engine also has some role to play here (data too big to serialize)

com.google.apphosting.api.ApiProxy$RequestTooLargeException: The request to API call datastore_v3.Put() was too large.

but not sure what is happening exactly… what has to be done in the addon to handle this situation?..

To find out what causes client side exceptions, it’s generally advisable to run the code using GWT’s development mode. If you’re using the Vaadin plugin for Eclipse, there is a convenient button for creating a launch configuration in the project configuration dialog. When dev mode is used, you will get real Java exceptions with full stacktraces whenever a client side exception occurs. The stracktraces can be found by scrolling through the log view in the GWT Development Mode window.

Regarding the RequestTooLargeException that you get, I’d guess the problem is that the server side state of your application is too big to get serialized to the GAE datastore. You could check for memory leaks and investigate whether some of the UI logic could be lazily initialized and discarded once the user leaves that part of the application.

The limit for a single datastore item size in GAE is 1MB (see the table at the end of
this page
).

In most applications this isn’t a problem, but maybe your components or the data they hold are over that limit. Some profiling of the session size might help identify if your issue is some specific data structure or the component hierarchy in general.

Running in GWT’s development mode helped me solve the client side issue… thanks!! :slight_smile:

Yup… the issue is… like I mentioned earlier i have 2 VerticalLayout with around 50+ rows each, each row is another layout containing around 5 labels including 1 description label, 6 links… 2 images… for now
this
works… however, need to find a better solution.

In Wicket there is a onComponentTag(ComponentTag tag) & onComponentTagBody(MarkupStream markupStream, ComponentTag openTag) to manipulate the tag & body respectively… do we have similar stuff in Vaadin? because this can help me reduce substantial number of components I add.

Thanks.

Whoa, that many layouts will definitely cause problems.

To me your use case sounds that you would more likely want to use a Table to render the rows instead of 50+ rows of VerticalLayouts.

If you do want to keep your current approach then I strongly suggest swapping out as many VerticalLayouts as you can with CSSLayouts or even build your own HTML hierarchy with one CustomLayout. Then you could further improve by lazy loading those layouts using something like the
LazyLoadWrapper
.

Hi John, thanks for the suggestions… I’ll try them out soon.