Saturday, November 19, 2011

Weblogic specific issue abt custom Tags

Dear Friends,

I was facing an issue specifically on weblogic and the same JSP was working fine on Oracle Application Server.
I thought it is worth sharing with all.

ERROR MESSAGE :
The method setTabindex (String) in the type NumericNewTextTag is not applicable for the arguments (int)

After seeing the error message, the obvious thought that came to my mind was, that we are passing an int and it is expecting a String.

Then I thought, why and how it is getting compiled on Oracle AS?
Is JSP to Servlet compilation, vendor specific?
What abt the theory that Java says? write once, run anywhere? Doesn't this theory apply here?


You'll get the answers to all these questions at the end of this post.

Problematic code

int tabindex=0;
<nuchtml:numbertextbox 
         property="txtGrossRevenues" 
         displayClass="<%= flag %>" 
         mode="<%= vMode %>" 
         value="<%=Format.getFormatDbl(value,DECIMAL_PRECISION)%>" 
         onchange="fnOnChange()" 
         maxlength="13" 
         onkeypress="checkNumericsNew(event)" 
         onblur="addCommaCurrencyFormat(this);" 
         onfocus=" callCurrencyFocus(this)" 
         onmousedown="Disable_Copy_Paste();" 
         onkeydown="Disable_Copy_Paste();" 
         tabindex="<%=tabIndex%>" <%-- That's the problematic line --%>
         style="width:200"/>

tabindex++;


Code with Problem resolved.

int tabindex=0;
// Please note the change in tabindex attribute.
<nuchtml:numbertextbox 
         property="txtGrossRevenues" 
         displayClass="<%= flag %>" 
         mode="<%= vMode %>" 
         value="<%=Format.getFormatDbl(value,DECIMAL_PRECISION)%>" 
         onchange="fnOnChange()" 
         maxlength="13" 
         onkeypress="checkNumericsNew(event)" 
         onblur="addCommaCurrencyFormat(this);" 
         onfocus=" callCurrencyFocus(this)" 
         onmousedown="Disable_Copy_Paste();" 
         onkeydown="Disable_Copy_Paste();" 
         tabindex="<%=Integer.toString(tabIndex)%>"
         style="width:200"/>

tabindex++;


Key Points
===========

On Oracle this custom tag gets translated to somewhat like the following.

// Please note that whatever is the return type 
// of the expression is wrapped into String and then sent to setTabIndex method.
// So even if the developer sends a primitive int, oracle will convert it
// to String before sending it to method.
// Hence no compilation problem on Oracle server.
__jsp_taghandler_33.setTabindex(OracleJspRuntime.toStr(Integer.toString(tabIndex));

Note that, the oracle server converts the argument passed by the user to a String explicitly, which is not the case with weblogic.
So, if you are using a request-time expression value in the attribute of a custom-tag, Make sure that return type of the expression is a String.

Here are the answers to the questions:

Why and how it is getting compiled on Oracle AS?
The above explanation clearly explains that.
Is JSP to Servlet translation, vendor specific?
Yes, JSP to servlet translation varies across vendors.
What abt the theory that Java says? write once, run anywhere? Doesn't this theory apply here?
This theory still works. Because, it was the mistake on developer's end, not to comply with the syntax of JSP, which luckily worked on Oracle.

JSP always say, you must pass a String to an custom-tag's attribute.


Some questions are still boggling my mind?

  1. Is it good that Oracle converts every passed expression to String before passing to the setTabindex method? What should be the ideal translation that is expected from a container?
  2. how abt the literals that are passed like tabindex="1", how that were working on weblogic? Why those didn't create an issue? Did weblogic converted them to String before passing it to method?

No comments:

Post a Comment