Hi Prasanth,

Short answer: no. 7.4.0 will not start sending you to the input page.

The conversion error was already being registered before the fix. WW-5700
only
changed what the map accessor does with the *return value* of
XWorkConverter.convertValue(); it did not touch the error reporting inside
convertValue() itself. I ran the same binding against the pre-fix and
post-fix
code to be sure:

before: map = {100=1, 200=ognl.NoConversionPossible}
conversionErrors = {capDeferral[200]=ConversionData}

after: map = {100=1}
conversionErrors = {capDeferral[200]=ConversionData}

Identical error, different map. So whatever your stack does with that error
today, it will do exactly the same in 7.4.0.

One thing that does change for your code
----------------------------------------

The entry is now absent rather than holding the marker. That means

getCapDeferral().get(compID)

returns null where it used to return "ognl.NoConversionPossible". Your
temporary
guard is therefore not merely redundant after the upgrade - its else branch
stops
running, because the outer != null test is now false and the 0 is never put:

if (get(compID) != null) {
if (get(compID) instanceof Integer) { ... }
else { put(compID, Integer.valueOf(0)); } // no longer reached
}

Your validate() line itself is fine, since

get(compID) != null && get(compID) == 1

is already null-safe and simply evaluates to false. But if anything
downstream
relies on the key existing with a 0, key that off absence instead:

Integer v = getCapDeferral().get(compID);
boolean selected = Integer.valueOf(1).equals(v);

Why yours submits successfully at all
-------------------------------------

This part is worth a look, independently of the fix. The default stack runs

params -> conversionError -> validation -> workflow

so validate() always runs even when a conversion error is pending -
workflow is
what returns INPUT, and it comes after validation. That ordering is why your
ClassCastException surfaced inside validate() rather than being
short-circuited
earlier.

But with an unmodified defaultStack and a ValidationAware action, the
conversionError interceptor does turn that entry into a field error - I
checked,
it produces

capDeferral[200] = [Invalid field value for field "capDeferral[200]".]

and hasErrors() is then true, so workflow returns INPUT. If your form
submits
successfully instead, something in your setup is swallowing it: most likely
the
conversionError interceptor is not in your stack, or the action is not
ValidationAware, or workflow is excluded for that method. Worth confirming,
because that is your safety net for every conversion failure, not just this
one.

Again, none of that changes in 7.4.0 - it behaves the same before and after.

Cheers
Łukasz

On Wed, Sep 02, 2026 03:42 PM, Prasanth <[email protected]> wrote:

> Hi Lukasz,
>
> After adding the instanceof guard if validate method did not generate any
> field errors the form submission was successful. Would the new 7.4.0 go
> back to input page because the struts has added a
> conversion error?
>
> Thanks,
> Prasanth
>
> On 9/2/26 12:22 AM, Lukasz Lenart wrote:
> > 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