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

NullPointerException when compiled to Spring Native binary #3271

Open
rj93 opened this issue Apr 2, 2024 · 3 comments · May be fixed by #3277
Open

NullPointerException when compiled to Spring Native binary #3271

rj93 opened this issue Apr 2, 2024 · 3 comments · May be fixed by #3277

Comments

@rj93
Copy link

rj93 commented Apr 2, 2024

Describe the bug
I am using Spring Shell to create a cli tool, the library works fine when run from the jar, however when compiled to a native binary and ran it throws a NullPointerException.

I have added the client-java-spring-aot-integrations dependency but it doesn't seem to have resolved anything, and I am also required to add the following to reflect-config.json otherwise I get a different error.

[
  {
    "name": "io.kubernetes.client.openapi.models.",
    "unsafeAllocated": true
  }
]

When running as native it errors after Kubectl.get(...) is invoked:

2024-04-02T23:40:30.399+01:00  INFO 96712 --- [           main] com.rj93.cli.CliApplication              : Started CliApplication in 0.071 seconds (process running for 0.097)
2024-04-02T23:40:30.400+01:00  INFO 96712 --- [           main] com.rj93.cli.commands.GetPodsCommand     : Getting pods
2024-04-02T23:36:50.127+01:00 ERROR 96399 --- [           main] io.kubernetes.client.util.ModelMapper    : Unexpected exception while loading classes

java.lang.NullPointerException: null
        at io.kubernetes.client.util.ModelMapper.getClassNamesFromPackage(ModelMapper.java:479) ~[na:na]
        at io.kubernetes.client.util.ModelMapper.initModelMap(ModelMapper.java:407) ~[na:na]
        at io.kubernetes.client.util.ModelMapper.<clinit>(ModelMapper.java:81) ~[na:na]
        at io.kubernetes.client.extended.kubectl.Kubectl$ApiClientBuilder.refreshDiscovery(Kubectl.java:236) ~[k8s-cli-native-example:na]
        at io.kubernetes.client.extended.kubectl.KubectlGet.execute(KubectlGet.java:60) ~[k8s-cli-native-example:na]
        at com.rj93.cli.commands.GetPodsCommand.getConfigMaps(GetPodsCommand.java:27) ~[k8s-cli-native-example:na]

Client Version
20.0.1

Kubernetes Version
1.29.1

Java Version
21.0.2-tem

GraalVM Version
21.0.2-graalce

To Reproduce
Reproducable example can be found here: https://github.com/rj93/k8s-cli-native-example

Expected behavior
A NullPointerExpcetion not to be thrown

KubeConfig

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: <<REDACTED>>
    server: https://kubernetes.docker.internal:6443
  name: docker-desktop
contexts:
- context:
    cluster: docker-desktop
    user: docker-desktop
  name: docker-desktop
current-context: docker-desktop
kind: Config
preferences: {}
users:
- name: docker-desktop
  user:
    client-certificate-data: <<REDACTED>>
    client-key-data: <<REDACTED>>

Server:

  • OS: MacOS
  • Environment: bash
  • K8s Cluster: Docker Desktop
@rj93
Copy link
Author

rj93 commented Apr 2, 2024

@joshlong I see you implemented the spring-aot module in #2457, would you maybe have an idea what is happening here?

@rj93
Copy link
Author

rj93 commented Apr 3, 2024

Done some digging and (sort of) found the issue, registering the Spring hints relies on the API model classes being annnotated with @ApiModel, however it appears that they no longer have the annotation so it is returning 0 models to register.

Updating this to find all classes in the io.kubernetes.client.openapi.models package correctly registers all models for reflection:

Reflections reflections = new Reflections("io.kubernetes.client.openapi.models", Scanners.SubTypes.filterResultsBy(s -> true));
Set<Class<?>> classes = reflections.getSubTypesOf(Object.class);
LOGGER.info("Found {} apiModels", classes.size());
for (Class<?> clazz : classes) {
     LOGGER.info("registering {} for reflection", clazz);
    hints.reflection().registerType(clazz, allMemberCategories);
}
2024-04-03T13:58:31.395+01:00  INFO 17552 --- [           main] org.reflections.Reflections              : Reflections took 272 ms to scan 2 urls, producing 565 keys and 5623 values
2024-04-03T13:58:31.489+01:00  INFO 17552 --- [           main] tesBeanFactoryInitializationAotProcessor : Found 1115 models
2024-04-03T13:58:31.489+01:00  INFO 17552 --- [           main] tesBeanFactoryInitializationAotProcessor : registering class io.kubernetes.client.openapi.models.V1beta1Variable$CustomTypeAdapterFactory for reflection
2024-04-03T13:58:31.489+01:00  INFO 17552 --- [           main] tesBeanFactoryInitializationAotProcessor : registering class io.kubernetes.client.openapi.models.V1Endpoint for reflection
...

This appears to fix the use of the *Api classes from the io.kubernetes.client.openapi.apis package, however Kubectl still fails with the original error.

@rj93 rj93 linked a pull request Apr 3, 2024 that will close this issue
@cache-sk
Copy link

This is also mentioned in issue #3134

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