googleapis / google-cloud-java

Google Cloud Client Library for Java
https://cloud.google.com/java/docs/reference
Apache License 2.0
1.86k stars 1.06k forks source link

[Secrets Manager]Java Maven: Configuring GCP Secret Manager. "Type" Not Accessible Error #10975

Closed phillipshaong closed 1 week ago

phillipshaong commented 2 weeks ago

Issue

I would like to use GCP Secrets Manager for my Java application. The main trouble comes when using the module-info.java file, if I use a version of Java less than 9 that doesn't have the module-info.java file, then it works fine. The main error that comes up is The import com.google.cloud.secretmanager.v1.{Class Name} cannot be resolved Java (268435846)., and that applies to the following classes:

AccessSecretVersionResponse
ProjectName
Replication
Secret
SecretPayload
SecretVersion

The only class that correctly imports is SecretManagerServiceClient.

Environment details

  1. OS type and version: M1 Pro 14.5 (23F79)
  2. Java version: 11 & 21
  3. Version(s): libraries-bom (26.32.0)

Steps to reproduce

LINK TO REPRODUCIBLE CODE: https://github.com/phillipshaong/java-gcp-secrets-manager-test/tree/main

  1. Create a new MVN project mvn archetype:generate in a new folder, following prompts.
  2. Add the following code in pom.xml in their respective areas to turn it into a Java Version 11 or 21 project
    <properties>
    <java.version>11</java.version> <!-- Can also be 21 -->
    </properties>
    <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
          <configuration>
            <source>11</source>  <!-- Can also be 21 -->
            <target>11</target>    <!-- Can also be 21 -->
          </configuration>
        </plugin>
  3. Copy and paste quickstart instructions from https://cloud.google.com/secret-manager/docs/reference/libraries#client-libraries-install-java in the main Java file.

Code example

package app;

import com.google.cloud.secretmanager.v1.AccessSecretVersionResponse;
import com.google.cloud.secretmanager.v1.ProjectName;
import com.google.cloud.secretmanager.v1.Replication;
import com.google.cloud.secretmanager.v1.Secret;
import com.google.cloud.secretmanager.v1.SecretManagerServiceClient;
import com.google.cloud.secretmanager.v1.SecretPayload;
import com.google.cloud.secretmanager.v1.SecretVersion;
// import com.google.protobuf.ByteString;

public class Quickstart {

    public void quickstart() throws Exception {
        // TODO(developer): Replace these variables before running the sample.
        String projectId = "your-project-id";
        String secretId = "your-secret-id";
        quickstart(projectId, secretId);
    }

    public void quickstart(String projectId, String secretId) throws Exception {
        // Initialize client that will be used to send requests. This client only needs
        // to be created
        // once, and can be reused for multiple requests. After completing all of your
        // requests, call
        // the "close" method on the client to safely clean up any remaining background
        // resources.
        try (SecretManagerServiceClient client = SecretManagerServiceClient.create()) {
            // Build the parent name from the project.
            ProjectName projectName = ProjectName.of(projectId);

            // Create the parent secret.
            Secret secret = Secret.newBuilder()
                    .setReplication(
                            Replication.newBuilder()
                                    .setAutomatic(Replication.Automatic.newBuilder().build())
                                    .build())
                    .build();

            Secret createdSecret = client.createSecret(projectName, secretId, secret);

            // Add a secret version.
            SecretPayload payload = SecretPayload.newBuilder().setData(ByteString.copyFromUtf8("hello world!")).build();
            SecretVersion addedVersion = client.addSecretVersion(createdSecret.getName(), payload);

            // Access the secret version.
            AccessSecretVersionResponse response = client.accessSecretVersion(addedVersion.getName());

            // Print the secret payload.
            //
            // WARNING: Do not print the secret in a production environment - this
            // snippet is showing how to access the secret material.
            String data = response.getPayload().getData().toStringUtf8();
            System.out.printf("Plaintext: %s\n", data);
        }
    }
}

Stack trace

N/A

External references such as API reference guides

-https://cloud.google.com/secret-manager/docs/reference/libraries#client-libraries-install-java

Any additional information below

N/A

Following these steps guarantees the quickest resolution possible.

Thanks!

suztomo commented 1 week ago

Checking.

suztomo commented 1 week ago

Thank you for preparing the project (https://github.com/phillipshaong/java-gcp-secrets-manager-test/tree/main). I opened the project in IntelliJ (Community Edition) and it asked to add lines to module-info.java for the missing packages:

Screenshot 2024-06-20 at 2 28 17 PM

After adding these lines, the module-info.java looks:

module com.gcp_secrets_manager_test.app {

    requires google.cloud.secretmanager;
    requires proto.google.cloud.secretmanager.v1;
    requires protobuf.java;

}

Even after the compilation errors disappear, the Java module system does not work; I got java: the unnamed module reads package com.google.cloud.secretmanager.v1 from both google.cloud.secretmanager and proto.google.cloud.secretmanager.v1.

I'm afraid that the Cloud SDK for Java does not work with the Java platform module system that use module-info.java.

phillipshaong commented 1 week ago

Thanks for checking @suztomo. Does that mean, at this moment, the Cloud Java SDK for Secret Manager doesn't work in a modularized project? Is there any workaround for that? My project needs to include the module-info.java file for other dependencies.

suztomo commented 1 week ago

I'm afraid that's the case. I created https://github.com/googleapis/google-cloud-java/issues/10979 for the issue.

The current known workaround is to repackage the JAR files. As we gather information, we'll enrich the issue. Of course, if you put the Cloud Java SDK for Secret Manager in the class path (not module paths), it just works fine. Module path and class path can coexist.

phillipshaong commented 1 week ago

Good to know, thank you for taking a look into it and the recommendation.