You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by "Miguel Munoz (JIRA)" <ji...@apache.org> on 2008/04/05 03:15:24 UTC

[jira] Created: (WICKET-1483) Unusual ClassCastException (SimpleAttributeModifier to IBehaviorListener) processing onError.

Unusual ClassCastException (SimpleAttributeModifier to IBehaviorListener) processing onError.
---------------------------------------------------------------------------------------------

                 Key: WICKET-1483
                 URL: https://issues.apache.org/jira/browse/WICKET-1483
             Project: Wicket
          Issue Type: Bug
          Components: wicket
    Affects Versions: 1.3.2, 1.3.1, 1.3.0-final
         Environment: Microsoft Windows XP [Version 5.1.2600] (Server & Client)
            Reporter: Miguel Munoz
            Priority: Minor


Build the application from the four class files and one html file below. Run class Start as an application. Go to your browser, to this URL:

http://localhost:4280/behaviorbug/

Type some text into the text field. After six characters, it will throw a ClassCastException.

Source:

package com.bugs.behaviorBug;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.behavior.SimpleAttributeModifier;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.model.IModel;

public class BehaviorBug extends TextField {

  public BehaviorBug(String id, IModel model) {
    super( id, model );
    init();
  }

  private int kc = 0;
  private int cc = 0;
  private final SimpleAttributeModifier blackBorder = new SimpleAttributeModifier(
      "border-color", "black" );
  private final SimpleAttributeModifier redBorder = new SimpleAttributeModifier(
      "border-color", "red" );
  private SimpleAttributeModifier currentBorder = null;

  private void init() {
    setBorder( this.blackBorder );
    AjaxFormComponentUpdatingBehavior changeWarningBehavior = new AjaxFormComponentUpdatingBehavior(
        "onchange" ) {

      @Override
      protected void onUpdate(AjaxRequestTarget target) {
        System.err.println( "WarningTextField onUpdate onChange "
            + BehaviorBug.this.cc++ );
        reColor();
      }

    };

    // I'm trying to do something tricky here. I want it to validate after every
    // keystroke, so the user can get instant feedback on when the data is good.
    AjaxFormComponentUpdatingBehavior keyUpWarningBehavior = new AjaxFormComponentUpdatingBehavior(
        "onkeyup" ) {

      @Override
      protected void onUpdate(AjaxRequestTarget target) {
        System.err.println( "WarningTextField onUpdate onKeyUp "
            + BehaviorBug.this.kc++ );
        reColor();
        // Thread.dumpStack();
      }

      // The implementation of AjaxFormComponentUpdatingBehavior only calls
      // onUpdate
      // when the field is valid. Since it won't update when the field is
      // invalid, I
      // can't get my instant feedback unless I call onUpdate() when there's an
      // error.
      // Since I can't override onEvent() (It's final), I override onError to
      // force
      // an update even when the field is invalid. This should be safe, since
      // onError()
      // is only called on invalid data with a null exception, in which case it
      // does
      // nothing.
      // This, however, seems to be what causes the bug. I have no idea why this
      // would cause the bug.
      @Override
      protected void onError(AjaxRequestTarget target, RuntimeException e) {
        // Called on validation error with a null e.
        super.onError( target, e ); // Throws e, if it's not null. Does nothing
                                    // otherwise.
        onUpdate( target );
      }

    };
    add( changeWarningBehavior );
    add( keyUpWarningBehavior );
  }

  private void reColor() {
    if ( isValid() ) {
      setBorder( BehaviorBug.this.blackBorder );
    } else {
      setBorder( BehaviorBug.this.redBorder );
    }
  }

  private void setBorder(SimpleAttributeModifier border) {
    if ( this.currentBorder != null && this.currentBorder != border ) {
      remove( this.currentBorder );
    }
    this.currentBorder = border;
    add( this.currentBorder );
  }
}

package com.bugs.behaviorBug;

import org.apache.wicket.Application;
import org.apache.wicket.Page;
import org.apache.wicket.Request;
import org.apache.wicket.Response;
import org.apache.wicket.Session;
import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.protocol.http.WebSession;

/**
 * 
 * @author Miguel Muñoz
 * @version $Id$
 * 
 */
public class BehaviorBugApplication extends WebApplication {

  /**
   * Constructor
   */
  public BehaviorBugApplication() {
    // empty
  }

  @Override
  protected void init() {
    // empty
  }

  @Override
  public Class<? extends Page> getHomePage() {
    return Index.class;
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.apache.wicket.protocol.http.WebApplication#newSession(org.apache.wicket.Request,
   *      org.apache.wicket.Response)
   */
  @Override
  public Session newSession(Request request, Response response) {
    return new BugSession( this, request );
  }
  
  public class BugSession extends WebSession {
    public BugSession(Application application, Request request) {
      super(request);
      setApplication( application );
    }
  }
}

package com.bugs.behaviorBug;

import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.model.Model;
import org.apache.wicket.validation.IValidator;
import org.apache.wicket.validation.validator.StringValidator;

/**
 * 
 * @author Miguel Muñoz
 * @version $Id$
 * 
 */
public class Index extends WebPage {

  /**
   * 
   */
  public Index() {
    Form form = new Form("form");
    TextField textField = new BehaviorBug("testfield", new Model());
    IValidator lengthValidator = new StringValidator.MaximumLengthValidator(4);
    textField.add( lengthValidator );
    form.add( textField );
    add(form);
  }
  
}

package com.bugs.behaviorBug;

import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.webapp.WebAppContext;

/**
 * 
 * @author Miguel Muñoz
 * @version $Id$
 * 
 */
public class Start {
  private static final int defaultPort = 4280;
  /**
   * 
   * @param args
   */
  public static void main(String[] args) {
    int port = defaultPort;
    if (args.length != 0) {
      try {
        port = Integer.valueOf( args[0] );
      } catch ( NumberFormatException e ) {
        System.err.println("Unable to parse port parameter \"" + args[0] + "\" as an integer.");
        System.err.println("Using default value of x " + defaultPort);
      }
    }
    Server server = new Server();
    SelectChannelConnector connector = new SelectChannelConnector();
    connector.setPort( port );
    server.setConnectors( new Connector[] { connector } );

    WebAppContext web = new WebAppContext();
//    web.setContextPath( "/workspace/WicketTutorial" );
    web.setContextPath( "/behaviorbug" );
    System.out.println( "CP: " + web.getContextPath() );
    web.setWar( "src/main/webapp" + port );
    server.addHandler( web );
    
    try {
      server.start(); // Who was the bozo who declared this to throw Exception?
      server.join();
    } catch ( Exception e ) {
      e.printStackTrace();
      System.exit( 1 );
    }
  }
}

<html>
<head>
<title>Behavior Bug</title>
<link href="style.css" rel="stylesheet" />
</head>
<body>
<div id="container">
	<div id="header">Behavior Bug</div>
	<div id="content">
		Type some text into the field below. After six characters, you'll get a stack trace.
		<form wicket:id="form">
			<input type="text" wicket:id="testfield" name="txt" width="35" size="25" /><p>
			submit: <input type="submit" value="That's all, Folks!"/></p>
		</form>
		End of form.
	</div>
</div>
Test of Build Process.
</body>
</html>

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Resolved: (WICKET-1483) Unusual ClassCastException (SimpleAttributeModifier to IBehaviorListener) processing onError.

Posted by "Igor Vaynberg (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/WICKET-1483?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Igor Vaynberg resolved WICKET-1483.
-----------------------------------

       Resolution: Fixed
    Fix Version/s: 1.4-RC2
                   1.3.6

> Unusual ClassCastException (SimpleAttributeModifier to IBehaviorListener) processing onError.
> ---------------------------------------------------------------------------------------------
>
>                 Key: WICKET-1483
>                 URL: https://issues.apache.org/jira/browse/WICKET-1483
>             Project: Wicket
>          Issue Type: Bug
>          Components: wicket
>    Affects Versions: 1.3.0-final, 1.3.1, 1.3.2
>         Environment: Microsoft Windows XP [Version 5.1.2600] (Server & Client)
>            Reporter: Miguel Munoz
>            Assignee: Igor Vaynberg
>            Priority: Minor
>             Fix For: 1.3.6, 1.4-RC2
>
>         Attachments: wicket.behavior.patch
>
>   Original Estimate: 2h
>  Remaining Estimate: 2h
>
> Build the application from the four class files and one html file below. Run class Start as an application. Go to your browser, to this URL:
> http://localhost:4280/behaviorbug/
> Type some text into the text field. After six characters, it will throw a ClassCastException.
> Source:
> package com.bugs.behaviorBug;
> import org.apache.wicket.ajax.AjaxRequestTarget;
> import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
> import org.apache.wicket.behavior.SimpleAttributeModifier;
> import org.apache.wicket.markup.html.form.TextField;
> import org.apache.wicket.model.IModel;
> public class BehaviorBug extends TextField {
>   public BehaviorBug(String id, IModel model) {
>     super( id, model );
>     init();
>   }
>   private int kc = 0;
>   private int cc = 0;
>   private final SimpleAttributeModifier blackBorder = new SimpleAttributeModifier(
>       "border-color", "black" );
>   private final SimpleAttributeModifier redBorder = new SimpleAttributeModifier(
>       "border-color", "red" );
>   private SimpleAttributeModifier currentBorder = null;
>   private void init() {
>     setBorder( this.blackBorder );
>     AjaxFormComponentUpdatingBehavior changeWarningBehavior = new AjaxFormComponentUpdatingBehavior(
>         "onchange" ) {
>       @Override
>       protected void onUpdate(AjaxRequestTarget target) {
>         System.err.println( "WarningTextField onUpdate onChange "
>             + BehaviorBug.this.cc++ );
>         reColor();
>       }
>     };
>     // I'm trying to do something tricky here. I want it to validate after every
>     // keystroke, so the user can get instant feedback on when the data is good.
>     AjaxFormComponentUpdatingBehavior keyUpWarningBehavior = new AjaxFormComponentUpdatingBehavior(
>         "onkeyup" ) {
>       @Override
>       protected void onUpdate(AjaxRequestTarget target) {
>         System.err.println( "WarningTextField onUpdate onKeyUp "
>             + BehaviorBug.this.kc++ );
>         reColor();
>         // Thread.dumpStack();
>       }
>       // The implementation of AjaxFormComponentUpdatingBehavior only calls
>       // onUpdate
>       // when the field is valid. Since it won't update when the field is
>       // invalid, I
>       // can't get my instant feedback unless I call onUpdate() when there's an
>       // error.
>       // Since I can't override onEvent() (It's final), I override onError to
>       // force
>       // an update even when the field is invalid. This should be safe, since
>       // onError()
>       // is only called on invalid data with a null exception, in which case it
>       // does
>       // nothing.
>       // This, however, seems to be what causes the bug. I have no idea why this
>       // would cause the bug.
>       @Override
>       protected void onError(AjaxRequestTarget target, RuntimeException e) {
>         // Called on validation error with a null e.
>         super.onError( target, e ); // Throws e, if it's not null. Does nothing
>                                     // otherwise.
>         onUpdate( target );
>       }
>     };
>     add( changeWarningBehavior );
>     add( keyUpWarningBehavior );
>   }
>   private void reColor() {
>     if ( isValid() ) {
>       setBorder( BehaviorBug.this.blackBorder );
>     } else {
>       setBorder( BehaviorBug.this.redBorder );
>     }
>   }
>   private void setBorder(SimpleAttributeModifier border) {
>     if ( this.currentBorder != null && this.currentBorder != border ) {
>       remove( this.currentBorder );
>     }
>     this.currentBorder = border;
>     add( this.currentBorder );
>   }
> }
> package com.bugs.behaviorBug;
> import org.apache.wicket.Application;
> import org.apache.wicket.Page;
> import org.apache.wicket.Request;
> import org.apache.wicket.Response;
> import org.apache.wicket.Session;
> import org.apache.wicket.protocol.http.WebApplication;
> import org.apache.wicket.protocol.http.WebSession;
> /**
>  * 
>  * @author Miguel Muñoz
>  * @version $Id$
>  * 
>  */
> public class BehaviorBugApplication extends WebApplication {
>   /**
>    * Constructor
>    */
>   public BehaviorBugApplication() {
>     // empty
>   }
>   @Override
>   protected void init() {
>     // empty
>   }
>   @Override
>   public Class<? extends Page> getHomePage() {
>     return Index.class;
>   }
>   /*
>    * (non-Javadoc)
>    * 
>    * @see org.apache.wicket.protocol.http.WebApplication#newSession(org.apache.wicket.Request,
>    *      org.apache.wicket.Response)
>    */
>   @Override
>   public Session newSession(Request request, Response response) {
>     return new BugSession( this, request );
>   }
>   
>   public class BugSession extends WebSession {
>     public BugSession(Application application, Request request) {
>       super(request);
>       setApplication( application );
>     }
>   }
> }
> package com.bugs.behaviorBug;
> import org.apache.wicket.markup.html.WebPage;
> import org.apache.wicket.markup.html.form.Form;
> import org.apache.wicket.markup.html.form.TextField;
> import org.apache.wicket.model.Model;
> import org.apache.wicket.validation.IValidator;
> import org.apache.wicket.validation.validator.StringValidator;
> /**
>  * 
>  * @author Miguel Muñoz
>  * @version $Id$
>  * 
>  */
> public class Index extends WebPage {
>   /**
>    * 
>    */
>   public Index() {
>     Form form = new Form("form");
>     TextField textField = new BehaviorBug("testfield", new Model());
>     IValidator lengthValidator = new StringValidator.MaximumLengthValidator(4);
>     textField.add( lengthValidator );
>     form.add( textField );
>     add(form);
>   }
>   
> }
> package com.bugs.behaviorBug;
> import org.mortbay.jetty.Connector;
> import org.mortbay.jetty.Server;
> import org.mortbay.jetty.nio.SelectChannelConnector;
> import org.mortbay.jetty.webapp.WebAppContext;
> /**
>  * 
>  * @author Miguel Muñoz
>  * @version $Id$
>  * 
>  */
> public class Start {
>   private static final int defaultPort = 4280;
>   /**
>    * 
>    * @param args
>    */
>   public static void main(String[] args) {
>     int port = defaultPort;
>     if (args.length != 0) {
>       try {
>         port = Integer.valueOf( args[0] );
>       } catch ( NumberFormatException e ) {
>         System.err.println("Unable to parse port parameter \"" + args[0] + "\" as an integer.");
>         System.err.println("Using default value of x " + defaultPort);
>       }
>     }
>     Server server = new Server();
>     SelectChannelConnector connector = new SelectChannelConnector();
>     connector.setPort( port );
>     server.setConnectors( new Connector[] { connector } );
>     WebAppContext web = new WebAppContext();
> //    web.setContextPath( "/workspace/WicketTutorial" );
>     web.setContextPath( "/behaviorbug" );
>     System.out.println( "CP: " + web.getContextPath() );
>     web.setWar( "src/main/webapp" + port );
>     server.addHandler( web );
>     
>     try {
>       server.start(); // Who was the bozo who declared this to throw Exception?
>       server.join();
>     } catch ( Exception e ) {
>       e.printStackTrace();
>       System.exit( 1 );
>     }
>   }
> }
> <html>
> <head>
> <title>Behavior Bug</title>
> <link href="style.css" rel="stylesheet" />
> </head>
> <body>
> <div id="container">
> 	<div id="header">Behavior Bug</div>
> 	<div id="content">
> 		Type some text into the field below. After six characters, you'll get a stack trace.
> 		<form wicket:id="form">
> 			<input type="text" wicket:id="testfield" name="txt" width="35" size="25" /><p>
> 			submit: <input type="submit" value="That's all, Folks!"/></p>
> 		</form>
> 		End of form.
> 	</div>
> </div>
> Test of Build Process.
> </body>
> </html>

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Updated: (WICKET-1483) Unusual ClassCastException (SimpleAttributeModifier to IBehaviorListener) processing onError.

Posted by "Igor Vaynberg (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/WICKET-1483?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Igor Vaynberg updated WICKET-1483:
----------------------------------

    Attachment: wicket.behavior.patch

attaching patch that fixes the problem by leaving null entries in ibehavior[] to preserve indexes

> Unusual ClassCastException (SimpleAttributeModifier to IBehaviorListener) processing onError.
> ---------------------------------------------------------------------------------------------
>
>                 Key: WICKET-1483
>                 URL: https://issues.apache.org/jira/browse/WICKET-1483
>             Project: Wicket
>          Issue Type: Bug
>          Components: wicket
>    Affects Versions: 1.3.0-final, 1.3.1, 1.3.2
>         Environment: Microsoft Windows XP [Version 5.1.2600] (Server & Client)
>            Reporter: Miguel Munoz
>            Assignee: Igor Vaynberg
>            Priority: Minor
>         Attachments: wicket.behavior.patch
>
>   Original Estimate: 2h
>  Remaining Estimate: 2h
>
> Build the application from the four class files and one html file below. Run class Start as an application. Go to your browser, to this URL:
> http://localhost:4280/behaviorbug/
> Type some text into the text field. After six characters, it will throw a ClassCastException.
> Source:
> package com.bugs.behaviorBug;
> import org.apache.wicket.ajax.AjaxRequestTarget;
> import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
> import org.apache.wicket.behavior.SimpleAttributeModifier;
> import org.apache.wicket.markup.html.form.TextField;
> import org.apache.wicket.model.IModel;
> public class BehaviorBug extends TextField {
>   public BehaviorBug(String id, IModel model) {
>     super( id, model );
>     init();
>   }
>   private int kc = 0;
>   private int cc = 0;
>   private final SimpleAttributeModifier blackBorder = new SimpleAttributeModifier(
>       "border-color", "black" );
>   private final SimpleAttributeModifier redBorder = new SimpleAttributeModifier(
>       "border-color", "red" );
>   private SimpleAttributeModifier currentBorder = null;
>   private void init() {
>     setBorder( this.blackBorder );
>     AjaxFormComponentUpdatingBehavior changeWarningBehavior = new AjaxFormComponentUpdatingBehavior(
>         "onchange" ) {
>       @Override
>       protected void onUpdate(AjaxRequestTarget target) {
>         System.err.println( "WarningTextField onUpdate onChange "
>             + BehaviorBug.this.cc++ );
>         reColor();
>       }
>     };
>     // I'm trying to do something tricky here. I want it to validate after every
>     // keystroke, so the user can get instant feedback on when the data is good.
>     AjaxFormComponentUpdatingBehavior keyUpWarningBehavior = new AjaxFormComponentUpdatingBehavior(
>         "onkeyup" ) {
>       @Override
>       protected void onUpdate(AjaxRequestTarget target) {
>         System.err.println( "WarningTextField onUpdate onKeyUp "
>             + BehaviorBug.this.kc++ );
>         reColor();
>         // Thread.dumpStack();
>       }
>       // The implementation of AjaxFormComponentUpdatingBehavior only calls
>       // onUpdate
>       // when the field is valid. Since it won't update when the field is
>       // invalid, I
>       // can't get my instant feedback unless I call onUpdate() when there's an
>       // error.
>       // Since I can't override onEvent() (It's final), I override onError to
>       // force
>       // an update even when the field is invalid. This should be safe, since
>       // onError()
>       // is only called on invalid data with a null exception, in which case it
>       // does
>       // nothing.
>       // This, however, seems to be what causes the bug. I have no idea why this
>       // would cause the bug.
>       @Override
>       protected void onError(AjaxRequestTarget target, RuntimeException e) {
>         // Called on validation error with a null e.
>         super.onError( target, e ); // Throws e, if it's not null. Does nothing
>                                     // otherwise.
>         onUpdate( target );
>       }
>     };
>     add( changeWarningBehavior );
>     add( keyUpWarningBehavior );
>   }
>   private void reColor() {
>     if ( isValid() ) {
>       setBorder( BehaviorBug.this.blackBorder );
>     } else {
>       setBorder( BehaviorBug.this.redBorder );
>     }
>   }
>   private void setBorder(SimpleAttributeModifier border) {
>     if ( this.currentBorder != null && this.currentBorder != border ) {
>       remove( this.currentBorder );
>     }
>     this.currentBorder = border;
>     add( this.currentBorder );
>   }
> }
> package com.bugs.behaviorBug;
> import org.apache.wicket.Application;
> import org.apache.wicket.Page;
> import org.apache.wicket.Request;
> import org.apache.wicket.Response;
> import org.apache.wicket.Session;
> import org.apache.wicket.protocol.http.WebApplication;
> import org.apache.wicket.protocol.http.WebSession;
> /**
>  * 
>  * @author Miguel Muñoz
>  * @version $Id$
>  * 
>  */
> public class BehaviorBugApplication extends WebApplication {
>   /**
>    * Constructor
>    */
>   public BehaviorBugApplication() {
>     // empty
>   }
>   @Override
>   protected void init() {
>     // empty
>   }
>   @Override
>   public Class<? extends Page> getHomePage() {
>     return Index.class;
>   }
>   /*
>    * (non-Javadoc)
>    * 
>    * @see org.apache.wicket.protocol.http.WebApplication#newSession(org.apache.wicket.Request,
>    *      org.apache.wicket.Response)
>    */
>   @Override
>   public Session newSession(Request request, Response response) {
>     return new BugSession( this, request );
>   }
>   
>   public class BugSession extends WebSession {
>     public BugSession(Application application, Request request) {
>       super(request);
>       setApplication( application );
>     }
>   }
> }
> package com.bugs.behaviorBug;
> import org.apache.wicket.markup.html.WebPage;
> import org.apache.wicket.markup.html.form.Form;
> import org.apache.wicket.markup.html.form.TextField;
> import org.apache.wicket.model.Model;
> import org.apache.wicket.validation.IValidator;
> import org.apache.wicket.validation.validator.StringValidator;
> /**
>  * 
>  * @author Miguel Muñoz
>  * @version $Id$
>  * 
>  */
> public class Index extends WebPage {
>   /**
>    * 
>    */
>   public Index() {
>     Form form = new Form("form");
>     TextField textField = new BehaviorBug("testfield", new Model());
>     IValidator lengthValidator = new StringValidator.MaximumLengthValidator(4);
>     textField.add( lengthValidator );
>     form.add( textField );
>     add(form);
>   }
>   
> }
> package com.bugs.behaviorBug;
> import org.mortbay.jetty.Connector;
> import org.mortbay.jetty.Server;
> import org.mortbay.jetty.nio.SelectChannelConnector;
> import org.mortbay.jetty.webapp.WebAppContext;
> /**
>  * 
>  * @author Miguel Muñoz
>  * @version $Id$
>  * 
>  */
> public class Start {
>   private static final int defaultPort = 4280;
>   /**
>    * 
>    * @param args
>    */
>   public static void main(String[] args) {
>     int port = defaultPort;
>     if (args.length != 0) {
>       try {
>         port = Integer.valueOf( args[0] );
>       } catch ( NumberFormatException e ) {
>         System.err.println("Unable to parse port parameter \"" + args[0] + "\" as an integer.");
>         System.err.println("Using default value of x " + defaultPort);
>       }
>     }
>     Server server = new Server();
>     SelectChannelConnector connector = new SelectChannelConnector();
>     connector.setPort( port );
>     server.setConnectors( new Connector[] { connector } );
>     WebAppContext web = new WebAppContext();
> //    web.setContextPath( "/workspace/WicketTutorial" );
>     web.setContextPath( "/behaviorbug" );
>     System.out.println( "CP: " + web.getContextPath() );
>     web.setWar( "src/main/webapp" + port );
>     server.addHandler( web );
>     
>     try {
>       server.start(); // Who was the bozo who declared this to throw Exception?
>       server.join();
>     } catch ( Exception e ) {
>       e.printStackTrace();
>       System.exit( 1 );
>     }
>   }
> }
> <html>
> <head>
> <title>Behavior Bug</title>
> <link href="style.css" rel="stylesheet" />
> </head>
> <body>
> <div id="container">
> 	<div id="header">Behavior Bug</div>
> 	<div id="content">
> 		Type some text into the field below. After six characters, you'll get a stack trace.
> 		<form wicket:id="form">
> 			<input type="text" wicket:id="testfield" name="txt" width="35" size="25" /><p>
> 			submit: <input type="submit" value="That's all, Folks!"/></p>
> 		</form>
> 		End of form.
> 	</div>
> </div>
> Test of Build Process.
> </body>
> </html>

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Assigned: (WICKET-1483) Unusual ClassCastException (SimpleAttributeModifier to IBehaviorListener) processing onError.

Posted by "Igor Vaynberg (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/WICKET-1483?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Igor Vaynberg reassigned WICKET-1483:
-------------------------------------

    Assignee: Igor Vaynberg

> Unusual ClassCastException (SimpleAttributeModifier to IBehaviorListener) processing onError.
> ---------------------------------------------------------------------------------------------
>
>                 Key: WICKET-1483
>                 URL: https://issues.apache.org/jira/browse/WICKET-1483
>             Project: Wicket
>          Issue Type: Bug
>          Components: wicket
>    Affects Versions: 1.3.0-final, 1.3.1, 1.3.2
>         Environment: Microsoft Windows XP [Version 5.1.2600] (Server & Client)
>            Reporter: Miguel Munoz
>            Assignee: Igor Vaynberg
>            Priority: Minor
>   Original Estimate: 2h
>  Remaining Estimate: 2h
>
> Build the application from the four class files and one html file below. Run class Start as an application. Go to your browser, to this URL:
> http://localhost:4280/behaviorbug/
> Type some text into the text field. After six characters, it will throw a ClassCastException.
> Source:
> package com.bugs.behaviorBug;
> import org.apache.wicket.ajax.AjaxRequestTarget;
> import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
> import org.apache.wicket.behavior.SimpleAttributeModifier;
> import org.apache.wicket.markup.html.form.TextField;
> import org.apache.wicket.model.IModel;
> public class BehaviorBug extends TextField {
>   public BehaviorBug(String id, IModel model) {
>     super( id, model );
>     init();
>   }
>   private int kc = 0;
>   private int cc = 0;
>   private final SimpleAttributeModifier blackBorder = new SimpleAttributeModifier(
>       "border-color", "black" );
>   private final SimpleAttributeModifier redBorder = new SimpleAttributeModifier(
>       "border-color", "red" );
>   private SimpleAttributeModifier currentBorder = null;
>   private void init() {
>     setBorder( this.blackBorder );
>     AjaxFormComponentUpdatingBehavior changeWarningBehavior = new AjaxFormComponentUpdatingBehavior(
>         "onchange" ) {
>       @Override
>       protected void onUpdate(AjaxRequestTarget target) {
>         System.err.println( "WarningTextField onUpdate onChange "
>             + BehaviorBug.this.cc++ );
>         reColor();
>       }
>     };
>     // I'm trying to do something tricky here. I want it to validate after every
>     // keystroke, so the user can get instant feedback on when the data is good.
>     AjaxFormComponentUpdatingBehavior keyUpWarningBehavior = new AjaxFormComponentUpdatingBehavior(
>         "onkeyup" ) {
>       @Override
>       protected void onUpdate(AjaxRequestTarget target) {
>         System.err.println( "WarningTextField onUpdate onKeyUp "
>             + BehaviorBug.this.kc++ );
>         reColor();
>         // Thread.dumpStack();
>       }
>       // The implementation of AjaxFormComponentUpdatingBehavior only calls
>       // onUpdate
>       // when the field is valid. Since it won't update when the field is
>       // invalid, I
>       // can't get my instant feedback unless I call onUpdate() when there's an
>       // error.
>       // Since I can't override onEvent() (It's final), I override onError to
>       // force
>       // an update even when the field is invalid. This should be safe, since
>       // onError()
>       // is only called on invalid data with a null exception, in which case it
>       // does
>       // nothing.
>       // This, however, seems to be what causes the bug. I have no idea why this
>       // would cause the bug.
>       @Override
>       protected void onError(AjaxRequestTarget target, RuntimeException e) {
>         // Called on validation error with a null e.
>         super.onError( target, e ); // Throws e, if it's not null. Does nothing
>                                     // otherwise.
>         onUpdate( target );
>       }
>     };
>     add( changeWarningBehavior );
>     add( keyUpWarningBehavior );
>   }
>   private void reColor() {
>     if ( isValid() ) {
>       setBorder( BehaviorBug.this.blackBorder );
>     } else {
>       setBorder( BehaviorBug.this.redBorder );
>     }
>   }
>   private void setBorder(SimpleAttributeModifier border) {
>     if ( this.currentBorder != null && this.currentBorder != border ) {
>       remove( this.currentBorder );
>     }
>     this.currentBorder = border;
>     add( this.currentBorder );
>   }
> }
> package com.bugs.behaviorBug;
> import org.apache.wicket.Application;
> import org.apache.wicket.Page;
> import org.apache.wicket.Request;
> import org.apache.wicket.Response;
> import org.apache.wicket.Session;
> import org.apache.wicket.protocol.http.WebApplication;
> import org.apache.wicket.protocol.http.WebSession;
> /**
>  * 
>  * @author Miguel Muñoz
>  * @version $Id$
>  * 
>  */
> public class BehaviorBugApplication extends WebApplication {
>   /**
>    * Constructor
>    */
>   public BehaviorBugApplication() {
>     // empty
>   }
>   @Override
>   protected void init() {
>     // empty
>   }
>   @Override
>   public Class<? extends Page> getHomePage() {
>     return Index.class;
>   }
>   /*
>    * (non-Javadoc)
>    * 
>    * @see org.apache.wicket.protocol.http.WebApplication#newSession(org.apache.wicket.Request,
>    *      org.apache.wicket.Response)
>    */
>   @Override
>   public Session newSession(Request request, Response response) {
>     return new BugSession( this, request );
>   }
>   
>   public class BugSession extends WebSession {
>     public BugSession(Application application, Request request) {
>       super(request);
>       setApplication( application );
>     }
>   }
> }
> package com.bugs.behaviorBug;
> import org.apache.wicket.markup.html.WebPage;
> import org.apache.wicket.markup.html.form.Form;
> import org.apache.wicket.markup.html.form.TextField;
> import org.apache.wicket.model.Model;
> import org.apache.wicket.validation.IValidator;
> import org.apache.wicket.validation.validator.StringValidator;
> /**
>  * 
>  * @author Miguel Muñoz
>  * @version $Id$
>  * 
>  */
> public class Index extends WebPage {
>   /**
>    * 
>    */
>   public Index() {
>     Form form = new Form("form");
>     TextField textField = new BehaviorBug("testfield", new Model());
>     IValidator lengthValidator = new StringValidator.MaximumLengthValidator(4);
>     textField.add( lengthValidator );
>     form.add( textField );
>     add(form);
>   }
>   
> }
> package com.bugs.behaviorBug;
> import org.mortbay.jetty.Connector;
> import org.mortbay.jetty.Server;
> import org.mortbay.jetty.nio.SelectChannelConnector;
> import org.mortbay.jetty.webapp.WebAppContext;
> /**
>  * 
>  * @author Miguel Muñoz
>  * @version $Id$
>  * 
>  */
> public class Start {
>   private static final int defaultPort = 4280;
>   /**
>    * 
>    * @param args
>    */
>   public static void main(String[] args) {
>     int port = defaultPort;
>     if (args.length != 0) {
>       try {
>         port = Integer.valueOf( args[0] );
>       } catch ( NumberFormatException e ) {
>         System.err.println("Unable to parse port parameter \"" + args[0] + "\" as an integer.");
>         System.err.println("Using default value of x " + defaultPort);
>       }
>     }
>     Server server = new Server();
>     SelectChannelConnector connector = new SelectChannelConnector();
>     connector.setPort( port );
>     server.setConnectors( new Connector[] { connector } );
>     WebAppContext web = new WebAppContext();
> //    web.setContextPath( "/workspace/WicketTutorial" );
>     web.setContextPath( "/behaviorbug" );
>     System.out.println( "CP: " + web.getContextPath() );
>     web.setWar( "src/main/webapp" + port );
>     server.addHandler( web );
>     
>     try {
>       server.start(); // Who was the bozo who declared this to throw Exception?
>       server.join();
>     } catch ( Exception e ) {
>       e.printStackTrace();
>       System.exit( 1 );
>     }
>   }
> }
> <html>
> <head>
> <title>Behavior Bug</title>
> <link href="style.css" rel="stylesheet" />
> </head>
> <body>
> <div id="container">
> 	<div id="header">Behavior Bug</div>
> 	<div id="content">
> 		Type some text into the field below. After six characters, you'll get a stack trace.
> 		<form wicket:id="form">
> 			<input type="text" wicket:id="testfield" name="txt" width="35" size="25" /><p>
> 			submit: <input type="submit" value="That's all, Folks!"/></p>
> 		</form>
> 		End of form.
> 	</div>
> </div>
> Test of Build Process.
> </body>
> </html>

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.