Native compilation with GraalVM

Open
#23,642 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
38/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Stale
Tech stack
docker, java, spring-boot
Domain
api, build-system

Research direction

Start by reproducing the native Spring Boot image build and the Directory users.list().execute() call described in the issue, then compare the generated request URL with the JVM result. The payload names no repository files or tests; done means query parameters such as domain and maxResults are retained in the native build and the directory request succeeds.

Written by the indexing model from the issue text.

Description

priority: p3 type: bug

There is an issue when using native compilation with GraalVM. I'm trying to use the Admin SDK API Client Library for directory operations.

Environment details
  • Admin SDK API Client Library, version directory_v1-rev20240924-2.0.0
  • Java Temurin 21
  • Native compilation of a Spring Boot 3.3.4 app using by default at this time :
    • paketo-buildpacks/ca-certificates 3.8.6
    • paketo-buildpacks/bellsoft-liberica 10.9.0
    • paketo-buildpacks/syft 2.1.0
    • paketo-buildpacks/executable-jar 6.11.3
    • paketo-buildpacks/spring-boot 5.31.2
    • paketo-buildpacks/native-image 5.14.4
Steps to reproduce

Fresh Spring Boot 3.3.4 project.

Maven configuration

<dependency>
  <groupId>com.google.apis</groupId>
  <artifactId>google-api-services-admin-directory</artifactId>
  <version>directory_v1-rev20240924-2.0.0</version>
</dependency>
...
<plugin>
  <groupId>org.graalvm.buildtools</groupId>
  <artifactId>native-maven-plugin</artifactId>
</plugin>

Build Directory service

private Directory buildDirectoryService(@Nonnull final String gcpKey, @Nonnull final String serviceAccountUser) throws IOException, GeneralSecurityException {
    final ServiceAccountCredentials sourceCredentials =
        ServiceAccountCredentials.fromStream(...)
        .toBuilder()
        .setServiceAccountUser(serviceAccountUser)
        .setScopes(ImmutableSet.of(
            DirectoryScopes.ADMIN_DIRECTORY_GROUP_READONLY,
            DirectoryScopes.ADMIN_DIRECTORY_USER_READONLY
        ))
        .build();

    return new Directory.Builder(Utils.getDefaultTransport(), Utils.getDefaultJsonFactory(), new HttpCredentialsAdapter(sourceCredentials))
        .setApplicationName("MY_APP")
        .build();
  }

Add reflection hints for ErrorInfo.class

@Configuration
@ImportRuntimeHints(NativeImageHints.class)
class NativeImageHints implements RuntimeHintsRegistrar {
  @Override
  public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
    hints.reflection().registerType(ErrorInfo.class, (type) -> type.withConstructor(Collections.emptyList(), ExecutableMode.INVOKE));
  }
}

Directory api call

final Users batch = directory
            .users()
            .list()
            .setMaxResults(100)
            .setDomain("my-domain.com")
            .execute();

Build and run image

mvn clean spring-boot:build-image -e --no-transfer-progress -P native -D skipTests=true
docker run -p 8080:8080 my-app:0.0.1-SNAPSHOT

Result of directory execute()

2024-10-14T12:44:13.891Z  INFO 1 --- [my-app] [nio-8080-exec-1] c.google.api.client.http.HttpTransport   : {
  "error": {
    "code": 400,
    "message": "Bad Request",
    "errors": [
      {
        "message": "Bad Request",
        "domain": "global",
        "reason": "badRequest"
      }
    ]
  }
}

Reason
If I launch the app in DEBUG logging mode, I can see that the URL for the API query is not properly prepared :

curl -v --compressed 
-H 'Accept-Encoding: gzip' 
-H 'Authorization: <Not Logged>' 
-H 'User-Agent: MY_APP Google-API-Java-Client/2.7.0 Google-HTTP-Java-Client/1.45.0 (gzip)' 
-H 'x-goog-api-client: gl-java/21.0.4-graalvm gdcl/2.7.0 linux/6.8.0' -- 'https://admin.googleapis.com/admin/directory/v1/users'

instead of

curl -v --compressed 
-H 'Accept-Encoding: gzip' 
-H 'Authorization: <Not Logged>' 
-H 'User-Agent: MY_APP Google-API-Java-Client/2.7.0 Google-HTTP-Java-Client/1.45.0 (gzip)' 
-H 'x-goog-api-client: gl-java/21.0.4-graalvm gdcl/2.7.0 linux/6.8.0' -- 'https://admin.googleapis.com/admin/directory/v1/users?domain=my-domain.com&maxResults=100'
Dominant language
Java
Stars
725
Forks
394
Avg merge
42m
Merged PRs (30d)
257

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from googleapis/google-api-java-client-services

All issues in googleapis/google-api-java-client-services

Similar issues

More Java issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.