7

Hi I've an issue with Java SDK library for Google Cloud.

I need to query Dialogflow V2 API and I'm using this SDK (https://github.com/GoogleCloudPlatform/google-cloud-java/tree/master)

I've followed the instructions in order to set GOOGLE_APPLICATION_CREDENTIALS as environment variable.

I did several attempts (I'm using a Mac):

export GOOGLE_APPLICATION_CREDENTIALS=path/to/my.json

doesn't work

putting

export GOOGLE_APPLICATION_CREDENTIALS=path/to/my.json

in .bash_profile

doesn't work

In my Java code:

System.setProperty("GOOGLE_APPLICATION_CREDENTIALS", "/path/to/my.json");
GoogleCredential credential = GoogleCredential.getApplicationDefault();

doesn't work

String jsonPath = "/path/to/my.json";
GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(jsonPath));
Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();

doesn't work

putting GOOGLE_APPLICATION_CREDENTIALS as environment variable in Eclipse by "Maven build > Environment > New variable" and restarted IDE

doesn't work

The same error always occurs:

An error occurred during Dialogflow http request: The Application Default Credentials are not available. They are available if running in Google Compute Engine. Otherwise, the environment variable GOOGLE_APPLICATION_CREDENTIALS must be defined pointing to a file defining the credentials. See https://developers.google.com/accounts/docs/application-default-credentials for more information.
java.io.IOException: The Application Default Credentials are not available. They are available if running in Google Compute Engine. Otherwise, the environment variable GOOGLE_APPLICATION_CREDENTIALS must be defined pointing to a file defining the credentials. See https://developers.google.com/accounts/docs/application-default-credentials for more information

Really I can't undestand what is wrong.

This is the code snippet to query Dialogflow never reached due to the above error:

SessionsClient sessionsClient = SessionsClient.create();
SessionName session = SessionName.of("my-project-id", sessionId);
InputStream stream = new ByteArrayInputStream(requestBody.getBytes(StandardCharsets.UTF_8));
QueryInput queryInput = QueryInput.newBuilder().build().parseFrom(stream);
DetectIntentResponse response = sessionsClient.detectIntent(session, queryInput);  

Exception is raised on

SessionsClient sessionsClient = SessionsClient.create();

Thanks in advance.

Jinjun
  • 381
  • 2
  • 11
HK15
  • 737
  • 1
  • 14
  • 32
  • Enviromnment variable modifications need to restart your computer to take effect, but I imagine that you have already done it – Jul10 May 12 '18 at 13:23
  • Yes, done it but ... it doesn't work – HK15 May 14 '18 at 06:11
  • 1
    The solution was to set GOOGLE_APPLICATION_CREDENTIALS as environment variable for the Application Server – HK15 Jun 06 '18 at 16:03
  • I rolled back the edit to your question. We don't mark questions by putting "SOLVED" in the title and we don't write answers in the question body. A question is a question is a question. Please add a new answer instead below. – Max Vollmer Jun 06 '18 at 16:21
  • 1
    @Yuri I am getting the same problem. How do you set variable for the application server? – Mr. D Apr 02 '19 at 16:00

2 Answers2

4

The solution is to set GOOGLE_APPLICATION_CREDENTIALS as environment variable for the Application Server.

Jinjun
  • 381
  • 2
  • 11
-2

Unlike mentioned in question, I've got 'credentials' working when provided that way

Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();

But same approach with FirestoreOptions failed with mentioned error "The Application Default Credentials are not available".

Note: I'm willing to not configure my app via environment variable and prefer doing it in code. One more reason for that - I need multiple different connections from one app.

After debugging into Google's code I've found that they do not use supplied credentials, they rather call getCredentialsProvider() on provided options. I think this is bug in their implementation, but workaround is rather simple:

  1. Create own CredentialsProvider
  2. Set it into FirestoreOptions

Dummy sample:

public static class MyCredentialsProvider implements CredentialsProvider {
    GoogleCredentials credentials;

    public MyCredentialsProvider(GoogleCredentials credentials) {
        this.credentials = credentials;
    }

    @Override
    public Credentials getCredentials() throws IOException {
        return credentials;
    }
}

...

FirestoreOptions.Builder builder = FirestoreOptions.newBuilder()
        .setProjectId(serviceAccount.project_id)
        .setCredentialsProvider(new MyCredentialsProvider(credentials));
Xtra Coder
  • 3,389
  • 4
  • 40
  • 59