fabric8io / kubernetes-client

Java client for Kubernetes & OpenShift
http://fabric8.io
Apache License 2.0
3.33k stars 1.44k forks source link

Class name generation fails for fields with special characters using java-generator-maven-plugin #5968

Closed fengyinqiao closed 2 weeks ago

fengyinqiao commented 1 month ago

Describe the bug

Environment:

Fabric8 Kubernetes Client Version: 6.12.0 Maven Version: 3.9.6 Java Version: 17.0.10 Kubernetes Version: 1.20.1 Plugin Used: io.fabric8:java-generator-maven-plugin:6.12.0

Issue Summary:

When using io.fabric8:java-generator-maven-plugin to generate Java POJOs from CRDs, the plugin fails to generate valid Java class names for fields that start with special characters such as -. Specifically, fields named -XX result in generated classes with invalid Java identifiers.

Steps to Reproduce:

Define a CRD with a property named -XX under any object. Configure the java-generator-maven-plugin in a Maven project. Run Maven generate-sources goal.

Expected Result:

The plugin should generate a valid Java class name or provide a mechanism to specify a valid Java identifier for properties with names that are not valid Java identifiers.

Actual Result:

The generated Java class contains an invalid name, like this, the class name is empty:

public class <A extends io.strimzi.kafka.v1beta2.kafkaspec.kafka.jvmoptions._XXFluent<A>> extends BaseFluent<A>{
  public () {
  }
...
}

Proposed Solution:

It would be helpful if the plugin could either:

Automatically convert invalid identifiers into valid Java class names. Provide a configuration option in the Maven plugin to manually specify replacements or mappings for invalid identifiers. Example CRD Snippet:

jvmOptions:
  description: JVM Options for pods.
  properties:
    -XX:
      description: A map of -XX options to the JVM.
      type: object
      x-kubernetes-preserve-unknown-fields: true

Additional Context:

This issue prevents us from automatically generating client libraries for our custom Kubernetes resources, requiring manual intervention or post-generation scripts to correct the class names.

Fabric8 Kubernetes Client version

6.12.1

Steps to reproduce

  1. Define a CRD with a property named -XX under any object.
  2. Configure the java-generator-maven-plugin in a Maven project.
  3. Run Maven generate-sources goal.

Expected behavior

The plugin should generate a valid Java class name or provide a mechanism to specify a valid Java identifier for properties with names that are not valid Java identifiers.

Runtime

Kubernetes (vanilla)

Kubernetes API Server version

1.23

Environment

macOS

Fabric8 Kubernetes Client Logs

No response

Additional context

This issue prevents us from automatically generating client libraries for our custom Kubernetes resources, requiring manual intervention or post-generation scripts to correct the class names.

matteriben commented 1 month ago

I wasn't able to reproduce this using this file: https://github.com/fabric8io/kubernetes-client/blob/main/java-generator/core/src/test/resources/strimzi-kafka-crd.yml

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1</version>
  <properties>
    <kubernetes-client.version>6.12.0</kubernetes-client.version>
    <sundrio.version>0.103.1</sundrio.version>
    <lombok.version>1.18.32</lombok.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
    <dependency>
      <groupId>io.fabric8</groupId>
      <artifactId>kubernetes-client</artifactId>
      <version>${kubernetes-client.version}</version>
    </dependency>
    <dependency>
      <groupId>io.fabric8</groupId>
      <artifactId>generator-annotations</artifactId>
      <version>${kubernetes-client.version}</version>
    </dependency>
    <!-- extraAnnotations requires these additional dependencies -->
    <dependency>
      <groupId>io.sundr</groupId>
      <artifactId>builder-annotations</artifactId>
      <version>${sundrio.version}</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>${lombok.version}</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>io.fabric8</groupId>
        <artifactId>java-generator-maven-plugin</artifactId>
        <version>${kubernetes-client.version}</version>
        <executions>
          <execution>
            <goals>
              <goal>generate</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <source>strimzi-kafka-crd.yml</source>
          <alwaysPreserveUnknown>true</alwaysPreserveUnknown>
          <extraAnnotations>true</extraAnnotations>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>
$ mvn -v
Apache Maven 3.9.1 (Red Hat 3.9.1-3)
Maven home: /usr/share/maven
Java version: 17.0.9, vendor: Red Hat, Inc., runtime: /usr/lib/jvm/java-17-openjdk-17.0.9.0.9-3.fc39.aarch64
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "6.7.10-200.fc39.aarch64", arch: "aarch64", family: "unix"
fengyinqiao commented 1 month ago
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.15</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.mycompany.app</groupId>
    <artifactId>myapp</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>myapp</name>
    <description>an operation gateway for middleware</description>
    <properties>
        <java.version>17</java.version>
        <io.fabric8.version>6.9.2</io.fabric8.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-commons</artifactId>
        </dependency>
        <dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
            <version>2.6.0</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-boot-starter</artifactId>
            <version>3.0.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.fabric8</groupId>
            <artifactId>kubernetes-client</artifactId>
        </dependency>
        <dependency>
            <groupId>io.fabric8</groupId>
            <artifactId>generator-annotations</artifactId>
        </dependency>
        <dependency>
            <groupId>io.sundr</groupId>
            <artifactId>builder-annotations</artifactId>
            <version>0.101.3</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.fabric8</groupId>
                <artifactId>kubernetes-client</artifactId>
                <version>${io.fabric8.version}</version>
            </dependency>
            <dependency>
                <groupId>io.fabric8</groupId>
                <artifactId>generator-annotations</artifactId>
                <version>${io.fabric8.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>io.fabric8</groupId>
                <artifactId>java-generator-maven-plugin</artifactId>
                <version>6.12.0</version> 
                <executions>
                    <execution>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <source>src/main/resources/kubernetes</source>
                            <alwaysPreserveUnknown>true</alwaysPreserveUnknown>
                            <generatedAnnotations>true</generatedAnnotations>
                            <extraAnnotations>true</extraAnnotations>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

that's my pom.xml , I changed io.sundr:builder-annotations:0.101.3 to 0.103.1 as you, problem solved. I think it's a bug of io.sundr:builder-annotations

manusa commented 2 weeks ago

Sundrio was bumped on #5621

v6.10.0 of the client provides the BOM with the right sundrio version.