Button exception: very disturbing!

I sometimes get this exception:


12:47:29,109 INFO  [STDOUT]
 java.lang.ClassCastException: java.lang.String
12:47:29,109 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.Button.paintContent(Button.java:151)
12:47:29,109 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.AbstractComponent.paint(AbstractComponent.java:663)
12:47:29,109 INFO  [STDOUT]
 	at com.itmill.toolkit.terminal.gwt.server.CommunicationManager.handleUidlRequest(CommunicationManager.java:394)
12:47:29,109 INFO  [STDOUT]
 	at com.itmill.toolkit.terminal.gwt.server.ApplicationServlet.service(ApplicationServlet.java:431)
12:47:29,109 INFO  [STDOUT]
 	at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
12:47:29,109 INFO  [STDOUT]
 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
12:47:29,109 INFO  [STDOUT]
 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
12:47:29,109 INFO  [STDOUT]
 	at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:81)
12:47:29,109 INFO  [STDOUT]
 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
12:47:29,109 INFO  [STDOUT]
 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
12:47:29,109 INFO  [STDOUT]
 	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
12:47:29,109 INFO  [STDOUT]
 	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
12:47:29,109 INFO  [STDOUT]
 	at org.jboss.web.tomcat.security.CustomPrincipalValve.invoke(CustomPrincipalValve.java:39)
12:47:29,109 INFO  [STDOUT]
 	at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:153)
12:47:29,109 INFO  [STDOUT]
 	at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:59)
12:47:29,109 INFO  [STDOUT]
 	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
12:47:29,109 INFO  [STDOUT]
 	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
12:47:29,109 INFO  [STDOUT]
 	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
12:47:29,109 INFO  [STDOUT]
 	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
12:47:29,109 INFO  [STDOUT]
 	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)
12:47:29,109 INFO  [STDOUT]
 	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:744)
12:47:29,109 INFO  [STDOUT]
 	at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
12:47:29,109 INFO  [STDOUT]
 	at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
12:47:29,109 INFO  [STDOUT]
 	at java.lang.Thread.run(Thread.java:595)

This is very disturbing because it causes the server to crash. It seems the value of some button is somehow set to String type (I know it’s not in my code). The paintContent() method of Button can’t deal with this exception:


public void paintContent(PaintTarget target) throws PaintException {
        super.paintContent(target);

        if (isSwitchMode()) {
            target.addAttribute("type", "switch");
        }
        boolean state;
        try {
            state = ((Boolean) getValue()).booleanValue();
        } catch (final NullPointerException e) {
            state = false;
        }
        target.addVariable(this, "state", state);

    }

I need to solve this problem very soon so I would really appreciate any ideas for help.

The version number is 5.2.6.

Button.setValue() should throw exception. It doesn’t. I’ll make a ticket for it.

I 've no idea how you ended up with that situation. Before ticket is fixed, you could try to extend Button by changing your Buttons to that extended button.

Somethig like this, add debug breakpoint and check stacktrace:

public DebugButton extends Button {
   @Override
   public void setValue(Object o) {
        if (o instanceof String) {
           System.out.println("OUCH");
        }
    super.setValue(o);
   }
}

Hi,

That is very odd since the value of Button most certainly should never be anything but Boolean…

It’s impossible to fix without being able to reproduce, though, so I really must ask you to provide more code - preferably a reduced example causing the problem.
We will of course investigate this anyway, but since Button is a fairly common component, and this is the first problem of this kind, it might be hard to reproduce w/o any pointers…

Is the Button for instance connected to some external Property, generated by FieldFactory or in a GeneratedColumn in Table? Or something else that’s not just basic addComponent(new Button(Click me"))?

Best Regards,
Marc

Made ticket

#2151 - Button#setValue requires type-checking

At this point I’m not sure which button it is that generates this exception. But they all are generated “normally” like this:


someButton = new Button("ButtonName",this);

so that should be OK.

In my application, there is a valueChangeEvent, triggered by a change of selection in a NativeSelect. Some data is fetched from db, and lots of fields inside a TabSheet are updated etc. All of my own code executes normally. It is after the valueChangeEvent has completed, that the exception occurs. This is why it’s been hard to pinpoint where exactly the problem is.

This is a good idea, I’ll try it.

This exception happens when certain Buttons are updated from disabled to enabled. I extended those buttons to get some log messages, but they seem to be OK.

I extended the paintContent() method in the OrderedLayout where this happens. It looks like some sub-layout component has its start tag set to “button” and end tag to “orderedlayout”.


23:08:27,921 INFO  [STDOUT]
 java.lang.ClassCastException: java.lang.String
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.Button.paintContent(Button.java:151)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.AbstractComponent.paint(AbstractComponent.java:663)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.OrderedLayout.paintContent(OrderedLayout.java:198)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.AbstractComponent.paint(AbstractComponent.java:663)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.OrderedLayout.paintContent(OrderedLayout.java:198)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.AbstractComponent.paint(AbstractComponent.java:663)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.Panel.paintContent(Panel.java:178)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.AbstractComponent.paint(AbstractComponent.java:663)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.OrderedLayout.paintContent(OrderedLayout.java:198)
23:08:27,921 INFO  [STDOUT]
 	at com.company.ui.web.panels.MySheet.paintContent(MySheet.java:972)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.AbstractComponent.paint(AbstractComponent.java:663)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.TabSheet.paintContent(TabSheet.java:233)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.AbstractComponent.paint(AbstractComponent.java:663)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.OrderedLayout.paintContent(OrderedLayout.java:198)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.AbstractComponent.paint(AbstractComponent.java:663)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.Panel.paintContent(Panel.java:178)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.AbstractComponent.paint(AbstractComponent.java:663)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.OrderedLayout.paintContent(OrderedLayout.java:198)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.AbstractComponent.paint(AbstractComponent.java:663)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.terminal.gwt.server.CommunicationManager.handleUidlRequest(CommunicationManager.java:394)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.terminal.gwt.server.ApplicationServlet.service(ApplicationServlet.java:431)
23:08:27,921 INFO  [STDOUT]
 	at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
23:08:27,921 INFO  [STDOUT]
 	at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:81)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
23:08:27,921 INFO  [STDOUT]
 	at org.jboss.web.tomcat.security.CustomPrincipalValve.invoke(CustomPrincipalValve.java:39)
23:08:27,921 INFO  [STDOUT]
 	at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:153)
23:08:27,921 INFO  [STDOUT]
 	at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:59)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:744)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
23:08:27,921 INFO  [STDOUT]
 	at java.lang.Thread.run(Thread.java:595)
23:08:27,921 INFO  [STDOUT]
 com.itmill.toolkit.terminal.PaintException: Invalid UIDL: wrong ending tag: 'orderedlayout' expected: 'button'.
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.terminal.gwt.server.JsonPaintTarget.endTag(JsonPaintTarget.java:177)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.AbstractComponent.paint(AbstractComponent.java:677)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.TabSheet.paintContent(TabSheet.java:233)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.AbstractComponent.paint(AbstractComponent.java:663)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.OrderedLayout.paintContent(OrderedLayout.java:198)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.AbstractComponent.paint(AbstractComponent.java:663)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.Panel.paintContent(Panel.java:178)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.AbstractComponent.paint(AbstractComponent.java:663)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.OrderedLayout.paintContent(OrderedLayout.java:198)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.ui.AbstractComponent.paint(AbstractComponent.java:663)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.terminal.gwt.server.CommunicationManager.handleUidlRequest(CommunicationManager.java:394)
23:08:27,921 INFO  [STDOUT]
 	at com.itmill.toolkit.terminal.gwt.server.ApplicationServlet.service(ApplicationServlet.java:431)
23:08:27,921 INFO  [STDOUT]
 	at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
23:08:27,921 INFO  [STDOUT]
 	at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:81)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
23:08:27,921 INFO  [STDOUT]
 	at org.jboss.web.tomcat.security.CustomPrincipalValve.invoke(CustomPrincipalValve.java:39)
23:08:27,921 INFO  [STDOUT]
 	at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:153)
23:08:27,921 INFO  [STDOUT]
 	at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:59)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:744)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
23:08:27,921 INFO  [STDOUT]
 	at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
23:08:27,921 INFO  [STDOUT]
 	at java.lang.Thread.run(Thread.java:595)

So there wasn’t “OUCH” in console output at all and still you get that Button#paintContent cast exception?

Is it always same button, or does it happen randomly? If you check Buttons value with debugger it might help you to investigate how Button got its invalid value.

This is caused by Button#paintContent. It doesn’t set end tag properly because of the cast exception.

How about extending Button, overriding setValue() and put the logging there instead. At some point in time setValue() must be called with a String parameter if getValue() returns a String.

An even easier way if you are running Eclipse or some other IDE would be to put a breakpoint in AbstractField.setValue() and restrict it to break only when “this” is an instanceof Button and newValue is an instanceof String. Then you should be able to directly see what causes the problem.

The problem seems really strange to me. What has happened is that your button.getValue() returns a String instead of Boolean. The problem might be impossible to solve without seeing your source code, but I would propose to try out the following:

  • Upgrade to latest version (5.2.10)
  • Put a breakpoint to button.paintContents and button.setValue and trace where the string originates from
  • Recheck (or post here) the paintContents code. The situation you describe with OrderedLayout seems impossible

That’s right. I replaced all buttons in the application with DebugButtons, but no errors come from there. So there has to be a “hidden” button somehow generated somewhere. Or, Toolkit treats some OrderedLayout as a Button. The problem-causing buttons are inside an OrderedLayout, and when you remove the buttons, the problem goes away. But as said, these buttons have been extended to DebugButtons and they seem to work OK. Very strange.

The frameworks does not do anything like that.

We would like to help, but without seeing your application or an example where this exception could be reproduced we can just guess.

My best guess is that you either:

  • Have a button that binds to String-typed datasource
  • Have missed something in your checks
  • End up with broken UIDL by painting something violating the paint restrictions in paint or paintContents and this somehow triggers the problem.

Then the problem is solved, please post the solution here. Even though I have not heard of this kind of problem before, it could be useful to add more checks for wrong arguments in order to prevent this happening to anyone else.

Really interesting problem you have there. What is the Buttons value when you look it with debugger? You can catch right Button by making IDE break on ClassCastException. If your using eclipse->debug perspective->breakpoints tab->add java exception break point (small icon)

Thank you. I did that and finally found out the problem.

The problem component was actually a Checkbox whose value I had accidentally changed to String at one point because of too much copy-pasting. But because the exception messages were coming from Button class, I concentrated my efforts on the Buttons, didn’t realize the Checkbox is an extension of Button. In any case, it was my mistake and not an Itmill bug.

My apologies for not posting earlier.