Hi Prasanth,

Just to close the loop: the fix is merged.

WW-5700 — the map and list accessors no longer store the value when the
conversion fails, so the marker string never reaches your map. A follow-up,
WW-5701, fixes a related case where the marker was compared with equals()
instead of identity, which could drop a legitimate element whose text
happens
to match.

Both are in 7.4.0 and 6.12.0, neither released yet. Once you upgrade you can
drop the instanceof Integer guard — an unconvertible value will simply leave
the entry is absent, and the conversion error is still recorded as before.

Thanks again for the report and for coming back with the tag; that is what
made it reproducible.

Cheers
Łukasz

On Thu, Aug 27, 2026 06:08 PM, Prasanth Pasala <[email protected]>
wrote:

> Hi Lukasz,
>
> Thank you for looking into it and the detailed explanation.  During
> debugging I did see the NO CONVERSION POSSIBLE message in the map.
>
> As you suggested using Boolean is probably the best solution.  Changing
> the default value of unchecked for the stack could cause problems somewhere
> else.
>
> The line of code where the error occurs is in the validate method. There
> are dependencies between fields so the validation code is checking if the
> check box is selected and if so has the user populated another text box or
> not.
>
> Below is the temporary solution I had put in to make the site work.
> --------------
> if(getEnrollmentForm().getCapDeferral().get(compID) != null ) {
>                 if(getEnrollmentForm().getCapDeferral().get(compID)
> instanceof Integer) {
>                     // got valid value
>                 }
>                 else {
>                     getEnrollmentForm().getCapDeferral().put(compID,
> Integer.valueOf(0));
>                 }
>             }
> --------------
> Thanks,
> Prasanth
>
> On 8/27/26 2:52 AM, Łukasz Lenart wrote:
>
> Thanks for the tag, that was the missing piece — I can reproduce it and it
> is
> a bug in Struts, not in your code.
>
> I have raised it as 
> WW-5700:https://www.google.com/url?q=https://issues.apache.org/jira/browse/WW-5700&source=gmail&ust=1787903552853000&sa=E
>
> What happens
> ------------
>
> With submitUnchecked="true" the tag renders a companion hidden field, and
> when
> the box is not checked CheckboxInterceptor submits the parameter with its
> "uncheckedValue", which defaults to the string "false".
>
> So Struts is asked to bind "false" into a HashMap<Long, Integer>. That
> conversion fails, as it should. The problem is what happens next:
> XWorkConverter.convertValue() signals failure by returning the constant
> TypeConverter.NO_CONVERSION_POSSIBLE — and that constant is itself a plain
> String, "ognl.NoConversionPossible". XWorkMapPropertyAccessor.setProperty()
> puts that return value straight into your map without checking for it.
>
> Because generics are erased, the map is just a Map at that point, so the put
> succeeds silently. Nothing blows up until your own code reads the entry back
> and unboxes it, which is exactly why the stack trace points at your line
>
> ... getCapDeferral().get(compID) == 1 ...
>
> and not at anything in Struts. The same missing check exists for List and
> Collection properties, and for map keys as well as values.
>
> What you can do now
> -------------------
>
> The cleanest workaround is to bind the checkbox to a Boolean rather than an
> Integer. "false" is the unchecked default precisely because a checkbox is
> boolean by nature, so this converts cleanly:
>
> @Element(value = java.lang.Boolean.class)
> private HashMap<Long, Boolean> capDeferral = new HashMap<>();
>
> <s:checkbox name="capDeferral[%{#attr.compensation.enrollmentCompID}]"
> fieldValue="true" submitUnchecked="true"/>
>
> and then test Boolean.TRUE.equals(getCapDeferral().get(compID)).
>
> If you need to keep Integer, set the interceptor's uncheckedValue to
> something
> convertible instead:
>
> <interceptor-ref name="checkbox">
> <param name="uncheckedValue">0</param>
> </interceptor-ref>
>
> Be aware that is stack-wide, so it affects every checkbox in that stack, not
> just this one — any checkbox bound to a Boolean will then receive "0".
>
> One more thing worth checking on your side: the conversion failure *is*
> recorded as a conversion error, so with the default stack the
> conversionError
> and workflow interceptors should normally return INPUT before your action
> code
> runs. If your action is reaching that line anyway, it may not be
> ValidationAware, or it may be on a custom stack — that is worth a look
> independently of this bug, since it is your safety net for every other
> conversion failure too.
>
> Thanks for the report and for following up with the tag.
>
> Cheers
> Łukasz
>
> On Tue, Aug 18, 2026 12:12 AM, Prasanth Pasala <[email protected]> 
> <[email protected]>
> wrote:
>
>
> <s:checkbox class="disableText" 
> name="capDeferral[%{#attr.compensation.enrollmentCompID}]"
> fieldValue="1" submitUnchecked="true"/>
>
> Thanks,
> Prasanth
>
> On 8/14/26 11:24 PM, Lukasz Lenart wrote:
>
> pt., 14 sie 2026 o 22:36 Prasanth <[email protected]> 
> <[email protected]>
>
> napisał(a):
>
> Getting the below exception after a form is submitted. The form has a
>
> check box, when this check box is not selected we get the exception. If the
> check box is selected it works normally. Is there
>
> anything I should be doing to force struts to put a Integer value in
>
> the hash map when the check box is not selected?
>
>    Exception: java.lang.ClassCastException: class java.lang.String
>
> cannot be cast to class java.lang.Integer (java.lang.String and
> java.lang.Integer are in module java.base of loader 'bootstrap')
>
> The code line where it happens is below
>
>                   else if(getEnrollmentForm().getCapDeferral().get(compID)
>
> != null && getEnrollmentForm().getCapDeferral().get(compID)==1) {
>
> Variable Declaration:
>       @Element(value=java.lang.Integer.class)
>       private HashMap<Long, Integer> capDeferral = new
>
> HashMap<Long,Integer>();
>
> Can you post the UI, how do you compose the form from tags?
>
>
> Cheers
> Łukasz
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>
>  ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>
>
>

Reply via email to