<!--
   Licensed to the Apache Software Foundation (ASF) under one
   or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
   regarding copyright ownership.  The ASF licenses this file
   to you under the Apache License, Version 2.0 (the
   "License"); you may not use this file except in compliance
   with the License.  You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing,
   software distributed under the License is distributed on an
   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   KIND, either express or implied.  See the License for the
   specific language governing permissions and limitations
   under the License.
-->
<html><head><title>Error Page</title>

<style>
body, table, td {
  font-family: arial, sans-serif;
  font-size: 12px;
}
td.header {
  color: white;
  background: navy;
}
.errorReport {
  display: none;
}
</style>
<script type="text/javascript">
function displayError() {
  errorReport.style.display = 'block';
}
</script></head>
<body>
 <h1>Error Page</h1>
 
 The application encountered an unexpected error.
 <p>
 
    To view error details click <a href="#" onclick="displayError();">here</a>.
   </p><p>
   </p><div style="display: block;" id="errorReport" class="errorReport">
<table border="1" cellpadding="4" cellspacing="1" width="100%"><tbody><tr><td colspan="2" style="color: white; background-color: navy; font-weight: bold;">Exception</td></tr><tr><td width="12%"><b>Class</b></td><td>java.lang.NullPointerException</td></tr><tr><td valign="top" width="12%"><b>Message</b></td><td>null</td></tr><tr><td colspan="2" valign="top">
<pre style="font-family: Courier New,courier;"><div> 33:          brokenBorderLink.setListener(this, "onBrokenBorderClick");</div><div> 34:          addControl(brokenBorderLink);</div><div> 35:  </div><div> 36:          ActionLink brokenContentLink = <span style="color: rgb(127, 0, 85); font-weight: bold;">new</span> ActionLink("brokenContentLink");</div><div> 37:          brokenContentLink.setListener(this, "onBrokenContentClick");</div><div> 38:          addControl(brokenContentLink);</div><div> 39:      }</div><div> 40:  </div><div> 41:      <span style="color: rgb(127, 0, 85); font-weight: bold;">public</span> <span style="color: rgb(127, 0, 85); font-weight: bold;">boolean</span> onNullPointerClick() {</div><div> 42:          Object object = null;</div><div style="background-color: yellow;"> <b>43</b>:          object.hashCode();</div><div> 44:          <span style="color: rgb(127, 0, 85); font-weight: bold;">return</span> <span style="color: rgb(127, 0, 85); font-weight: bold;">true;</span></div><div> 45:      }</div><div> 46:  </div><div> 47:      <span style="color: rgb(127, 0, 85); font-weight: bold;">public</span> <span style="color: rgb(127, 0, 85); font-weight: bold;">boolean</span> onBrokenRendererClick() {</div><div> 48:          addModel("brokenRenderer", <span style="color: rgb(127, 0, 85); font-weight: bold;">new</span> BrokenRenderer());</div><div> 49:          <span style="color: rgb(127, 0, 85); font-weight: bold;">return</span> <span style="color: rgb(127, 0, 85); font-weight: bold;">true;</span></div><div> 50:      }</div><div> 51:  </div><div> 52:      <span style="color: rgb(127, 0, 85); font-weight: bold;">public</span> <span style="color: rgb(127, 0, 85); font-weight: bold;">boolean</span> onBrokenBorderClick() {</div><div> 53:          setPath("broken-border.htm");</div></pre></td></tr><tr><td colspan="2" valign="top">
<pre><tt style="font-size: 10pt;">java.lang.NullPointerException
	at examples.page.ExceptionDemo.onNullPointerClick(ExceptionDemo.java:43)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:324)
	at org.apache.click.util.ClickUtils.invokeListener(ClickUtils.java:188)
	at org.apache.click.control.ActionLink.onProcess(ActionLink.java:510)
	at org.apache.click.ClickServlet.processPage(ClickServlet.java:324)
	at org.apache.click.ClickServlet.handleRequest(ClickServlet.java:210)
	at org.apache.click.ClickServlet.doGet(ClickServlet.java:154)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:744)
	at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
	at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
	at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
	at java.lang.Thread.run(Thread.java:534)</tt></pre></td></tr></tbody></table><br><table border="1" cellpadding="4" cellspacing="1" width="100%"><tbody><tr><td colspan="2" style="color: white; background-color: navy; font-weight: bold;">Page</td></tr><tr><td width="12%"><b>Classname</b></td><td>examples.page.ExceptionDemo</td></tr><tr><td width="12%"><b>Path</b></td><td>exception.htm</td></tr><tr><td><b width="12%">Template</b></td><td>border.htm</td></tr></tbody></table><br><table border="1" cellpadding="4" cellspacing="1" width="100%"><tbody><tr><td colspan="2" style="color: white; background-color: navy; font-weight: bold;">Request</td></tr><tr><td valign="top" width="12%"><b>Attributes</b></td><td>&nbsp;</td></tr><tr><td width="12%"><b>Auth Type</b></td><td>null</td></tr><tr><td width="12%"><b>Context Path</b></td><td><a href="http://localhost:8080/click-examples">/click-examples</a></td></tr><tr><td valign="top" width="12%"><b>Headers</b></td><td>accept=text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5<br>accept-charset=ISO-8859-1,utf-8;q=0.7,*;q=0.7<br>accept-encoding=gzip,deflate<br>accept-language=en-us,en;q=0.5<br>connection=keep-alive<br>host=localhost:8080<br>keep-alive=300<br>referer=http://localhost:8080/click-examples/exception.htm<br>user-agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.7) Gecko/20050414 Firefox/1.0.3<br></td></tr><tr><td width="12%"><b>Query</b></td><td>actionLink=nullPointerLink</td></tr><tr><td width="12%"><b>Method</b></td><td>GET</td></tr><tr><td valign="top" width="12%"><b>Parameters</b></td><td>actionLink=nullPointerLink<br></td></tr><tr><td width="12%"><b>Remote User</b></td><td>null</td></tr><tr><td valign="top" width="12%"><b>URI</b></td><td><a href="http://localhost:8080/click-examples/exception.htm">/click-examples/exception.htm</a></td></tr><tr><td><b width="12%">URL</b></td><td><a href="http://localhost:8080/click-examples/exception.htm">http://localhost:8080/click-examples/exception.htm</a></td></tr><tr><td valign="top" width="12%"><b>Session</b></td><td>&nbsp;</td></tr></tbody></table>
</div>

 
</body></html>