Skip to content

Commit 288e54b

Browse files
committed
[Java][microprofile] add JSpecify support
useJspecify was rejected for the microprofile library, even though the option is listed in its generated documentation. This enables it, reusing the machinery already shared in AbstractJavaCodegen: - add MICROPROFILE to JSPECIFY_SUPPORTED_LIBRARIES - emit @nullable on optional properties and operation parameters via the shared nullable_var_annotations partial, and route types through nullableDataType/nullableDatatypeWithEnum so annotations on qualified types are placed type-use style (java.math.@nullable BigDecimal) - declare the org.jspecify:jspecify dependency in both microprofile poms The @NullMarked package-info.java files already came from the base applyJspecify(), which resolves against the shared Java template dir. Every template change is guarded by {{#useJspecify}}, so output with the flag off is byte-identical to before (verified by diffing generated output against master). The guard is required rather than cosmetic: jakarta.annotation.Nullable/Nonnull only exist from jakarta.annotation-api 2.1.1, while the microprofile poms pin 1.3.5 and 2.0.0, so emitting the default annotations produces code that does not compile. Two cases need the annotation partial paired with the datatype lambda, which stashes and re-emits it: the enum getter branches, and the literal File / List<File> type in the isFile form-parameter branch. Without that pairing the annotation is silently dropped. Adds a sample (microprofile-rest-client-3.0-jspecify, registered in the jdk11 samples workflow) and tests covering type-use placement, JAX-RS parameter annotations coexisting with @nullable, sealed oneOf interfaces, enum getters, optional file parameters, and that required properties are not annotated.
1 parent 029523d commit 288e54b

50 files changed

Lines changed: 2837 additions & 17 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/samples-java-client-jdk11.yaml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ jobs:
8686
- samples/client/petstore/java/microprofile-rest-client-3.0-jackson-mutiny
8787
- samples/client/petstore/java/microprofile-rest-client-3.0-jackson-with-xml
8888
- samples/client/petstore/java/microprofile-rest-client-3.0-mutiny
89+
- samples/client/petstore/java/microprofile-rest-client-3.0-jspecify
8990
- samples/client/petstore/java/microprofile-rest-client-with-useSingleRequestParameter
9091
- samples/client/petstore/java/microprofile-oneof-interface
9192
- samples/client/petstore/java/apache-httpclient
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
generatorName: java
2+
outputDir: samples/client/petstore/java/microprofile-rest-client-3.0-jspecify
3+
library: microprofile
4+
inputSpec: modules/openapi-generator/src/test/resources/3_0/java/jspecify.yaml
5+
templateDir: modules/openapi-generator/src/main/resources/Java
6+
validateSpec: false
7+
additionalProperties:
8+
serializationLibrary: jackson
9+
artifactId: microprofile-rest-client-3-jspecify
10+
configKey: petstore
11+
microprofileRestClientVersion: "3.0"
12+
hideGenerationTimestamp: true
13+
useReflectionEqualsHashCode: true
14+
openApiNullable: "false"
15+
useJspecify: true
16+
typeMappings:
17+
BigDecimal: java.math.BigDecimal

‎docs/generators/java-microprofile.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
101101
|useGzipFeature|Send gzip-encoded requests| |false|
102102
|useJackson3|Use Jackson 3 instead of Jackson 2. Supported for 'native', 'apache-httpclient', and 'jersey3' libraries (requires Java 17+) and for Spring 'resttemplate', 'webclient', and 'restclient' libraries (require useSpringBoot4=true).| |false|
103103
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
104-
|useJspecify|Use Jspecify for null checks. Only supported for [native, restclient, resttemplate, webclient]| |false|
104+
|useJspecify|Use Jspecify for null checks. Only supported for [microprofile, native, restclient, resttemplate, webclient]| |false|
105105
|useOneOfDiscriminatorLookup|Use the discriminator's mapping in oneOf to speed up the model lookup. IMPORTANT: Validation (e.g. one and only one match in oneOf's schemas) will be skipped. Only jersey2, jersey3, native, okhttp-gson support this option.| |false|
106106
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
107107
|usePlayWS|Use Play! Async HTTP client (Play WS API)| |false|

‎docs/generators/java.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
101101
|useGzipFeature|Send gzip-encoded requests| |false|
102102
|useJackson3|Use Jackson 3 instead of Jackson 2. Supported for 'native', 'apache-httpclient', and 'jersey3' libraries (requires Java 17+) and for Spring 'resttemplate', 'webclient', and 'restclient' libraries (require useSpringBoot4=true).| |false|
103103
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
104-
|useJspecify|Use Jspecify for null checks. Only supported for [native, restclient, resttemplate, webclient]| |false|
104+
|useJspecify|Use Jspecify for null checks. Only supported for [microprofile, native, restclient, resttemplate, webclient]| |false|
105105
|useOneOfDiscriminatorLookup|Use the discriminator's mapping in oneOf to speed up the model lookup. IMPORTANT: Validation (e.g. one and only one match in oneOf's schemas) will be skipped. Only jersey2, jersey3, native, okhttp-gson support this option.| |false|
106106
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
107107
|usePlayWS|Use Play! Async HTTP client (Play WS API)| |false|

‎modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaClientCodegen.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
190190

191191
@Setter protected int maxAttemptsForRetry = 1;
192192
@Setter protected long waitTimeMillis = 10l;
193-
private final Set<String> JSPECIFY_SUPPORTED_LIBRARIES = new TreeSet<>(Arrays.asList(RESTCLIENT, WEBCLIENT, NATIVE, RESTTEMPLATE));
193+
private final Set<String> JSPECIFY_SUPPORTED_LIBRARIES = new TreeSet<>(Arrays.asList(MICROPROFILE, RESTCLIENT, WEBCLIENT, NATIVE, RESTTEMPLATE));
194194

195195
private static class MpRestClientVersion {
196196
public final String rootPackage;
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{{#isBodyParam}}{{#useBeanValidation}}@Valid {{/useBeanValidation}}{{{dataType}}} {{paramName}}{{/isBodyParam}}
1+
{{#isBodyParam}}{{#useBeanValidation}}@Valid {{/useBeanValidation}}{{#useJspecify}}{{>nullable_var_annotations}}{{/useJspecify}}{{>nullableDataType}} {{paramName}}{{/isBodyParam}}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{{#isCookieParam}}@CookieParam("{{baseName}}") {{#useBeanValidation}}{{>beanValidationCookieParams}}{{/useBeanValidation}} {{{dataType}}} {{paramName}}{{/isCookieParam}}
1+
{{#isCookieParam}}@CookieParam("{{baseName}}") {{#useBeanValidation}}{{>beanValidationCookieParams}}{{/useBeanValidation}} {{#useJspecify}}{{>nullable_var_annotations}}{{/useJspecify}}{{>nullableDataType}} {{paramName}}{{/isCookieParam}}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{{#isFormParam}}{{^isFile}}{{#required}}{{#useBeanValidation}}@NotNull {{/useBeanValidation}}{{/required}}@FormParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/isFile}}{{#isFile}} {{#required}}{{#useBeanValidation}}@NotNull {{/useBeanValidation}}{{/required}}@FormParam("{{baseName}}") {{^isArray}}File{{/isArray}}{{#isArray}}List<File>{{/isArray}} {{paramName}}Detail{{/isFile}}{{/isFormParam}}
1+
{{#isFormParam}}{{^isFile}}{{#required}}{{#useBeanValidation}}@NotNull {{/useBeanValidation}}{{/required}}@FormParam("{{baseName}}") {{#useJspecify}}{{>nullable_var_annotations}}{{/useJspecify}}{{>nullableDataType}} {{paramName}}{{/isFile}}{{#isFile}} {{#required}}{{#useBeanValidation}}@NotNull {{/useBeanValidation}}{{/required}}@FormParam("{{baseName}}") {{#useJspecify}}{{>nullable_var_annotations}}{{/useJspecify}}{{#lambda.jSpecifyDatatype}}{{^isArray}}File{{/isArray}}{{#isArray}}List<File>{{/isArray}}{{/lambda.jSpecifyDatatype}} {{paramName}}Detail{{/isFile}}{{/isFormParam}}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{{#isHeaderParam}}@HeaderParam("{{baseName}}") {{#useBeanValidation}}{{>beanValidationHeaderParams}}{{/useBeanValidation}} {{{dataType}}} {{paramName}}{{/isHeaderParam}}
1+
{{#isHeaderParam}}@HeaderParam("{{baseName}}") {{#useBeanValidation}}{{>beanValidationHeaderParams}}{{/useBeanValidation}} {{#useJspecify}}{{>nullable_var_annotations}}{{/useJspecify}}{{>nullableDataType}} {{paramName}}{{/isHeaderParam}}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{{#isPathParam}}@PathParam("{{baseName}}"){{#useBeanValidation}}{{>beanValidationPathParams}}{{/useBeanValidation}} {{{dataType}}} {{paramName}}{{/isPathParam}}
1+
{{#isPathParam}}@PathParam("{{baseName}}"){{#useBeanValidation}}{{>beanValidationPathParams}}{{/useBeanValidation}} {{#useJspecify}}{{>nullable_var_annotations}}{{/useJspecify}}{{>nullableDataType}} {{paramName}}{{/isPathParam}}

0 commit comments

Comments
 (0)