Jsp loading problem.

Hi,

I am having this problem with my jsp page:

I can load the page without any problems. There is a submit button which I can click to load the records of a table. It is also working fine.

However, after the table records are loaded, if I click on any button, including the "submit" button i clicked earlier, it will throw the following exception.

I have println statements in my Action class, but none of them is printed when this error appears.

I'll post the jsp file in the following-up post. Thanks in advance.

java.lang.ArrayIndexOutOfBoundsException

at java.lang.reflect.Array.get(Native Method)

at org.apache.struts.action.DynaActionForm.get(DynaActionForm.java:296)

at org.apache.commons.beanutils.PropertyUtils.getIndexedProperty(PropertyUtils.java:474)

at org.apache.commons.beanutils.PropertyUtils.getIndexedProperty(PropertyUtils.java:428)

at org.apache.commons.beanutils.PropertyUtils.getNestedProperty(PropertyUtils.java:770)

at org.apache.commons.beanutils.PropertyUtils.getProperty(PropertyUtils.java:801)

at org.apache.commons.beanutils.BeanUtils.setProperty(BeanUtils.java:881)

at org.apache.commons.beanutils.BeanUtils.populate(BeanUtils.java:808)

at org.apache.struts.util.RequestUtils.populate(RequestUtils.java:1252)

at org.apache.struts.action.RequestProcessor.processPopulate(RequestProcessor.java:821)

at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:254)

at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482)

at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:525)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)

at com.evermind[Oracle Application Server Containers for J2EE 10g (9.0.4.0.0)].server.http.ResourceFilterChain.doFilter(ResourceFilterChain.java:65)

at com.yellowpages.ids.common.web.LoggerFilter.doFilter(LoggerFilter.java:47)

at com.evermind[Oracle Application Server Containers for J2EE 10g (9.0.4.0.0)].server.http.EvermindFilterChain.doFilter(EvermindFilterChain.java:16)

at com.yellowpages.ids.common.web.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:135)

at com.evermind[Oracle Application Server Containers for J2EE 10g (9.0.4.0.0)].server.http.ServletRequestDispatcher.invoke(ServletRequestDispatcher.java:600)

at com.evermind[Oracle Application Server Containers for J2EE 10g (9.0.4.0.0)].server.http.ServletRequestDispatcher.forwardInternal(ServletRequestDispatcher.java:317)

at com.evermind[Oracle Application Server Containers for J2EE 10g (9.0.4.0.0)].server.http.HttpRequestHandler.processRequest(HttpRequestHandler.java:790)

at com.evermind[Oracle Application Server Containers for J2EE 10g (9.0.4.0.0)].server.http.HttpRequestHandler.run(HttpRequestHandler.java:270)

at com.evermind[Oracle Application Server Containers for J2EE 10g (9.0.4.0.0)].server.http.HttpRequestHandler.run(HttpRequestHandler.java:112)

at com.evermind[Oracle Application Server Containers for J2EE 10g (9.0.4.0.0)].util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.java:192)

at java.lang.Thread.run(Thread.java:534)

[3345 byte] By [thewarrencluba] at [2007-11-26 15:27:26]
# 1

[nobr]This is the jsp code. (I know some of the code does not conform to good practice. This is just the development stage.)

Ya, another problem is:

why the <%=ind.intValue()%> method in the <nested:iterate> block does not pass in its integer value, but instead this string "<%=ind.intValue()%>" itself to the javascript? I am confused with this one too, because I remember it worked on my applications I have done some time ago.

Thanks for the help. I am really stuck here. If u need my Action class code, I can post here too.

<%@ taglib uri="/WEB-INF/struts-nested.tld" prefix="nested" %>

<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>

<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html:html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

<title><bean:message bundle="labels" key="AMS"/></title>

<link href="/ids/fonts.css" rel="stylesheet" type="text/css" />

<script language="javascript">

function retrieveDirSrss(){

document.ams2mForm.method.value = 'retrieveDirSrss';

document.ams2mForm.submit();

}

function updateRecord( ind ){

alert('array index ' + ind );

document.ams2mForm.modIndex.value = ind;

document.ams2mForm.method.value = 'updateRecord';

document.ams2mForm.submit();

}

function deleteRecord( ind ){

alert('array index ' + ind );

document.ams2mForm.modIndex.value = ind;

document.ams2mForm.method.value = 'deleteRecord';

document.ams2mForm.submit();

}

function insertRecord(){

document.ams2mForm.method.value = 'insertRecord';

document.ams2mForm.submit();

}

function cancelDirSrss(){

alert( "cancel the screen" );

document.ams2mForm.method.value = 'cancelDirSrss';

document.ams2mForm.submit();

}

function lookupEmployee( f, ind ){

alert("The index is " + ind );

window.open( '../ams/ams2mAction.do?method=loadEmployee&initial='+f.value+'&ind='+ind,

'Employees',

'width=600,height=300,resizable=yes,scrollbars=yes,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no' );

}

</script>

</head>

<body>

<nested:form action="/ams2mAction">

<nested:hidden property="method"/>

<nested:hidden property="modIndex"/>

<nested:define id="dirCol" property="dirCol" type="com.vo.AccountRefVO[]"/>

<nested:define id="srssCol" property="srssAssCol" type="com.vo.SRSSAssignmentVO[]"/>

<table width="700" border="0" cellspacing="1" cellpadding="1">

<tr>

<td width="110"><h1><bean:message bundle="labels" key="AMS2_M"/></h1></td>

<td width="590"><h1 align="center"><bean:message bundle="labels" key="AMS"/></h1></td>

</tr>

<tr>

<td> </td>

<td><h1 align="center"><bean:message bundle="labels" key="AMS2_M_HDR"/></h1></td>

</tr>

</table>

<br/>

<table width="700" border="0" cellspacing="1" cellpadding="1">

<tr>

<td width="80" class="label"><bean:message bundle="labels" key="DIRECTORY"/></td>

<td width="463">

<nested:select property="publ_id">

<html:option value=""> </html:option>

<%

if( dirCol == null )

System.err.println("JSP: is dirCol null? " + (dirCol == null) );

else{

System.err.println("JSP: length of dirCol : " + dirCol.length );

}

for( int i = 0; i < dirCol.length; ++i ){ %>

<%--html:option value="<%=dirCol[i].getDirectoryGroup()%>"><%=dirCol[i].getRefCode()%>-<%=dirCol[i].getRefDesc()%></html:option--%>

<html:option value="<%=dirCol[i].getDirectoryGroup()%>"><%=dirCol[i].getRefDesc()%></html:option>

<%}// end for block%>

</nested:select>

</td>

<td width="157">

<div align="right">

<nested:image src="images/button-submit.gif" onclick="retrieveDirSrss()" alt="retrieve directory records"/>

</div></td>

</tr>

</table>

<br/>

<% if( srssCol.length > 0 ){%>

<table width="700" border="0" cellpadding="1" cellspacing="1" class="result">

<tr>

<th width="245" class="label"><div align="left"><bean:message bundle="labels" key="SALESREP"/></div></th>

<th width="245" class="label"><div align="left"><bean:message bundle="labels" key="SS_STAFF"/></div></th>

<th width="70" class="label"><div align="left"><bean:message bundle="labels" key="OPERATOR"/></div></th>

<th width="90" class="label"><div align="left"><bean:message bundle="labels" key="LAST_UPDATE"/></div></th>

<th width="50"><div align="left"></div></th>

</tr>

<nested:iterate property="srssAssCol" indexId="ind">

<tr>

<td><nested:text styleClass="readonly" readonly="true" maxlength="30" property="salesrepName" size="31"/></td>

<td><nested:text maxlength="30" property="ssName" size="31"/><nested:image src="images/button-lov.gif" onclick="lookupEmployee(document.ams2mForm.srssAssCol[<%=ind.intValue()%>].ssName, '<%=ind.intValue()%>');"/></td>

<td><nested:write property="operator"/></td>

<td><nested:write property="lastUpdateStr"/></td>

<td>

<nested:image src="images/icon-pencil.gif" onclick="updateRecord('<%=ind.intValue()%>')" alt="update the record"/>

<nested:image src="images/icon-trashbin.gif" onclick="deleteRecord('<%=ind.intValue()%>')" alt="delete the record"/>

</td>

</tr>

</nested:iterate>

<tr>

<td><nested:text maxlength="30" property="salesrep_no" size="31"/><nested:image src="images/button-lov.gif" onclick="lookupEmployee();"/></td>

<td><nested:text maxlength="30" property="salesService" size="31"/><nested:image src="images/button-lov.gif" onclick="lookupEmployee();"/></td>

<td> </td>

<td> </td>

<td><nested:image src="images/icon-addnew.gif" onclick="insertRecord()" alt="Add the record"/></td>

</tr>

</table>

<table width="700" border="0" cellspacing="1" cellpadding="1">

<tr>

<td> </td>

<td><div align="right">

<nested:image src="images/button-cancel.gif" onclick="cancelDirSrss()" alt="cancel the records from this directory"/>

</div></td>

</tr>

</table>

<%}%>

</nested:form>

</body>

</html:html>

Message was edited by:

thewarrenclub:

removed sensitive information.

Message was edited by:

thewarrenclub

Message was edited by:

thewarrenclub[/nobr]

thewarrencluba at 2007-7-8 21:43:20 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 2

>why the <%=ind.intValue()%> method in the <nested:iterate> block does not pass in its integer value, but instead this string "<%=ind.intValue()%>" itself to the javascript?

you pass the parameter inside quotes. So it is passed as a string.

onclick="updateRecord('<%=ind.intValue()%>')"

Try this

onclick="updateRecord(<%=ind.intValue()%>)"

(didnt check)

kalania at 2007-7-8 21:43:20 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 3
I tried this. The browser even complains javascript syntax error without the quote.
thewarrencluba at 2007-7-8 21:43:20 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 4

so why dont you use it inside the javascript itself?

first, in your jsp code, assign that value to a variable(say num) by calling intValue()

then

function updateRecord( ){

var number = <%=num%>;

alert('array index ' + number );

document.ams2mForm.modIndex.value = number;

document.ams2mForm.method.value = 'updateRecord';

document.ams2mForm.submit();

}

onclick="updateRecord()"

this should be possible

kalania at 2007-7-8 21:43:20 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 5
Hi,I tried this way, but unfortunately it is possible, because the variable is the index of a loop, its value always changing. I have to pass the index to the parameter of the javascript function, otherwise the index will have been changed or out of scope.
thewarrencluba at 2007-7-8 21:43:20 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 6
I cant understand why is it a problem.here u call the intValue() method and assign the returned value to a variable, before the javascript function being called. so inside the function u access that value itself, not a changed value.I cant think another way to do that
kalania at 2007-7-8 21:43:20 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 7

OK. I'll try your method.

but this is a minor problem compared to the ArrayIndexOutOfBoundsException i got.

The problem is, it throws this exception, but none of the log messages in my Action class is printed. Not even the message I put at the first line of the method.

I really can't find where it is from.

thewarrencluba at 2007-7-8 21:43:20 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 8

Couple of ideas to hopefully push you in the right direction.

First the <%=ind.intValue()%> issue.

When you want a struts tag attribute to be dynamic, it must be wholely dynamic. ie <tag attribute="<%= theEntireExpression %>"/> rather than <tag attribute="static<%=dynamic%>"/>

To use a simpler example than you have in the code consider if you wanted to make the src of the image dynamic:

The following is logical but incorrect:

<nested:image src= "images/<%= imageName%>"/>

Instead the entire value for the attribute must be dynamic - ie between <%= %>

This will work:

<nested:image src= "<%="images/" + imageName%>"/>

Some servers have issues with nesting quotes like this, so I normally use single quotes on the outer delimiters

ie: <nested:image src='<%="images/" + imageName%>'/>

Applying that to your code, you will see you have to make the entire onlick event a string expression:

<nested:image src="images/button-lov.gif" onclick='<%= "lookupEmployee(document.ams2mForm.srssAssCol[" + ind.intValue() + "].ssName, '" + ind.intValue() + ");" %>'/></td>

hmm - I'm not entirely certain the above will work as you have single quotes nested within the double quotes nested within a third set of quotes, but hopefully you see my point.

If that doesn't work you may have to break it into two steps such as

<%

String onclickEvent = "lookupEmployee(document.ams2mForm.srssAssCol[" + ind.intValue() + "].ssName, '" + ind.intValue() + ");";

%>

<nested:image src="images/button-lov.gif" onclick=' <%= onclickEvent %>'/>

disclaimer: scriptlet code used for example purposes only.

evnafetsa at 2007-7-8 21:43:20 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 9

Ok, the ArrayIndexOutOfBounds exception.

This is being thrown from the population phase of struts - when it is setting the request parameters into your action form.

Hence it is failing before it comes anywhere near your code ;-)

From the stack trace, you seem to be using a DynaActionForm - presumably defined in struts-config. Can you post that definition?

The property it is trying to set seems to be a nested, indexed property - ie something like bean.property[1]

I'm fairly certain this is related to your use of the <nested> tags. I haven't used them myself but from a quick glance that seems appropriate.

I think you might find this reference useful: http://wiki.apache.org/struts/StrutsCatalogLazyList

It explains how/why you get ArrayIndexOutOfBounds errors, and suggests some solutions.

Cheers,

evnafets

evnafetsa at 2007-7-8 21:43:20 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 10

Thanks for the pointers. I will try them out.

Yes, I used nested. I have been using it for a long time, so I am fairly familiar with them and find them easier than html tags. at least for myself.

this is the config code about Dyna Form. The architect designed it to use Dyna Form. I personally don't favor it: not flexible.

<form-bean name="ams2mForm" type="org.apache.struts.validator.DynaValidatorForm">

<form-property name="method" type="java.lang.String" />

<form-property name="dirCol" type="com.vo.AccountRefVO[]" />

<form-property name="srssAssCol" type="com.vo.SRSSAssignmentVO[]" />

<form-property name="modIndex" type="java.lang.Integer" />

<form-property name="publ_id" type="java.lang.String" />

<form-property name="salesrep_no" type="java.lang.Integer" />

<form-property name="salesService" type="java.lang.String" />

<form-property name="employeeCol" type="com.vo.EmployeeVO[]" />

</form-bean>

thewarrencluba at 2007-7-8 21:43:20 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 11

Thank to all of you guys, esp. to evnafets and kalani.

I've solved the problem. This is how:

The array index out of bounds exception:

I read the url posted by evnafets. Although there is no solution there, I found the reason behind the problem. So i replaced the nested:iterate with logic:iterate and use html: tags instead of nested: tags between the logic:iterate. And it works now. I can't explain the reason, because nested:iterate should work, but it failed me.

The javascript index problem:

as evnafets pointed out, i take everything out of the onclick. constructed a whole dynamic string and pass the string to the onclick.

Something like this:

<% String jsString = "deleteRecord(" + ind.intValue() + ")"; %>

<html:text .... onclick=<%=jsString%> ... />

This whole dynamic string works.

thewarrencluba at 2007-7-8 21:43:20 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...