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

JDK classes should also be scanned if required #1999

Closed
cristalp opened this issue Sep 24, 2024 · 10 comments · Fixed by #2002
Closed

JDK classes should also be scanned if required #1999

cristalp opened this issue Sep 24, 2024 · 10 comments · Fixed by #2002

Comments

@cristalp
Copy link
Contributor

Started by #1995

The Maven plugin doesn't scan any JDK classes. We use TimeUnit in some REST endpoints, and while there is a workaround for that (thanks @MikeEdgar), it's cumbersome.

So I suggest an enhancement: Either there should be a flag to enable JDK class scanning or there should be a plugin property where a number of JDK classes can be listed to be scanned.

Since the first solution would probably make scanning slower, I suggest implementing the second solution - thanks!

@cristalp
Copy link
Contributor Author

cristalp commented Oct 28, 2024

I just tested 4.0.0, since this is one of the things that was fixed. However, I can't get it to work.

I removed the temporary solution from #1995 and added

              <includeStandardJavaModules>
                <includeStandardJavaModule>java.base</includeStandardJavaModule>
              </includeStandardJavaModules>

Testing with some dummy endpoints:

  @GET
  @Path("foo")
  @Produces(MediaType.TEXT_PLAIN)
  public Response foo(@QueryParam("timeunit") final TimeUnit timeunit) {
    return Response.ok("foo").build();
  }

  @GET
  @Path("bar/{timeunit}")
  @Produces(MediaType.TEXT_PLAIN)
  public Response bar(@PathParam("timeunit") final TimeUnit timeunit) {
    return Response.ok("bar").build();
  }

I get the following in openapi.json:

    "/api/dummy/foo" : {
      "get" : {
        "parameters" : [ {
          "name" : "timeunit",
          "in" : "query",
          "schema" : {
            "type" : "object"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "OK"
          }
        }
      }
    },
    "/api/dummy/bar/{timeunit}" : {
      "get" : {
        "parameters" : [ {
          "name" : "timeunit",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "object"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "OK"
          }
        }
      }
    }

What am I doing wrong?

Also, it would be great to have the configuration documented on https://github.com/smallrye/smallrye-open-api/tree/main/tools/maven-plugin

This is what I see in the Maven console:

[INFO] --- smallrye-open-api:4.0.0:generate-schema (default) @ design-register-web-service ---
...
Okt. 28, 2024 11:02:08 AM io.smallrye.openapi.runtime.scanner.OpenApiDataObjectScanner process
WARN: SROAP04005: Could not find schema class in index: java.util.concurrent.TimeUnit
Okt. 28, 2024 11:02:08 AM io.smallrye.openapi.runtime.scanner.OpenApiDataObjectScanner process
WARN: SROAP04005: Could not find schema class in index: java.util.concurrent.TimeUnit

@MikeEdgar
Copy link
Member

If you run the plugin with -X do you see any logging about module:java.base being indexed?

@cristalp
Copy link
Contributor Author

I see the following:

[DEBUG] Configuring mojo execution 'io.smallrye:smallrye-open-api-maven-plugin:4.0.0:generate-schema:default' with basic configurator -->
...
[DEBUG]   (f) includeStandardJavaModules = [java.base]
[DEBUG] -- end configuration --
...
[DEBUG] Indexed directories/artifacts for annotation scanning:
[DEBUG]   module:java.base (index time PT1.4724597S)
[DEBUG]   /foo/maven-repository/com/sun/activation/jakarta.activation/1.2.2/jakarta.activation-1.2.2.jar (index time PT0.0217228S)
[DEBUG]   /foo/maven-repository/org/slf4j/slf4j-api/1.7.22/slf4j-api-1.7.22.jar (index time PT0.0095195S)
[DEBUG]   /foo/maven-repository/com/google/guava/guava/33.3.0-jre/guava-33.3.0-jre.jar (index time PT0.6154975S)
...

Note that we're in the midst of migrating from JDK 8 to JDK 17. This means that we're running the build under JDK 17, but compiling for target Java 8.

$ mvn --version
Apache Maven 3.9.6 (bc0240f3c744dd6b6ec2920b3cd08dcc295161ae)
Maven home: /foo/maven/current
Java version: 17.0.12, vendor: Azul Systems, Inc., runtime: /foo/java/zulu17.52.17-ca-fx-jdk17.0.12-linux_x64
Default locale: de_CH, platform encoding: UTF-8
OS name: "linux", version: "5.10.102.1-microsoft-standard-wsl2", arch: "amd64", family: "unix"

@MikeEdgar
Copy link
Member

What properties are you providing for these?

<scanExcludePackages>${openapi.exclude.packages}</scanExcludePackages>
<scanExcludeClasses>${openapi.exclude.classes}</scanExcludeClasses>

@cristalp
Copy link
Contributor Author

cristalp commented Oct 28, 2024

Some internal packages and classes, and then com.google and org.rendersnake.Renderable.

But I also see the following in the scanner log:

Okt. 28, 2024 2:26:13 PM io.smallrye.openapi.runtime.scanner.OpenApiDataObjectScanner process
WARN: SROAP04005: Could not find schema class in index: org.rendersnake.Renderable

@MikeEdgar
Copy link
Member

Are you using regex, or simply comma-separated packages/classes? I'm curious if somehow TimeUnit is matching those properties.

@cristalp
Copy link
Contributor Author

Well, here's the Maven debugging output, I'm not using regexes:

[DEBUG] Configuring mojo execution 'io.smallrye:smallrye-open-api-maven-plugin:4.0.0:generate-schema:default' with basic configurator -->
...
[DEBUG]   (f) includeDependenciesScopes = [compile, runtime, system]
[DEBUG]   (f) includeDependenciesTypes = [jar, ejb]
[DEBUG]   (f) includeStandardJavaModules = [java.base]
...
[DEBUG]   (f) scanDependenciesDisable = false
[DEBUG]   (f) scanExcludeClasses = foobar.type.ReflectiveEqualityObject,org.rendersnake.Renderable,foobar.web.service.esv.AufgabeResource
[DEBUG]   (f) scanExcludePackages = foobar.web.util.rs.resource,com.google
[DEBUG]   (f) scanExcludeProfiles = []
[DEBUG]   (f) scanPackages = foobar
[DEBUG]   (f) scanProfiles = []
[DEBUG]   (f) scanResourceClasses = {}
[DEBUG]   (f) scanners = []
...
[DEBUG]   (f) systemPropertyVariables = {mp.openapi.extensions.smallrye.private-properties.enable=false}

@MikeEdgar
Copy link
Member

Ok, the presence of scanPackages = foobar means that is the only thing to include. You can add java.util.concurrent.TimeUnit to scanClasses or add java.util.concurrent to scanPackages. Once you've specified what is included, basically other things will not be "seen" by the scanner.

@MikeEdgar
Copy link
Member

MikeEdgar commented Oct 28, 2024

This is from the specification [1], which might help how you set these include/exclude options:

The following rules are used to determine whether a class is scanned for annotations:

  1. A class is not scanned if it's listed in mp.openapi.scan.exclude.classes

  2. A class is scanned if it's listed in mp.openapi.scan.classes

  3. A class is not scanned if its package, or any of its parent packages are listed in mp.openapi.scan.exclude.packages, unless a more complete package or parent package is listed in mp.openapi.scan.packages

  4. A class is scanned if its package or any of its parent packages are listed in mp.openapi.scan.packages

  5. A class is scanned if mp.openapi.scan.classes and mp.openapi.scan.packages are both empty or not set

[1] https://download.eclipse.org/microprofile/microprofile-open-api-4.0.2/microprofile-openapi-spec-4.0.2.html#_core_configurations

@cristalp
Copy link
Contributor Author

Ah, I wasn't aware of that, thanks! I now removed scanPackages completely and have started a full build. Let's see what happens. But in my local test, TimeUnit has now appeared!

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

Successfully merging a pull request may close this issue.

2 participants