Skip to content

Commit 98c160e

Browse files
authored
fix regression on appEngine detection (googleapis#1109)
fix regression on appEngine detection, and small update to existing logic
1 parent dd99f73 commit 98c160e

2 files changed

Lines changed: 49 additions & 13 deletions

File tree

google-api-client/src/main/java/com/google/api/client/googleapis/auth/oauth2/DefaultCredentialProvider.java

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@
2929
import java.io.IOException;
3030
import java.io.InputStream;
3131
import java.lang.reflect.Constructor;
32+
import java.lang.reflect.Field;
3233
import java.lang.reflect.InvocationTargetException;
34+
import java.lang.reflect.Method;
3335
import java.security.AccessControlException;
3436
import java.util.Locale;
3537

@@ -169,7 +171,7 @@ private final Environment detectEnvironment(HttpTransport transport) throws IOEx
169171
return Environment.WELL_KNOWN_FILE;
170172

171173
// Try App Engine
172-
} else if (runningOnAppEngine()) {
174+
} else if (useGAEStandardAPI()) {
173175
return Environment.APP_ENGINE;
174176

175177
// Then try Cloud Shell. This must be done BEFORE checking
@@ -256,19 +258,56 @@ private GoogleCredential getCredentialUsingWellKnownFile(
256258
}
257259
}
258260

259-
260-
private boolean runningOnAppEngine() {
261+
private boolean useGAEStandardAPI() {
262+
// We should specifically return false in some cases in order to shortcircuit checking for
263+
// appengine classpath resources. This lets us flow into metadata server logic rather than
264+
// continuing to rely on jars on the classpath.
261265
if (getEnvEquals("GAE_ENV", "standard")) {
262-
return true;
266+
return getEnvEquals("GAE_RUNTIME", "java7");
263267
}
264-
if (getEnvEquals("GAE_RUNTIME", "java7")) {
265-
return true;
268+
if (getEnvEquals("GAE_VM", "true")) {
269+
return false;
266270
}
267-
if (getEnvEquals("GAE_RUNTIME", "java8")) {
268-
return true;
271+
272+
// Check the classpath for the existence of classes.
273+
Class<?> systemPropertyClass;
274+
try {
275+
systemPropertyClass = forName("com.google.appengine.api.utils.SystemProperty");
276+
} catch (ClassNotFoundException expected) {
277+
// We didn't find the class - move on.
278+
return false;
269279
}
270-
if (getEnvEquals("GAE_VM", "true")) {
271-
return true;
280+
281+
Exception cause = null;
282+
Field environmentField;
283+
try {
284+
// Use reflection to call com.google.appengine.api.utils.SystemProperty::environment.value().
285+
environmentField = systemPropertyClass.getField("environment");
286+
Object environmentValue = environmentField.get(null);
287+
Class<?> environmentType = environmentField.getType();
288+
Method valueMethod = environmentType.getMethod("value");
289+
Object environmentValueValue = valueMethod.invoke(environmentValue);
290+
291+
// Any value will be treated as "running on app engine standard".
292+
return (environmentValueValue != null);
293+
} catch (NoSuchFieldException ignored) {
294+
// If the field does not exist then we treat it as false.
295+
} catch (SecurityException exception) {
296+
cause = exception;
297+
} catch (IllegalArgumentException exception) {
298+
cause = exception;
299+
} catch (IllegalAccessException exception) {
300+
cause = exception;
301+
} catch (NoSuchMethodException exception) {
302+
cause = exception;
303+
} catch (InvocationTargetException exception) {
304+
cause = exception;
305+
}
306+
307+
if (cause != null) {
308+
throw new RuntimeException(String.format(
309+
"Unexpected error trying to determine if runnning on Google App Engine: %s",
310+
cause.getMessage()), cause);
272311
}
273312

274313
return false;

google-api-client/src/test/java/com/google/api/client/googleapis/auth/oauth2/DefaultCredentialProviderTest.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ public void testDefaultCredentialAppEngineDeployed() throws IOException {
8080
testProvider.addType(DefaultCredentialProvider.APP_ENGINE_CREDENTIAL_CLASS,
8181
MockAppEngineCredential.class);
8282
testProvider.addType(GAE_SIGNAL_CLASS, MockAppEngineSystemProperty.class);
83-
testProvider.setEnv("GAE_ENV", "standard");
8483

8584
Credential defaultCredential = testProvider.getDefaultCredential(transport, JSON_FACTORY);
8685

@@ -111,7 +110,6 @@ public void testDefaultCredentialAppEngineWithoutDependencyThrowsHelpfulLoadErro
111110
TestDefaultCredentialProvider testProvider = new TestDefaultCredentialProvider();
112111

113112
testProvider.addType(GAE_SIGNAL_CLASS, MockAppEngineSystemProperty.class);
114-
testProvider.setEnv("GAE_ENV", "standard");
115113

116114
try {
117115
testProvider.getDefaultCredential(transport, JSON_FACTORY);
@@ -129,7 +127,6 @@ public void testDefaultCredentialCaches() throws IOException {
129127
testProvider.addType(DefaultCredentialProvider.APP_ENGINE_CREDENTIAL_CLASS,
130128
MockAppEngineCredential.class);
131129
testProvider.addType(GAE_SIGNAL_CLASS, MockAppEngineSystemProperty.class);
132-
testProvider.setEnv("GAE_ENV", "standard");
133130

134131
Credential firstCall = testProvider.getDefaultCredential(transport, JSON_FACTORY);
135132

0 commit comments

Comments
 (0)