17

I had created some tool which was populating the google spreadsheet. It was working fine for 1 year, since today I've error

Exception in thread "main" com.google.gdata.util.AuthenticationException: Error authenticating (check service name)
at com.google.gdata.client.GoogleAuthTokenFactory.getAuthException(GoogleAuthTokenFactory.java:688)
at com.google.gdata.client.GoogleAuthTokenFactory.getAuthToken(GoogleAuthTokenFactory.java:560)
at com.google.gdata.client.GoogleAuthTokenFactory.setUserCredentials(GoogleAuthTokenFactory.java:397)
at com.google.gdata.client.GoogleService.setUserCredentials(GoogleService.java:364)
at com.google.gdata.client.GoogleService.setUserCredentials(GoogleService.java:319)
at com.google.gdata.client.GoogleService.setUserCredentials(GoogleService.java:303)

This is the part of code to connect with gmail:

String USERNAME = "usename@........com"; ->of course I'm using proper username and password
    String PASSWORD = "*******";
    SpreadsheetService service
            = new SpreadsheetService("SandboxCheck");
    service.setUserCredentials(USERNAME, PASSWORD);

I don't know how to connect with gmail, I was trying to do this via oAuth but I don't know how to do this. In examples on https://developers.google.com/google-apps/spreadsheets/authorize there is only code for .net.

Mogsdad
  • 44,709
  • 21
  • 151
  • 275
Skwarosz
  • 369
  • 1
  • 2
  • 8
  • I suspect you are hitting two issues. 1) OpenAuth 1 / Client Login is not longer supported and 2) Documents List API is depreciated, so you need to migrate to the Drive API to create a spreadsheet. Unfortunately, I don't have examples for you on how to do this in Java. – daryl May 27 '15 at 14:04
  • It's looked this way that Client Login is no longed supported. I hope they will update the Spreed API page and they will give example how to use it in Java. – Skwarosz May 27 '15 at 17:02
  • Same problem here, since yesterday! Have they dropped support for App Password authentication? – Dimitris Sfounis May 27 '15 at 22:51

3 Answers3

18

I finally with help from here managed to create such connection. Everything is working as before. Steps You have to do is:

  1. Register at https://console.developers.google.com
  2. Create new project
  3. Under APIs & Auth -> Credential -> Create New Client ID for Service Account
  4. When the Client ID is generated You have to generate P12 key.
  5. Client id will be needed in code below, Email addres is the addres You have to share Your spreadsheet

Below is the working code

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.jackson.JacksonFactory;
import com.google.gdata.client.spreadsheet.SpreadsheetService;
import com.google.gdata.data.spreadsheet.SpreadsheetEntry;
import com.google.gdata.data.spreadsheet.SpreadsheetFeed;
import com.google.gdata.util.ServiceException;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.List;
public class OAuthIntegration{
    public static void main(String[] args) throws MalformedURLException, GeneralSecurityException, IOException, ServiceException {
        URL SPREADSHEET_FEED_URL;
        SPREADSHEET_FEED_URL = new URL("https://spreadsheets.google.com/feeds/spreadsheets/private/full");

        File p12 = new File("./key.p12");

        HttpTransport httpTransport = new NetHttpTransport();
        JacksonFactory jsonFactory = new JacksonFactory();
        String[] SCOPESArray = {"https://spreadsheets.google.com/feeds", "https://spreadsheets.google.com/feeds/spreadsheets/private/full", "https://docs.google.com/feeds"};
        final List SCOPES = Arrays.asList(SCOPESArray);
        GoogleCredential credential = new GoogleCredential.Builder()
                .setTransport(httpTransport)
                .setJsonFactory(jsonFactory)
                .setServiceAccountId("cliend_ID")
                .setServiceAccountScopes(SCOPES)
                .setServiceAccountPrivateKeyFromP12File(p12)
                .build();

        SpreadsheetService service = new SpreadsheetService("Test");

        service.setOAuth2Credentials(credential);
        SpreadsheetFeed feed = service.getFeed(SPREADSHEET_FEED_URL, SpreadsheetFeed.class);
        List<SpreadsheetEntry> spreadsheets = feed.getEntries();

        if (spreadsheets.size() == 0) {
            System.out.println("No spreadsheets found.");
        }

         SpreadsheetEntry spreadsheet = null;
        for (int i = 0; i < spreadsheets.size(); i++) {
            if (spreadsheets.get(i).getTitle().getPlainText().startsWith("ListOfSandboxes")) {
                spreadsheet = spreadsheets.get(i);
                System.out.println("Name of editing spreadsheet: " + spreadsheets.get(i).getTitle().getPlainText());
                System.out.println("ID of SpreadSheet: " + i);
            }
        }

    }

}

I hope this will help with issues I've faced. This is the list of jar I've used:

guava-11.0.2.jar
gdata-spreadsheet-3.0.jar
gdata-maps-2.0.jar
gdata-core-1.0.jar
jackson-core-asl-1.9.11.jar
jackson-core-2.1.3.jar
google-oauth-client-1.20.0.jar
google-http-client-jackson2-1.20.0.jar
google-http-client-jackson-1.20.0.jar
google-http-client-1.20.0.jar
google-api-client-1.20.0.jar
Skwarosz
  • 369
  • 1
  • 2
  • 8
  • 2
    Thank you Skwarsz. One minor clarification for others. In Step 4 the Console will offer you "Client ID" and "Email address". (a) you need the "Email address" to use in the setServiceAccountId() method call (not the ID despite the method name). (b) you need to share your spreadsheet with that same email address – AndrewL May 31 '15 at 19:47
  • The ``SCOPES`` variable defined in the code for spreadsheets documents should be: ``static final List SCOPES_ARRAY = Arrays.asList("https://spreadsheets.google.com/feeds", "https://spreadsheets.google.com/feeds/spreadsheets/private/full", "https://docs.google.com/feeds")`` – Mariano Ruiz Jun 01 '15 at 20:20
  • 2
    Thanks Skwarsz. One minor point though: I think you need ***gdata-core-1.47.1.jar*** instead of gdata-core-1.0.jar you are using. Version 1.0 does not recognize setOAuth2Credentials() method of SpreadsheetService class. – davak Jun 16 '15 at 13:40
  • @Skvarosz: I actually found out that gdata-spreadsheet.jar and gdata-core.jara overlap. For me, removing the gdata-spreadsheet.jar worked. Consider checking whether it is/isn't redundant in your project too. – davak Jun 22 '15 at 17:05
  • Is anyone else getting Caused by: com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request { "error" : "invalid_grant" } ? I feel like I followed everything to the t. BTW, by "cliend_ID" do you mean "client_ID"? – Ji Mun Jun 23 '15 at 18:01
  • replace "cliend_ID"with email address - GOTCHA (finally) – Ji Mun Jun 23 '15 at 18:31
  • Thanks a bunch! Why couldn't Google include an example like this in their docs... – Barsum Jul 16 '15 at 21:43
  • 1
    where to save p12 key file ? – John Oct 07 '15 at 16:18
  • how can i get p12 key file? – Sumeet Vishwas Jun 28 '17 at 07:58
  • Hello Sumeet,I saw that console.developers.google.com changed the view. In order to get the key You need to go to Service Accounts then on right there are 3 dots, press them and choose Create Key, and select p12. – Skwarosz Jun 29 '17 at 09:36
4

Google just stopped support OAuth1.0. OAuth2 needs to be used. To switch, first go to Google Developer Console, create a project and set a credential. Then update your code similar to the following Java code:

private void createSpreadSheetService() throws GeneralSecurityException, IOException, ServiceException {
   HttpTransport httpTransport = new NetHttpTransport();
   JacksonFactory jsonFactory = new JacksonFactory();
   String [] SCOPESArray= {"https://spreadsheets.google.com/feeds", "https://docs.google.com/feeds"};
   final List SCOPES = Arrays.asList(SCOPESArray);
   GoogleCredential credential = new GoogleCredential.Builder()
     .setTransport(httpTransport)
     .setJsonFactory(jsonFactory)
     .setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
     .setServiceAccountScopes(SCOPES)
     .setServiceAccountPrivateKeyFromP12File(SERVICE_ACCOUNT_PKCS12_FILE)
     .build();

   SPREADSHEETSERVICE = new SpreadsheetService("data");
   SPREADSHEETSERVICE.setOAuth2Credentials(credential);

}

You would need two libraries: google-api-client and google-http-client-jackson. If you use Maven, including the following dependencies in pom.xml.

 <dependency>
  <groupId>com.google.api-client</groupId>
  <artifactId>google-api-client</artifactId>
  <version>1.19.0</version>
  <type>jar</type>
 </dependency>
 <dependency>
  <groupId>com.google.http-client</groupId>
  <artifactId>google-http-client-jackson</artifactId>
  <version>1.19.0</version>
  <type>jar</type>
 </dependency>
Gao
  • 1,527
  • 1
  • 9
  • 3
  • The reason: OpenAuth 1 / Client Login is not longer supported. As the wrote here https://code.google.com/p/gdata-issues/issues/detail?can=2&start=0&num=100&q=&colspec=API%20ID%20Type%20Status%20Priority%20Stars%20Summary&groupby=&sort=&id=2717 – Skwarosz May 28 '15 at 07:42
  • Where do you import `JacksonFactory` from? – Dimitris Sfounis May 28 '15 at 14:49
  • 1
    What exacly libs are needed in order to run this `createSpreadSheetService` ? – Skwarosz May 28 '15 at 17:14
  • Gao can You please tell me what libraries You've used to make this code works ? I'm all the time facing exceptions and other errors. – Skwarosz May 29 '15 at 11:39
1

I've tried solution from Gao but I have one problem with Libraries. I'm using netbeans, the project is building without error but when I'm trying to execute it I've this error:

 Exception in thread "main" java.lang.NoClassDefFoundError: org/codehaus/jackson/JsonFactory
at com.google.api.client.json.jackson.JacksonFactory.<init>(JacksonFactory.java:38)
at SandboxCheck.main(SandboxCheck.java:48) 

I found out that there are problem with classpath but I have no idea how to fix it on netbeans, I thought it would do it automatically when adding a library. I've added

google-oauth-client-1.16.0-rc.jar google-oauth-client-1.16.0-rc-sources.jar google-api-client-1.8.0-beta-sources.jar google-api-client-1.4.1-beta.jar google-api-client-1.19.1.jar

I'm not sure If I add too much of this libraries but If I remove for eg. google-api-client-1.4.1-beta.jar it won't see JacksonFactory class.

Skwarosz
  • 369
  • 1
  • 2
  • 8
  • Exact same problem here too. – Dimitris Sfounis May 28 '15 at 14:49
  • *UPDATE*: Managed to solve it by `import com.fasterxml.jackson.core.*;`. I don't know what the hell I'm doing or what is going on. – Dimitris Sfounis May 28 '15 at 15:23
  • How did manage to make it work Dimitris by this import, because it's using JsonFactory not JacksonFactory and I still have this issue. – Skwarosz May 28 '15 at 16:18
  • `JsonFactory` is an abstract superclass, your problem comes at `JacksonFactory` being unable to find a define. Include `jackson-core-2.1.3.jar` to your project's libraries and import what I wrote. It'll probably go through. – Dimitris Sfounis May 28 '15 at 16:36
  • I've faced `Exception in thread "main" java.lang.AbstractMethodError: com.google.api.client.json.JsonFactory.createJsonGenerator(Ljava/io/OutputStream;Ljava/nio/charset/Charset;)Lcom/google/api/client/json/JsonGenerator;` on `SpreadsheetFeed feed = service.getFeed(SPREADSHEET_FEED_URL, SpreadsheetFeed.class);` – Skwarosz May 28 '15 at 16:52
  • I know this is too late, but I tried the above approach, I have my keys for generating the .p12 file being used from the keychain access, please not I just used the keys from my company provided laptop. And exported them on to Desktop and now I end up getting:java.io.IOException: failed to decrypt safe contents entry: javax.crypto.BadPaddingException: Given final block not properly padded is it because I am using p12 from my office laptop, and using client Id generated for a different email in google apps? – ApJo Nov 22 '15 at 01:50