Skip to content

Commit c22c19b

Browse files
authored
have Java.version return null if java --version fails or cannot be run (#139614)
## Summary Fixes flutter/flutter#139180, where `flutter create` could crash if the `java` binary the tool found cannot be run. ## Context At startup, the tool searches for a Java installation[^1]. Unless the located installation is from [an Android Studio installation](https://github.com/flutter/flutter/blob/e1967ecabf014bf93d1731fde6a6547b06ca9c33/packages/flutter_tools/lib/src/android/android_studio.dart#L163), the tool does not verify that the binary is runnable. For more, see flutter/flutter#139613, which tracks this inconsistency in behavior. This means that in the scenario where 1) the user does not have Android Studio installed or the java binary found within cannot be run **and** 2) the user has a) `flutter config --jdk-dir` set, b) `JAVA_HOME` set in their environment, **or** c) `java` on their system path **and** 3) the java binary we think we found during cannot be run (or `java --version` fails), **then** the user running `flutter create` with Android enabled will hit a tool crash. ## Change `Java.version` should return null if version checking fails for any reason. [This is documented behavior](https://github.com/flutter/flutter/blob/48f57621ade657b0c20ba53d513de4c3cd563abd/packages/flutter_tools/lib/src/android/java.dart#L136). Therefore, we'll update the implementation to first verify that the binary is runnable. If it isn't, it will return `null`. [^1]: We find java by calling the static `Java.find`, see: https://github.com/flutter/flutter/blob/48187028c11ca8ca10e0179705d25553e1fe2c14/packages/flutter_tools/lib/src/context_runner.dart#L271 [^2]: This PR doesn't change this, as this would be too dangerous to cherry-pick into stable.
1 parent 2230c09 commit c22c19b

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

packages/flutter_tools/lib/src/android/java.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,13 +135,18 @@ class Java {
135135
/// Returns the version of java in the format \d(.\d)+(.\d)+
136136
/// Returns null if version could not be determined.
137137
late final Version? version = (() {
138+
if (!canRun()) {
139+
return null;
140+
}
141+
138142
final RunResult result = _processUtils.runSync(
139143
<String>[binaryPath, '--version'],
140144
environment: environment,
141145
);
142146
if (result.exitCode != 0) {
143147
_logger.printTrace('java --version failed: exitCode: ${result.exitCode}'
144148
' stdout: ${result.stdout} stderr: ${result.stderr}');
149+
return null;
145150
}
146151
final String rawVersionOutput = result.stdout;
147152
final List<String> versionLines = rawVersionOutput.split('\n');

packages/flutter_tools/test/general.shard/android/java_test.dart

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ OpenJDK 64-Bit Server VM Zulu19.32+15-CA (build 19.0.2+7, mixed mode, sharing)
183183
});
184184
});
185185

186-
group('getVersionString', () {
186+
group('version', () {
187187
late Java java;
188188

189189
setUp(() {
@@ -208,6 +208,23 @@ OpenJDK 64-Bit Server VM Zulu19.32+15-CA (build 19.0.2+7, mixed mode, sharing)
208208
);
209209
}
210210

211+
testWithoutContext('is null when java binary cannot be run', () async {
212+
addJavaVersionCommand('');
213+
processManager.excludedExecutables.add('java');
214+
215+
expect(java.version, null);
216+
});
217+
218+
testWithoutContext('is null when java --version returns a non-zero exit code', () async {
219+
processManager.addCommand(
220+
FakeCommand(
221+
command: <String>[java.binaryPath, '--version'],
222+
exitCode: 1,
223+
),
224+
);
225+
expect(java.version, null);
226+
});
227+
211228
testWithoutContext('parses jdk 8', () {
212229
addJavaVersionCommand('''
213230
java version "1.8.0_202"

0 commit comments

Comments
 (0)