From 72b9504694f34516b89849f4b4eab27c2cac38e9 Mon Sep 17 00:00:00 2001 From: brbousnguar Date: Thu, 1 Oct 2026 13:12:19 +0200 Subject: [PATCH 1/2] docs: clarify that supportingFiles is an allow-list (#22238) #22238 reports that the restclient ApiClient references ServerConfiguration, ServerVariable and ExceptionProvider without those classes being available. They are registered as supporting files and live in the same package as ApiClient, so a default run emits all of them and there is nothing to import. The reported build fails because its list predates the ApiClient gaining those references, and DefaultGenerator treats the list as a fixed allow-list, so the three files are skipped. Document that trap where it is read: a paragraph in the Selective generation section of docs/customization.md with the restclient example and a pointer to .openapi-generator-ignore, and a cross-reference from docs/global-properties.md. Correct the Javadoc on CodeGenMojo#supportingFilesToGenerate, which described modelsToGenerate instead, and add the same caveat to the Maven plugin README. Add two tests to JavaClientCodegenTest: one reproducing the reported configuration, where setting the supportingFiles global property to ApiClient.java emits ApiClient.java while skipping the three companions it references, and one pinning the premise the issue assumed had regressed, that a default restclient run emits all four files side by side. No generator behaviour change, so samples are untouched. --- docs/customization.md | 12 +++++ docs/global-properties.md | 2 + .../openapi-generator-maven-plugin/README.md | 2 +- .../codegen/plugin/CodeGenMojo.java | 6 ++- .../codegen/java/JavaClientCodegenTest.java | 52 +++++++++++++++++++ 5 files changed, 72 insertions(+), 2 deletions(-) diff --git a/docs/customization.md b/docs/customization.md index e8ef4ca6b852..15d70d3c6619 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -194,6 +194,18 @@ To control the specific files being generated, you can pass a CSV list of what y --global-property models=User,supportingFiles=StringUtil.java ``` +An explicit list is an allow-list, not an addition: anything missing from it is skipped. That makes it +fragile across upgrades, because supporting files frequently reference one another and a newer version +of a generator may add files the older list does not mention. For example, the `ApiClient` of the Java +generator's `restclient` library refers to `ServerConfiguration`, `ServerVariable` and +`ExceptionProvider`, so listing `supportingFiles=ApiClient.java` on its own produces sources that do +not compile. Each skipped file is logged at `INFO` level as +`Skipped (Skipped by supportingFiles options supplied by user.)`; a run without the option lists +the full set a generator produces in `.openapi-generator/FILES`. + +Prefer the [`.openapi-generator-ignore` file](#ignore-file-format) to exclude the handful of files you +do not want: new files are then generated by default, and only what you explicitly ignored is left out. + To control generation of docs and tests for api and models, pass false to the option. For api, these options are `--global-property apiTests=false,apiDocs=false`. For models, `--global-property modelTests=false,modelDocs=false`. These options default to true and don't limit the generation of the feature options listed above (like `--global-property api`): diff --git a/docs/global-properties.md b/docs/global-properties.md index fc672db05ef4..d62be0704e58 100644 --- a/docs/global-properties.md +++ b/docs/global-properties.md @@ -23,6 +23,8 @@ title: Global Properties | modelTests | Allows the user to define if model tests will be generated. Prefer using the more robust `.openapi-generator-ignore`. | `true` or `false` | | splitOperationsByContentType | Generates one operation per request/response content-type when an operation exposes several with different schemas | `true` or `false` | +Note that `supportingFiles`, `models` and `apis` take an allow-list: files a newer version of a generator added are not generated unless the list mentions them, which can break the generated code — see [Selective generation](./customization.md#selective-generation). + ## Note on splitOperationsByContentType diff --git a/modules/openapi-generator-maven-plugin/README.md b/modules/openapi-generator-maven-plugin/README.md index 4c5637e16a74..d24529647975 100644 --- a/modules/openapi-generator-maven-plugin/README.md +++ b/modules/openapi-generator-maven-plugin/README.md @@ -103,7 +103,7 @@ mvn clean compile | `generateModels` | `openapi.generator.maven.plugin.generateModels` | generate the models (`true` by default). Specific models may be defined as a CSV via `modelsToGenerate`. | | `modelsToGenerate` | `openapi.generator.maven.plugin.modelsToGenerate` | A comma separated list of models to generate. All models is the default. | | `generateSupportingFiles` | `openapi.generator.maven.plugin.generateSupportingFiles` | generate the supporting files (`true` by default) | -| `supportingFilesToGenerate` | `openapi.generator.maven.plugin.supportingFilesToGenerate` | A comma separated list of supporting files to generate. All files is the default. | +| `supportingFilesToGenerate` | `openapi.generator.maven.plugin.supportingFilesToGenerate` | A comma separated list of supporting files to generate. All files is the default. The list is a fixed allow-list, so supporting files added by a later version of the generator are not generated unless they are added here; prefer `.openapi-generator-ignore` instead. | | `generateModelTests` | `openapi.generator.maven.plugin.generateModelTests` | generate the model tests (`true` by default. Only available if `generateModels` is `true`) | | `generateModelDocumentation` | `openapi.generator.maven.plugin.generateModelDocumentation` | generate the model documentation (`true` by default. Only available if `generateModels` is `true`) | | `generateApiTests` | `openapi.generator.maven.plugin.generateApiTests` | generate the api tests (`true` by default. Only available if `generateApis` is `true`) | diff --git a/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java b/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java index 7cb3c174f28b..8d66eed95fd5 100644 --- a/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java +++ b/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java @@ -518,7 +518,11 @@ public class CodeGenMojo extends AbstractMojo { private Boolean generateSupportingFiles = true; /** - * A comma separated list of models to generate. All models is the default. + * A comma separated list of supporting files to generate. All supporting files are the default. + *

+ * The list is a fixed allow-list: supporting files added by a later version of the generator are + * not generated unless they are added here, which can leave the generated sources uncompilable. + * Prefer {@code .openapi-generator-ignore} to exclude the few files you do not want. */ @Parameter(name = "supportingFilesToGenerate", property = "openapi.generator.maven.plugin.supportingFilesToGenerate") private String supportingFilesToGenerate = ""; diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java index 33e78b1e4847..0be74ad5d842 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java @@ -37,6 +37,7 @@ import org.junit.jupiter.api.Assertions; import org.openapitools.codegen.*; import org.openapitools.codegen.config.CodegenConfigurator; +import org.openapitools.codegen.config.GlobalSettings; import org.openapitools.codegen.java.assertions.JavaFileAssert; import org.openapitools.codegen.languages.AbstractJavaCodegen; import org.openapitools.codegen.languages.JavaClientCodegen; @@ -3886,6 +3887,57 @@ public void testRestClientJackson3RegistersDefaults_issue_24587() { } + @Test(description = "Regression test for the premise of issue #22238: the restclient ApiClient refers to" + + " ServerConfiguration, ServerVariable and ExceptionProvider, which live in the invoker" + + " package, so a default run must generate them next to it.") + public void testRestClientDefaultGenerationIncludesCompanionFiles() { + final Path output = newTempFolder(); + final CodegenConfigurator configurator = new CodegenConfigurator() + .setGeneratorName(JAVA_GENERATOR) + .setLibrary(JavaClientCodegen.RESTCLIENT) + .addAdditionalProperty(CodegenConstants.API_PACKAGE, "xyz.abcdef.api") + .addAdditionalProperty(CodegenConstants.INVOKER_PACKAGE, "xyz.abcdef") + .setInputSpec("src/test/resources/3_1/java/petstore.yaml") + .setOutputDir(output.toString().replace("\\", "/")); + + List files = new DefaultGenerator().opts(configurator.toClientOptInput()).generate(); + + validateJavaSourceFiles(files); + assertFileExists(output.resolve("src/main/java/xyz/abcdef/ApiClient.java")); + assertFileExists(output.resolve("src/main/java/xyz/abcdef/ServerConfiguration.java")); + assertFileExists(output.resolve("src/main/java/xyz/abcdef/ServerVariable.java")); + assertFileExists(output.resolve("src/main/java/xyz/abcdef/ExceptionProvider.java")); + } + + @Test(description = "Issue #22238: the supportingFiles global property is an allow-list, so asking for" + + " ApiClient.java alone silently skips the ServerConfiguration, ServerVariable and" + + " ExceptionProvider it references, leaving sources that do not compile.") + public void testRestClientSupportingFilesAllowListSkipsApiClientCompanions_issue_22238() { + final Path output = newTempFolder(); + final CodegenConfigurator configurator = new CodegenConfigurator() + .setGeneratorName(JAVA_GENERATOR) + .setLibrary(JavaClientCodegen.RESTCLIENT) + .addAdditionalProperty(CodegenConstants.API_PACKAGE, "xyz.abcdef.api") + .addAdditionalProperty(CodegenConstants.INVOKER_PACKAGE, "xyz.abcdef") + .setInputSpec("src/test/resources/3_1/java/petstore.yaml") + .setOutputDir(output.toString().replace("\\", "/")); + + GlobalSettings.setProperty(CodegenConstants.SUPPORTING_FILES, "ApiClient.java"); + try { + new DefaultGenerator().opts(configurator.toClientOptInput()).generate(); + } finally { + GlobalSettings.reset(); + } + + assertFileExists(output.resolve("src/main/java/xyz/abcdef/ApiClient.java")); + assertFileNotExists(output.resolve("src/main/java/xyz/abcdef/ServerConfiguration.java")); + assertFileNotExists(output.resolve("src/main/java/xyz/abcdef/ServerVariable.java")); + assertFileNotExists(output.resolve("src/main/java/xyz/abcdef/ExceptionProvider.java")); + assertThat(output.resolve("src/main/java/xyz/abcdef/ApiClient.java")).content() + .contains("List servers") + .contains("ExceptionProvider"); + } + @Test public void testRestClientWithUseSingleRequestParameter_issue_19406() { final Path output = newTempFolder(); From 608b42c9b1d4a983780ed3e6c6861e9c0b2c8074 Mon Sep 17 00:00:00 2001 From: brbousnguar Date: Thu, 1 Oct 2026 14:20:30 +0200 Subject: [PATCH 2/2] docs: scope the supportingFiles upgrade warning to supporting files The note added under the global-properties table applied the "a newer generator version adds files an older list does not mention" warning to supportingFiles, models and apis alike. Only supportingFiles behaves that way: its names are template/supporting-file names owned by the generator, so a generator upgrade can introduce one. The models and apis lists filter names that come from the user's OpenAPI document, which a generator upgrade does not change. State the allow-list semantics for all three, then scope the upgrade warning to supportingFiles, and reword the sentence so it parses. --- docs/global-properties.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/global-properties.md b/docs/global-properties.md index d62be0704e58..f2b9eee13fff 100644 --- a/docs/global-properties.md +++ b/docs/global-properties.md @@ -23,7 +23,10 @@ title: Global Properties | modelTests | Allows the user to define if model tests will be generated. Prefer using the more robust `.openapi-generator-ignore`. | `true` or `false` | | splitOperationsByContentType | Generates one operation per request/response content-type when an operation exposes several with different schemas | `true` or `false` | -Note that `supportingFiles`, `models` and `apis` take an allow-list: files a newer version of a generator added are not generated unless the list mentions them, which can break the generated code — see [Selective generation](./customization.md#selective-generation). +Note that `supportingFiles`, `models` and `apis` take an allow-list: when one of them is set, only the +names it lists are generated. For `supportingFiles` this also means that supporting files added by a +newer version of a generator are not generated unless the list mentions them, which can break the +generated code — see [Selective generation](./customization.md#selective-generation). ## Note on splitOperationsByContentType