4

I'll premise that I've already googled and read the documentation before writing, I've noticed that it's a popular discussion here on StackOverflow as well, but none of the answers already given have helped me.

I created a Google Cloud account to use the API: Google Vision.

To do this I followed the steps of creating the project, adding the above API and finally creating a service account with a key.

I downloaded the key and put it in a folder in the java project on the PC.

Then, since it is a maven project I added the dependencies to the pom as described in the tutorials.

At this point I inserted the suggested piece of code to start using the API.

Everything seemed to be OK, everything was read, the various libraries/interfaces were imported.

But an error came up as soon as I tried to run the program:

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.

I must admit I didn't know what 'Google Compute Engine' was, but since there was an alternative and I had some credentials, I wanted to try and follow that.

So I follow the instructions:

After creating your service account, you need to download the service account key to your machine(s) where your application runs. You can either use the GOOGLE_APPLICATION_CREDENTIALS environment variable or write code to pass the service account key to the client library.

OK, I tried the first way, to pass the credentials via environment variable:

  • With powershell -> no response
$env:GOOGLE_APPLICATION_CREDENTIALS="my key path"
  • With cmd -> no response either
set GOOGLE_APPLICATION_CREDENTIALS=my key path

So I tried the second way, passing credentials using code and if I'm here something else must have gone wrong, in fact with what I have it was only possible to import io.grpc.Context, while everything else gives the error "Cannot resolve symbol ..".

import com.google.common.collect.Lists;
import io.grpc.Context;

import java.io.FileInputStream;
import java.io.IOException;

public class Main
{
    static void authExplicit(String jsonPath)
    {
        GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(jsonPath))
                .createScoped( Lists.newArrayList("https://www.googleapis.com/auth/cloud-platform"));
        Context.Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();

        System.out.println("Buckets:");
        Page<Bucket> buckets = storage.list();
        for (Bucket bucket : buckets.iterateAll()) {
            System.out.println(bucket.toString());
        }
    }

    public static void main(String[] args) throws IOException
    {
        OCR.detectText();
    }
}

(I don't think I can upload a screen of the code to show where it gives me errors, however it is this)

PS: I also already installed the Cloud SDK and restarted the PC because some comments said to do that to fix things.

I also tried setting the environment variable manually, but nothing changes: enter image description here

Solution

I don't know if it all worked out because of a series of operations I performed I for this one command line, anyway, for posterity's sake:

  • Fill in these fields manually using the email field in the json file and the path to the json file, both without inverted commas, then start cmd, paste the string and run!

gcloud auth activate-service-account your_account_email_id --key-file=json_file_path

It also helped me to reboot the PC afterwards.

Eugenio
  • 118
  • 1
  • 11
  • If you are on your workstation or on Google Cloud, you SHOULDN'T use a service account key file. That tutorial is bad. – guillaume blaquiere Jan 10 '22 at 21:27
  • @guillaumeblaquiere Hi, I followed [these guidelines](https://cloud.google.com/vision/docs/ocr?hl=it#vision_text_detection-java), I don't know if they are out of date.. – Eugenio Jan 10 '22 at 22:28
  • 1
    Yes, I know. I'm often fighting with Google Cloud about that documentation that advocate on bad practices. Not your fault, I'm just desperate to continue to see that such things in the documentation.... – guillaume blaquiere Jan 11 '22 at 08:13

1 Answers1

2

Please, consider read the ImageAnnotationClient class level javadocs, it gives you the right guidance about how to accomplish the authentication process. I modified the provided code to give you the full example:

// Please, set the appropriate path to your JSON credentials file here
String credentialsPath = "..."; 
// The credentials could be loaded as well as this.getClass().getResourceAsStream(), for example
GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(credentialsPath))
    .createScoped(Lists.newArrayList("https://www.googleapis.com/auth/cloud-platform"));

// Use that credentials to build your image annotation client
ImageAnnotatorSettings imageAnnotatorSettings =
  ImageAnnotatorSettings.newBuilder()
    .setCredentialsProvider(FixedCredentialsProvider.create(credentials))
    .build()
;

ImageAnnotatorClient imageAnnotatorClient = ImageAnnotatorClient.create(imageAnnotatorSettings);
// Perform the stuff you need to...

The only dependency you need to provide in your pom.xml is this:

<dependency>
    <groupId>com.google.cloud</groupId>
    <artifactId>google-cloud-vision</artifactId>
    <version>2.0.18</version>
</dependency>

In any case, please, consider for reference the pom.xml provided in the Cloud Vision examples.

The Cloud Vision examples repository gives some useful code snippets as well in the Detect class for the detection process itself.

Be sure that the service account you are using to connect to Google Cloud has the necessary permissions.

Although this solution could work, it has the drawback that you probably need to store the credentials file somewhere in your machine, maybe in your source code repository, etcetera, and it can suppose a security risk. If your are running your program from Google Cloud is always advisable to grant to the VM or service you are using the necessary permissions and use the default application credentials.

The use of the GOOGLE_APPLICATION_CREDENTIALS could be preferable as well. If you are trying using this variable, initially, try configuring it using your IDE provided mechanisms instead of cmd, PS, or bash, and see if it works.

For using any of the two last mentioned solutions you don't need to provide any additional information when constructing your ImageAnnotatorClient:

ImageAnnotatorClient imageAnnotatorClient = ImageAnnotatorClient.create();
jccampanero
  • 50,989
  • 3
  • 20
  • 49
  • Thank you very much for your well explained answer, I followed your steps to the letter: from replacing the code with ImageAnnotatorClient to modifying the pom (I had to copy the one in your link, because some dependencies for GoogleCredentials were missing) and finally replacing the ocr function with the one you proposed. I keep getting the same error. I also checked the permissions to the service account and I am owner, which together with editor seem to me the highest roles. – Eugenio Jan 10 '22 at 22:15
  • For the security issue I thank you for pointing it out, maybe it will be useful in the future, for the moment though I'm leaving everything local, I don't have large amounts of data on my hands, although once I've overcome that hurdle I'd like to try using ML applied to OCR as well, sounds like nice stuff. But one problem at a time... – Eugenio Jan 10 '22 at 22:15
  • Thank you very much for the feedback @Eugenio. I am sorry to hear that you are still facing the same problem. Please, could you further explain your setup? I mean, AFAIK, your IDE is telling you that `Cannot resolve symbol ..`. What IDE are you using? If you run Maven with `mvn compile` from the directory in which your `pom.xml` is located, do you still get the same errors? – jccampanero Jan 10 '22 at 22:29
  • I'm using IntelliJ as my IDE and it's a Maven project, yes, but I can't find the option to write that command line 'mvn compile' from within the code. If I run it from the Windows cmd it tells me it is not recognized. – Eugenio Jan 11 '22 at 10:04
  • Hi @Eugenio. Well, then probably you hadn't had installed maven in your machine, do not worry about that. From Intellij, try refreshing your maven project: right click in your `pom.xml` file in the file explorer, and select Maven > Reload project. It should download your dependencies. Please, could you try and see if the warnings disappear and everything is compiled fine? – jccampanero Jan 11 '22 at 10:10
  • Oh, I didn't think you meant that, I knew it, I used it from the right sidebar. I tried it but it always spits out that error. Since it's tied to the environment variable and the command line setting doesn't work for me, I tried doing it manually (I leave the screen in the main post), but even then it doesn't work, so I really don't understand.. – Eugenio Jan 11 '22 at 10:23
  • Please, set the environment variable in Intellij. You can do this like this. First, probably you have a run/debug configuration for your application. Open the application selector and then the first option "Edit configurations...". Select your application, and in the right zone of the screen, expand "Environment". In the expansion panel, at the last option, you will find "Environment variables". Include there the value for `GOOGLE_APPLICATION_CREDENTIALS`: `GOOGLE_APPLICATION_CREDENTIALS=P:\Java...`. Please, could you try? – jccampanero Jan 11 '22 at 10:36
  • Thank you, while you were answering I was looking for other options online and I found this command line: "gcloud auth activate-service-account --key-file=", if I entered it piece by piece it gave me an error, but if I manually pre-compiled it first and pasted it directly it said "Activated service account credentials", so I tried to run it, it didn't work, now I restarted the PC (considering that I had restarted it several times before) and it works!!! – Eugenio Jan 11 '22 at 10:47
  • I also inserted the environment variable you told me, but I can't say for sure if it would have solved the situation as well. In any case, I thank you for your great patience and availability. – Eugenio Jan 11 '22 at 10:47
  • You are welcome @Eugenio, I am glad to help. You activated the service account in your computer. Usually it is done in VM deployed in the cloud, for example, but I think it could be ok as well in your machine. Please, see the [relevant documentation](https://cloud.google.com/sdk/docs/authorizing). In any case, I hope that the provided configuration in the Intellij work properly as well. Please, do not hesitate to contact me again if you need further help. – jccampanero Jan 11 '22 at 11:39