App Engine specifically has a number of unusual security restrictions in file storage. I found the best place for reliable storage of resources - using the package itself. If you use the default Maven setting created by the appengine maven skeleton project, it's as simple as placing a file inside the corresponding resource directory

Once p12 is in the right place, you need to load it using the GetResourceAsStream function of the loader class. Then, when creating GoogleCredentials, do not use the documentation for setServiceAccountPrivateKeyFromP12File (), but instead use the setServiceAccountPrivateKey () function and pass the newly created PrivateKey.
In addition, you most likely will not want to use any of these functions with the live appengine instance, since Appengine already provides you with a much more convenient AppIdentityCredentials function in this case, so you probably want to determine if your application will be located in production mode and uses only ServiceAccount when testing using localhost.
Combining all these functions gives the following function that works for me:
public static HttpRequestInitializer getDefaultCredentials() throws IOException { List<String> scopes = Arrays.asList(new String[] {DEVSTORAGE_FULL_CONTROL}); if (SystemProperty.environment.value() == SystemProperty.Environment.Value.Production) return new AppIdentityCredential(scopes); else { GoogleCredential credential; try { String p12Password = "notasecret"; ClassLoader classLoader = ServiceUtils.class.getClassLoader(); KeyStore keystore = KeyStore.getInstance("PKCS12"); InputStream keyFileStream = classLoader.getResourceAsStream("key.p12"); if (keyFileStream == null){ throw new Exception("Key File Not Found."); } keystore.load(keyFileStream, p12Password.toCharArray()); PrivateKey key = (PrivateKey)keystore.getKey("privatekey", p12Password.toCharArray()); credential = new GoogleCredential.Builder() .setTransport(HTTP_TRANSPORT) .setJsonFactory(JSON_FACTORY) .setServiceAccountId(" YOUR_SERVICE_ACCOUNT_EMAIL@developer.gserviceaccount.com ") .setServiceAccountPrivateKey(key) .setServiceAccountScopes(scopes) .build(); } catch (GeneralSecurityException e) { e.printStackTrace(); return null; } catch (Exception e) { e.printStackTrace(); return null; } return credential; } }
source share