Search code examples
javakotlingraalvm-native-imagequarkus-native

Quarkus native executable & google-oauth-client


I've added a sample project here that replicates the issue.

My goal is to simply build a GoogleAuthorizationCodeRequestUrl. What is interesting about it is that a set of map entries that is fully "hydrated" running on JVM is empty when executing the native executable.

enter image description here

I've tried registering classes for reflection with no success. Here is an example (from the file reflection-config.json):

[
    {
        "name": "com.google.api.client.http.GenericUrl"
    }
]

Any thoughts?

My guess is that this has something to do with API's way of transporting data:

public class GenericData extends AbstractMap<String, Object> 

Solution

  • It turns out that it does have something to do with the way data is transported.

    In the snippet below, you will notice that the @Key annotation is used to generate the actual key when hydrating the entry set.

    public final class Userinfo extends GenericJson {
        @Key
        private String email;
        @Key("family_name")
        private String familyName;
        ...
    

    It turns out that this approach is widely used on libs that depend on google-http-client.

    I am using Kotlin, so my solution was to do this:

    @RegisterForReflection(
        targets = [
            // google-http-client
            com.google.api.client.http.HttpHeaders::class,
            com.google.api.client.json.rpc2.JsonRpcRequest::class,
            com.google.api.client.json.webtoken.JsonWebSignature::class,
            com.google.api.client.json.webtoken.JsonWebToken.Header::class,
            // google-api-client
            com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeRequestUrl::class,
            com.google.api.client.googleapis.auth.oauth2.GoogleBrowserClientRequestUrl::class,
            com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets::class,
            com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets.Details::class,
            com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload::class,
            com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse::class,
            com.google.api.client.googleapis.json.GoogleJsonError.ErrorInfo::class,
            com.google.api.client.googleapis.json.GoogleJsonError.Details::class,
            com.google.api.client.googleapis.json.GoogleJsonError.ParameterViolations::class,
            com.google.api.client.googleapis.json.GoogleJsonError::class,
            com.google.api.client.googleapis.json.GoogleJsonErrorContainer::class,
            com.google.api.client.googleapis.mtls.ContextAwareMetadataJson::class,
            // google-api-services-oauth2-v2
            com.google.api.services.oauth2.model.Userinfo::class,
            com.google.api.services.oauth2.model.Tokeninfo::class,
            com.google.api.services.oauth2.Oauth2.Tokeninfo::class,
            com.google.api.services.oauth2.Oauth2.Userinfo.Get::class,
            com.google.api.services.oauth2.Oauth2.Userinfo.V2.Me::class,
            com.google.api.services.oauth2.Oauth2.Userinfo.V2.Me.Get::class,
            // google-oauth-client
            com.google.api.client.auth.oauth.OAuthAuthorizeTemporaryTokenUrl::class,
            com.google.api.client.auth.oauth.OAuthCallbackUrl::class,
            com.google.api.client.auth.oauth.OAuthCredentialsResponse::class,
            com.google.api.client.auth.oauth2.AuthorizationCodeRequestUrl::class,
            com.google.api.client.auth.oauth2.AuthorizationCodeResponseUrl::class,
            com.google.api.client.auth.oauth2.AuthorizationCodeTokenRequest::class,
            com.google.api.client.auth.oauth2.AuthorizationRequestUrl::class,
            com.google.api.client.auth.oauth2.PasswordTokenRequest::class,
            com.google.api.client.auth.oauth2.RefreshTokenRequest::class,
            com.google.api.client.auth.oauth2.TokenErrorResponse::class,
            com.google.api.client.auth.oauth2.TokenRequest::class,
            com.google.api.client.auth.oauth2.TokenResponse::class,
            com.google.api.client.auth.openidconnect.IdToken.Payload::class,
            com.google.api.client.auth.openidconnect.IdTokenResponse::class
            // @TODO: This must be fixed first
            // https://github.com/googleapis/google-oauth-java-client/issues/947
            // com.google.api.client.auth.openidconnect.IdTokenVerifier.PublicKeyLoader.JsonWebKeySet::class
            // com.google.api.client.auth.openidconnect.IdTokenVerifier.PublicKeyLoader.JsonWebKey::class
        ]
    )
    class ReflectionConfig
    

    I hope that will help someone else.