0

I'm using Google API in Java and have the following code snippets.

    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.FileInputStream;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.security.GeneralSecurityException;
    import java.util.Collections;
    import java.util.List;
    import java.lang.Object;
    import java.util.ArrayList;

    import com.google.api.client.auth.oauth2.Credential;
    import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
    import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
    import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
    import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
    import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
    import com.google.api.client.http.javanet.NetHttpTransport;
    import com.google.api.client.json.JsonFactory;
    import com.google.api.client.json.jackson2.JacksonFactory;
    import com.google.api.client.util.store.FileDataStoreFactory;
    import com.google.api.services.drive.Drive;
    import com.google.api.services.drive.Drive.Files;
    import com.google.api.services.drive.DriveScopes;
    import com.google.api.services.drive.model.File;
    import com.google.api.services.drive.model.FileList;


    public class DriveQuickstart {

        private static final String APPLICATION_NAME = "DriveQuickstart";
        private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
        private static final String TOKENS_DIRECTORY_PATH = "tokens";

        // * Global instance of the scopes required by this quickstart.
        // * If modifying these scopes, delete your previously saved tokens/ folder.

        private static final List<String> SCOPES = Collections.singletonList(DriveScopes.DRIVE_METADATA_READONLY);
        private static final String CREDENTIALS_FILE_PATH = "C:/Quickstart/src/main/resources/client_secret.json";

// * Creates an authorized Credential object.
// * @param HTTP_TRANSPORT The network HTTP Transport.
// * @return An authorized Credential object.
// * @throws IOException If the client_secret.json file cannot be found.
// */
private static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT) throws IOException {
    // Load client secrets.
    InputStream in = new FileInputStream(CREDENTIALS_FILE_PATH);
    if (in == null) {
        throw new FileNotFoundException("Resource not found: " + CREDENTIALS_FILE_PATH);
    }
    GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));

    // Build flow and trigger user authorization request.
    GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
            HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
            .setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
            .setAccessType("offline")
            .build();
    LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build();
    return new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");

}

public static void main(String[] args) throws IOException, GeneralSecurityException {
    try
    {
    // Build a new authorized API client service.
    System.out.println("This is a test line");

    //declare final variable NetHttpTransport and GoogleNetHttpTransport from import statements
    final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
    System.out.println("This is the second test line");
    Drive service = new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
            .setApplicationName(APPLICATION_NAME)
            .build();

    System.out.println("This is the third test line");

    // Print the names and IDs for files.
    FileList result = service.files().list()
            .setPageSize(10)
            .setFields("nextPageToken, files(id, name)")
            .execute();
    List<File> files = result.getFiles();
    if (files == null || files.isEmpty()) {
        System.out.println("No files found.");
    } else {
        System.out.println("Files:");
        for (File file : files) {
            System.out.printf("%s (%s)\n", file.getName(), file.getId());
        }
    }
    Drive.Files var1 = service.files();
    System.out.println("var1 = " + var1.toString());
    Drive.Files.List var2 = var1.list();
    if (var2 == null)
        System.out.println("null");
    else {
        System.out.printf("Var2 size is: %d\n", var2.size() );
    }
    //iterate through map and print results
    }
    catch(Exception  e){
        System.out.println("error");
    }

    System.out.println("This is the fourth test line");

}

    }

    }    

To go more into detail. I'm using a somewhat unconventional method to try it. I'm using only command line to run (no IDEs, no gradle).

Here is a link to an ss with my output in command prompt. cmd output

Assuming that I am actually accessing the metadata in Google Drive, and that the Drive.Files is nested inside an Abstract Map (java.util.AbstractMap), I should be able to return the size of the map to get an idea of where it it searching by how many files it is returning.

I'm not sure what is going on. First time I compile and run, I get the tab opening in chrome asking for permission to gain access to metadata to drive. Second time, it gives the "WARNING: unable to change permissions for everybody: " errors. On top of that, var1 ('set to service.files()') returns com.google.api.services.drive.Drive$Files@458ad742 when using toString(). The subclass service.files().list() assigned to var2 should return a list of files in my Google Drive, but apparently it is not doing so.

I may be misunderstanding a lot of stuff, so bear with me. Thanks for the help.

In case people ask, I have tried the tutorial here https://developers.google.com/drive/api/v3/quickstart/java It opened the tab to ask for metadata access to google drive on whichever google account I selected.

storedcredential

So from that alone, I (think) connected to Google Drive. However, the default code that is supposed to list the names and ids of 10 files doesn't do anything.

How am I running the program: Here is the batch file that I'm using to compile and run the code in cmd.

    jar cfe DriveQuickstart.jar Quickstart DriveQuickstart.class
    javac -cp ./* DriveQuickstart.java
    java -cp ./* DriveQuickstart

For some reason I don't know/understand, this was the only way that wouldn't return methods from the imported jar files not existing.

Psi
  • 61
  • 10

1 Answers1

0

Familiarize yourself with the Java Quickstart to see how to get the results of the API calls.

Problems

1 - setPermissionsToOwnerOnly

I'm not sure what is going on. First time I compile and run, I get the tab opening in chrome asking for permission to gain access to metadata to drive. Second time, it gives the "WARNING: unable to change permissions for everybody: " errors.

This seems to be related to this issue. It could mean that the folder you are using to run your code from has different permissions than expected.

Does this happen if you place your code on your Desktop (as example) and then run it from there?

2 - toString()

On top of that, var1 ('set to service.files()') returns com.google.api.services.drive.Drive$Files@458ad742 when using toString(). The subclass service.files().list() assigned to var2 should return a list of files in my Google Drive, but apparently it is not doing so.

This weird looking string is how Java prints out an instance of a class.

com.google.api.services.drive.Drive$Files@458ad742
<NAMESPACE>$<CLASS>@<HASHCODE>

The fact that the toString method prints this out means that this method wasn't overwritten for this specific Class, so its calling the general Object.toString() method.

To print out what you want to see, try the nested methods.

Community
  • 1
  • 1
ZektorH
  • 2,680
  • 1
  • 7
  • 20
  • I have followed the tutorial, and I got the tab in chrome to open to ask for permission to access metadata. My problem after is that the code to print names and ids of the 10 files is not running. So I'm trying to manually check to see if it is accessing Drive.Files and it's subclasses by returning values that indicate that it has SOMETHING. – Psi Nov 07 '19 at 17:05
  • Hello @Phanotak, after giving the permissions to the application, what do you see? Please add full log outputs and screenshots if possible. – ZektorH Nov 08 '19 at 08:15
  • posted full code and added a screenshot of my command prompt output and the google tab it opens. If I delete the StoredCredential and run it, it opens up the google tab, does the unsafe notification, chooses account and asks for permission to access metadata on google drive. – Psi Nov 08 '19 at 18:07
  • I don't know if it might have anything to do with this link. https://github.com/googleapis/google-http-java-client/issues/315 – Psi Nov 08 '19 at 18:14
  • @Phanotak I've updated the answer, please let me know if it helps you or if you still see the problems. – ZektorH Nov 11 '19 at 08:29
  • 1
    Got it working. All I did was redo the tutorial and place it directly into C://Quickstart, not some convoluted long directory name going into 4-5 sub-folders. Thank you for the help though, I really appreciate having someone willing to help out. – Psi Nov 13 '19 at 20:30
  • @Phanotak glad to be of help. Take care. – ZektorH Nov 14 '19 at 07:57
  • Was wondering if you could help me with another problem. Question is here. https://stackoverflow.com/questions/58945797/google-drive-api-not-downloading-files-java-v3 – Psi Nov 20 '19 at 02:38