Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Additional @Decimal annotations generated for xs:int #17

Closed
Undover opened this issue Sep 6, 2024 · 8 comments
Closed

Additional @Decimal annotations generated for xs:int #17

Undover opened this issue Sep 6, 2024 · 8 comments

Comments

@Undover
Copy link

Undover commented Sep 6, 2024

Hello,

I'm in the process of migrating a project from javax to jakarta, and I've noticed some changes in how validations are generated for xs:int types.

This is part of the schema used for testing:

    <simpleType name="IntField">
        <restriction base="xs:int">
            <minInclusive value="1"/>
        </restriction>
    </simpleType>

    <simpleType name="LongField">
        <restriction base="xs:long">
            <minInclusive value="1"/>
        </restriction>
    </simpleType>

    <complexType name="ClassWithValidation">
        <sequence>
            <element name="intField" type="tns:IntField" minOccurs="0"/>
            <element name="otherIntField" type="xs:int" minOccurs="0"/>
            <element name="longField" type="tns:LongField" minOccurs="0"/>
            <element name="otherLongField" type="xs:long" minOccurs="0"/>
        </sequence>
    </complexType>

Classes generated with this schema differ between com.github.krasa:krasa-jaxb-tools:1.5 and com.fillumina:krasa-jaxb-tools:2.3.3 (among other dependency upgrades required for jakarta migration).

Before:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ClassWithValidation", namespace = "a", propOrder = {
    "intField",
    "otherIntField",
    "longField",
    "otherLongField"
})
public class ClassWithValidation
    implements Serializable
{

    private final static long serialVersionUID = 1L;
    @XmlElement(namespace = "a")
    @DecimalMin("1")
    protected Integer intField;
    @XmlElement(namespace = "a")
    protected Integer otherIntField;
    @XmlElement(namespace = "a")
    @DecimalMin("1")
    protected Long longField;
    @XmlElement(namespace = "a")
    protected Long otherLongField;
    ...

After:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ClassWithValidation", namespace = "a", propOrder = {
    "intField",
    "otherIntField",
    "longField",
    "otherLongField"
})
public class ClassWithValidation
    implements Serializable
{

    private static final long serialVersionUID = 1L;
    @XmlElement(namespace = "a")
    @DecimalMin(value = "1", inclusive = true)
    @DecimalMax(value = "2147483647", inclusive = true)
    protected Integer intField;
    @XmlElement(namespace = "a")
    @DecimalMin(value = "-2147483648", inclusive = true)
    @DecimalMax(value = "2147483647", inclusive = true)
    protected Integer otherIntField;
    @XmlElement(namespace = "a")
    @DecimalMin(value = "1", inclusive = true)
    protected Long longField;
    @XmlElement(namespace = "a")
    protected Long otherLongField;
    ...

What caught my attention is the generation of @DecimalMin(value = "-2147483648", inclusive = true) and @DecimalMax(value = "2147483647", inclusive = true) whenever a restriction is not specified for xs:int type, which is not the case for xs:long type, so if it's not a bug I assume something's wrong with my configuration.

Used flags for org.apache.cxf.tools.wsdlto.WSDLToJava:

-xjc-enableIntrospection
-Xfluent-api
-Xannotate
-XJsr303Annotations
-XJsr303Annotations:verbose=true
-Xcommons-lang
-verbose
-xjc-XJsr303Annotations:validationAnnotations=jakarta
-xjc-npa
-xjc-Xinheritance
-xjc-Xinject-code
-validate=all

In case of trouble with reproducing the issue, I could provide a sample project.

Thanks in advance

@fillumina
Copy link
Owner

Hi @Undover ,
that's a feature to restrict valid values to those allowed by the specs.

The XSD specifications allow for a lot of numeric types which are not present in java (i.e. unsignedShort) so to support them this program adds the necessary restrictions. Because the mechanism is automatic (it copies the restrictions added to the facet) they are added to supported types as well but that shouldn't be a problem.

Please see the numeric test on this package and the generated classes to better understand all the applied restrictions.

Regards

@Undover
Copy link
Author

Undover commented Sep 10, 2024

I've looked around and want to clarify things further, the generated Numeric class contains two fields aint and along, which according to the XSD spec should both be constrained (long to +/- 9223372036854775807, ints as they are now). Is the lack of validations for longs unintended then if they are generated for ints? If so, will the generation of those validation annotations be the default non-toggleable behavior in the future?

@fillumina
Copy link
Owner

fillumina commented Sep 10, 2024

The parsing of the XSD is done by the XSOM package invoked by JAXWS, for each defined type it fills the com.sun.xml.xsom.XSFacet class with the needed constraints and other info, which are read by krasa-jaxb-tools to create the needed validation annotations. We have no control over what constraints and info are passed by XSFacet but they should be consistent among other libraries that use the same XSOM package.

@fillumina
Copy link
Owner

fillumina commented Sep 10, 2024

As for the future it's hard to tell but the XSOM library is very mature and the tests present in here will fail if anything should change.

@fillumina
Copy link
Owner

Hi, to clarify

the generated Numeric class contains two fields aint and along, which according to the XSD spec should both be constrained (long to +/- 9223372036854775807, ints as they are now). Is the lack of validations for longs unintended then if they are generated for ints? If so, will the generation of those validation annotations be the default non-toggleable behavior in the future?

according to the int specs:

int is ·derived· from long by setting the value of ·maxInclusive· to be 2147483647 and ·minInclusive· to be -2147483648.

Because a Java int is a 32 bit signed value (from -2147483648 to 2147483647) it aligns with the XSD int specification so no further constraints are required. Same for xsd:long that is converted into a 64 bit signed Java type.

@Krzyshio
Copy link

Hi @fillumina ,

I’m encountering the same issue as @Undover .

As mentioned, the @DecimalMin and @DecimalMax annotations are being generated for int fields but not for long fields, which seems inconsistent. According to the XSD specs, both should have constraints, so it’s puzzling why int has validations while long does not.

You mentioned that no further constraints are required, but the problem is that int does have the validation annotations generated, which is causing confusion and, in my case, is problematic. Is there any way to disable these validation annotations for int fields? If this behavior is not toggleable, it could pose significant issues for us.

Thanks in advance for your help!

@Undover
Copy link
Author

Undover commented Sep 12, 2024

Because a Java int is a 32 bit signed value (from -2147483648 to 2147483647) it aligns with the XSD int specification so no further constraints are required. Same for xsd:long that is converted into a 64 bit signed Java type.

This is what's confusing to me, as both xsd:int and xsd:long have the same value ranges as the java int and long types, yet the validation annotations are only generated for ints. My codebase depends on the lack of unnecessary validation annotations; fixing this would require some refactoring and resolving this inconsistency with code gen in either direction would result in not having special cases.

@fillumina
Copy link
Owner

That's right, I have finally understood the inconsistency between int and long (it was a check made only for long), I am fixing it by removing all default constraints and setting an option to add them back if needed.

@fillumina fillumina reopened this Sep 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants