5

I seem to have hit a wall trying to get a Java application to list of files stored in my GoogleDrive folder. The

I have a project setup in the Developer Console. I have enabled for that project the Drive API I have create Auth credentials for a Service Account - and am using the P12 key produced.

My code looks like this :

import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.auth.oauth2.CredentialRefreshListener;
import com.google.api.client.auth.oauth2.TokenErrorResponse;
import com.google.api.client.auth.oauth2.TokenResponse;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.HttpTransport;
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.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.FileList;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Collections;
import java.util.List;

public class GoogleDriveTest {

    /** Global instance of the JSON factory. */
    private static final JsonFactory JSON_FACTORY = new JacksonFactory() ;

    /** instance of the HTTP transport. */
    private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport() ;

    /** Global instance of the Google Drive - the first connect will initialize */
    private static Drive drive;

    /*
     * instance variables
     */
    private String accessToken ;

    public static void main(String[] args) throws GeneralSecurityException, IOException {

        String CLIENTID = "XXXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@developer.gserviceaccount.com" ;
        String CLIENTUSER = "XXXXXXXX@gmail.com" ;
        String P2FILE = "random/src/main/resources/test.p12" ;

        try {
            GoogleCredential credential = new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)
                    .setJsonFactory(JSON_FACTORY)
                    .setServiceAccountId(CLIENTID)
                    .setServiceAccountScopes(Collections.singleton(DriveScopes.DRIVE_FILE))
                    .setServiceAccountPrivateKeyFromP12File(new java.io.File(P2FILE))
                    .setServiceAccountUser(CLIENTUSER)
                    .addRefreshListener(new CredentialRefreshListener() {
                        @Override
                        public void onTokenResponse(
                                Credential credential,
                                TokenResponse tokenResponse) throws IOException {

                            String token = tokenResponse.getAccessToken();
                            System.out.println("GOOGLEDRIVE token refreshed " + tokenResponse.getTokenType() + " successfully");
                        }

                        @Override
                        public void onTokenErrorResponse(
                                Credential credential,
                                TokenErrorResponse tokenErrorResponse) throws IOException {

                            System.out.println("GOOGLEDRIVE token refresh failure : " + tokenErrorResponse);
                        }
                    })
                    .build();

            /*
             * set up the global Drive instance
             */
            drive = new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential).setApplicationName("API Project").build();

            /*
             * output results
             */
            Drive.Files.List fileRequest = drive.files().list() ;
            FileList afiles = fileRequest.execute() ;
            List<File> bFiles = afiles.getItems() ;
            for(File file : bFiles) {
                System.out.println(file.getTitle()) ;
             }
        }
        catch (GeneralSecurityException | IOException e) {
            e.printStackTrace();
        }

    }

}

But the output I see is this :

GOOGLEDRIVE token refresh failure : null
com.google.api.client.auth.oauth2.TokenResponseException: 401 Unauthorized
    at com.google.api.client.auth.oauth2.TokenResponseException.from(TokenResponseException.java:105)
    at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:287)
    at com.google.api.client.auth.oauth2.TokenRequest.execute(TokenRequest.java:307)
    at com.google.api.client.googleapis.auth.oauth2.GoogleCredential.executeRefreshToken(GoogleCredential.java:384)
    at com.google.api.client.auth.oauth2.Credential.refreshToken(Credential.java:489)
    at com.google.api.client.auth.oauth2.Credential.intercept(Credential.java:217)
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:859)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
    at GoogleDriveTest.main(GoogleDriveTest.java:81)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

Process finished with exit code 0

Can anyone provide some pointers on Service Account access to Google Drive and what I might be doing wrong here ?

As the Service Account is created under my Google Account (XXXXXXXX@gmail.com) I assumed it would have access to the Drive once the API was enabled.

I have seen other posts about granting access to Service Accounts to a domain account via an admin console - but my account is a plain / standard google account. I'm not even sure what a domain account is !

All help would be greatly appreciated.

Thanky George
  • 51
  • 1
  • 2
  • 1
    A service account is not you. It doesn't have access to the drive account associated with your Gmail address until you grant it access buy adding the service account email address to the directory as a user. A service account has its own Google drive account files will be uploaded to that. (your error means that login isn't working, I am not a Java person so cant help with that. ) – Linda Lawton - DaImTo Mar 26 '15 at 11:36
  • This confusion between Service Accounts and regular accounts keeps coming up. See http://stackoverflow.com/questions/28580392/google-drive-api-access-my-own-account/28582334#28582334 for example. – pinoyyid Mar 26 '15 at 15:32
  • I'm having the exact same problem trying to use the GMail REST API. I didn't find an explanation of the differences between Service Accounts and regular accounts in the link above either. – JJensL Apr 02 '15 at 15:51

0 Answers0