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]>
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]>
> 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