Android Studio Android Flutter问题记录 - UNABLE TO FIND BUNDLED JAVA VERSION

前言 

有个紧急问题需要修复,本以为很快就能解决继续休假,没想到项目打开运行后Android端跑不起来了,iOS端正常运行,这就有点莫名其妙,明明放假前还是没问题的,难道我拉取的最新代码有问题?不会吧,谁放假还敲代码啊?樂️看了下最新的提交记录,还是放假前我提交的,那就肯定不是项目的问题。 

开发环境 

Android Studio: 2022.1.1 Flutter: 3.3.10 

问题描述 :

Android端构建运行失败,报错信息如下: 

Execution failed for task ':app:processDebugMainManifest'.

> Unable to make field private final java.lang.String java.io.File.path accessible: module java.base does not "opens java.io" to unnamed module

问题分析 

先网上搜一搜,大部分都是说JDK版本有问题,提到JDK版本我想到放假最后一天升级了Android Studio版本,从2021.3.1升级到2022.1.1,这应该算大版本更新,难道是这个升级导致JDK版本出问题了。尝试设置项目的JDK版本,折腾一番无果。 

既然是Flutter项目,那可以尝试用Flutter命令检查Android Studio正不正常: 

flutter doctor

执行输出: 

[✓] Flutter (Channel stable, 3.3.10, on macOS 13.0.1 22A400 darwin-x64, locale

zh-Hans-CN)

[!] Android toolchain - develop for Android devices (Android SDK version 33.0.1)

✗ Android license status unknown.

Run `flutter doctor --android-licenses` to accept the SDK licenses.

See https://flutter.dev/docs/get-started/install/macos#android-setup for

more details.

[✓] Xcode - develop for iOS and macOS (Xcode 14.2)

[✓] Chrome - develop for the web

[!] Android Studio (version 2022.1)

✗ Unable to find bundled Java version.

[✓] IntelliJ IDEA Community Edition (version 2022.3.1)

[✓] VS Code (version 1.74.2)

[✓] Connected device (3 available)

[✓] HTTP Host Availability

原来真有问题,还不止一个,那就逐个解决。 

Android license status unknown 

这个问题的解决办法Flutter已经给出了,执行下方命令即可: 

flutter doctor --android-licenses

执行输出: 

Error: A JNI error has occurred, please check your installation and try again

Exception in thread "main" java.lang.UnsupportedClassVersionError: com/android/prefs/AndroidLocationsProvider has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0

at java.lang.ClassLoader.defineClass1(Native Method)

at java.lang.ClassLoader.defineClass(ClassLoader.java:756)

at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)

at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)

at java.net.URLClassLoader.access$100(URLClassLoader.java:74)

at java.net.URLClassLoader$1.run(URLClassLoader.java:369)

at java.net.URLClassLoader$1.run(URLClassLoader.java:363)

at java.security.AccessController.doPrivileged(Native Method)

at java.net.URLClassLoader.findClass(URLClassLoader.java:362)

at java.lang.ClassLoader.loadClass(ClassLoader.java:418)

at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355)

at java.lang.ClassLoader.loadClass(ClassLoader.java:351)

at java.lang.Class.getDeclaredMethods0(Native Method)

at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)

at java.lang.Class.privateGetMethodRecursive(Class.java:3048)

at java.lang.Class.getMethod0(Class.java:3018)

at java.lang.Class.getMethod(Class.java:1784)

at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:650)

at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:632)

好家伙,这命令执行竟然报错了,我记得老早以前执行过没报错,网上一搜又是JDK版本问题。奇了怪了,虽然我电脑上有装多个版本的JDK,但是Android Studio一直是用的自带的JRE。 

Unable to find bundled Java version 

这个报错是说找不到捆绑的Java版本樂️,难道新版的Android Studio移除了自带的JRE?这么一想好像已经找到问题的根源所在了。接下来就是验证这个想法。 

首先把Flutter框架项目代码拉下来,搜索关键词Unable to find bundled Java version: 

关键代码(位于Flutter框架项目下的packages/flutter_tools/lib/src/android/android_studio.dart文件): 

final String javaPath = globals.platform.isMacOS ?

version != null && version.major < 2020 ?

globals.fs.path.join(directory, 'jre', 'jdk', 'Contents', 'Home') :

globals.fs.path.join(directory, 'jre', 'Contents', 'Home') :

globals.fs.path.join(directory, 'jre');

final String javaExecutable = globals.fs.path.join(javaPath, 'bin', 'java');

if (!globals.processManager.canRun(javaExecutable)) {

_validationMessages.add('Unable to find bundled Java version.');

} else {

// 省略

}

这段代码的作用就是拼接Java可执行程序的路径,并验证是否能执行。现在我们把涉及到路径的几个变量打印出来,打印很简单,这是Dart写的,直接用print方法就可以了。 

print('directory: $directory');

print('javaPath: $javaPath');

print('javaExecutable: $javaExecutable');

现在的问题是怎么执行到修改后的文件,当我们执行flutter doctor命令时,会执行到packages/flutter_tools/bin/flutter_tools.dart文件(后面会分析),然后再进一步解析命令执行。所以我们直接通过Dart命令执行flutter_tools.dart文件是不是就可以了。 

dart flutter_tools.dart doctor

切换到Flutter框架项目的packages/flutter_tools/bin目录下执行输出: 

flutter_tools.dart:1:1: Error: The specified language version is too high. The highest supported language version is 2.18.

// Copyright 2014 The Flutter Authors. All rights reserved.

^

../lib/executable.dart:1:1: Error: The specified language version is too high. The highest supported language version is 2.18.

// Copyright 2014 The Flutter Authors. All rights reserved.

^

../lib/runner.dart:1:1: Error: The specified language version is too high. The highest supported language version is 2.18.

// Copyright 2014 The Flutter Authors. All rights reserved.

^

../lib/src/artifacts.dart:1:1: Error: The specified language version is too high. The highest supported language version is 2.18.

// Copyright 2014 The Flutter Authors. All rights reserved.

^

../lib/src/base/context.dart:1:1: Error: The specified language version is too high. The highest supported language version is 2.18.

// Copyright 2014 The Flutter Authors. All rights reserved.

^

../lib/src/base/io.dart:1:1: Error: The specified language version is too high. The highest supported language version is 2.18.

// Copyright 2014 The Flutter Authors. All rights reserved.

^

../lib/src/base/io.dart:28:8: Error: Expected an identifier, but got ';'.

Try inserting an identifier before ';'.

library;

^

../lib/src/base/logger.dart:1:1: Error: The specified language version is too high. The highest supported language version is 2.18.

// Copyright 2014 The Flutter Authors. All rights reserved.

^

../lib/src/base/platform.dart:1:1: Error: The specified language version is too high. The highest supported language version is 2.18.

// Copyright 2014 The Flutter Authors. All rights reserved.

^

../lib/src/base/template.dart:1:1: Error: The specified language version is too high. The highest supported language version is 2.18.

// Copyright 2014 The Flutter Authors. All rights reserved.

^

执行报错了,原因是Dart SDK版本低了,电脑上当前的Dart SDK版本是2.18,拉下来的Flutter框架项目代码要求更高的版本。这时候不用去下载最新的Dart SDK版本,Flutter框架项目是自带Dart SDK的,位于项目bin/cache/dart-sdk路径下。 

2023/01/26更新:以上说明有点问题,实际的Flutter框架项目默认是不带Dart SDK的,如果你没找到,请看补充说明1。 

指定Dart可执行程序路径: 

flutter框架项目路径/bin/cache/dart-sdk/bin/dart flutter_tools.dart doctor

或者用这个,这个最终也是用到了bin/cache/dart-sdk/bin/dart: 

flutter框架项目路径/bin/dart flutter_tools.dart doctor

执行输出(省略部分): 

directory: /Applications/Android Studio.app/Contents

javaPath: /Applications/Android Studio.app/Contents/jre/Contents/Home

javaExecutable: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java

接下来检查/Applications/Android Studio.app/Contents路径下文件,可以选择[访达] -> [顶部菜单栏的前往] -> [前往文件夹] -> [输入路径跳转]或[应用程序] -> [Android Studio.app] -> [右键显示包内容] -> [Contents]。 

实锤了,新版本的Android Studio真的移除了JRE,jre目录找不到,怪不得报错了,不过多了一个jbr目录,找了个以前的Android Studio版本对比(旧版下载,不是很全): 

搜了一下jbr(JetBrains Runtime),原来IDEA老早就开始用了,是基于OpenJDK修改的东西。不知道为什么Android Studio从2022.1.1版本才开始支持,去下载了两个预览版也是没有jre目录了,说明后续应该都没了。 

综上,问题的根源在于Android Studo移除了jre目录。那如果我直接修改代码,将路径拼接过程中的jre改为jbr是不是就没问题了,实测可行,执行flutter框架项目路径/bin/cache/dart-sdk/bin/dart flutter_tools.dart doctor命令一切正常。 

解决方案 

如果你略过了前面的问题分析,请注意,以下所说的jbr所在目录路径为: 

macOS系统:/Applications/Android Studio.app/Contents

Windows系统:Android Studio的安装目录 

2023/01/30更新:实测以下三种解决方法在Flutter 3.7.0版本依旧适用。对于前两种方法,如果你尝试后未能解决,请先检查上方所说的目录中是否有jre目录或者软链接。 

这里提供三种解决方法(任选一种): 

简单粗暴的方法 

如果是macOS系统,在jbr同目录下创建一个jre目录,然后将jbr目录内的全部文件复制一份到jre目录下即可。 如果是Windows系统,jre目录是存在的,不过里面几乎没东西,可以直接将jbr目录内的全部文件复制一份到jre目录下即可。 

创建软链接的方法 

如果是macOS系统,切换到jbr所在目录执行命令: 

ln -s jbr jre

注意,如果是通过cd命令切换到jbr所在目录,需要对路径中的空格进行转义或用单/双引号包裹路径,例如cd /Applications/Android\ Studio.app/Contents。 

如果是Windows系统,使用管理员身份打开终端(可以按Win+X键,然后选择Windows 终端(管理员)),切换到jbr所在目录执行命令: 

mklink /D jre jbr

这里有几点要注意: 

一定要管理员身份运行,不然权限不足会报错提示你没有足够的权限执行此操作如果打开终端默认用的是PowerShell(输入命令那一行最前面有PS字符),需要输入cmd切换到命令提示符,这是因为PowerShell不支持mklink命令执行命令前需要删除已经存在的jre目录,不然会报错提示当文件已存在时,无法创建该文件右键创建快捷方式实测是行不通的,这种方式创建的快捷方式其实是创建了一个新的文件,只不过这个文件属性里面包含了目标路径,查看这个文件大小,才1000字节。通过mklink命令方式创建的,文件大小和占用空间等属性和目标文件属性一致。 

执行flutter doctor输出: 

Doctor summary (to see all details, run flutter doctor -v):

[✓] Flutter (Channel stable, 3.3.10, on macOS 13.0.1 22A400 darwin-x64, locale

zh-Hans-CN)

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.1)

[✓] Xcode - develop for iOS and macOS (Xcode 14.2)

[✓] Chrome - develop for the web

[✓] Android Studio (version 2022.1)

[✓] IntelliJ IDEA Community Edition (version 2022.3.1)

[✓] VS Code (version 1.74.2)

[✓] Connected device (3 available)

[✓] HTTP Host Availability

• No issues found!

一切正常!

2023/01/26更新:注意,修改Flutter SDK文件后,后续使用Flutter命令升级时可能会提示你是否要保留这些改动,一般来说,使用flutter upgrade --force 命令强制升级即可。 

快写完了,才发现差点忘了一开始是因为什么原因写这篇文章的,按以上解决方案做,如果执行flutter doctor命令没问题,实测Android端构建运行也恢复正常了,所以这其实是同一个问题导致的,如果感兴趣的话,可以看看补充分析Flutter问题记录 - Unable to find bundled Java version(续)。 

补充说明1 

如果在Flutter框架项目中没找到Dart SDK,需要先执行命令: 

flutter框架项目路径/bin/flutter

执行后,Flutter会自动下载Dart SDK,下载完成后会构建flutter tool,也就是生成flutter_tools.snapshot快照文件。 由于我执行过Flutter命令,所以一开始没注意到项目中默认是不带Dart SDK的。 

也许执行命令后你还会遇到这样的问题: 

Error: The Flutter directory is not a clone of the GitHub project.

The flutter tool requires Git in order to operate properly;

to install Flutter, see the instructions at:

https://flutter.dev/get-started

解决方法:使用Git工具拉取Flutter框架项目代码,不要直接下载。 

补充说明2 

如果生成flutter_tools.snapshot快照文件失败,报错提示: 

../lib/src/test/flutter_tester_device.dart:180:11: Warning: Operand of null-aware operation '!' has type 'Uri' which excludes null.

- 'Uri' is from 'dart:core'.

forwardingUri!,

^

../lib/runner.dart:9:8: Error: Error when reading '../../../.pub-cache/hosted/pub.flutter-io.cn/args-2.3.1/lib/command_runner.dart': No such file or directory

import 'package:args/command_runner.dart';

^

../lib/src/runner/flutter_command.dart:6:8: Error: Error when reading '../../../.pub-cache/hosted/pub.flutter-io.cn/args-2.3.1/lib/command_runner.dart': No such file or directory

import 'package:args/command_runner.dart';

^

../lib/runner.dart:10:8: Error: Error when reading '../../../.pub-cache/hosted/pub.flutter-io.cn/intl-0.17.0/lib/intl.dart': No such file or directory

import 'package:intl/intl.dart' as intl;

^

../lib/runner.dart:11:8: Error: Error when reading '../../../.pub-cache/hosted/pub.flutter-io.cn/intl-0.17.0/lib/intl_standalone.dart': No such file or directory

import 'package:intl/intl_standalone.dart' as intl_standalone;

^

../lib/src/runner/flutter_command_runner.dart:6:8: Error: Error when reading '../../../.pub-cache/hosted/pub.flutter-io.cn/args-2.3.1/lib/command_runner.dart': No such file or directory

import 'package:args/command_runner.dart';

^

../lib/src/artifacts.dart:5:8: Error: Error when reading '../../../.pub-cache/hosted/pub.flutter-io.cn/file-6.1.4/lib/memory.dart': No such file or directory

import 'package:file/memory.dart';

^

../lib/src/cache.dart:8:8: Error: Error when reading '../../../.pub-cache/hosted/pub.flutter-io.cn/file-6.1.4/lib/memory.dart': No such file or directory

import 'package:file/memory.dart';

^

../lib/src/artifacts.dart:6:8: Error: Error when reading '../../../.pub-cache/hosted/pub.flutter-io.cn/process-4.2.4/lib/process.dart': No such file or directory

import 'package:process/process.dart';

^

../lib/src/cache.dart:10:8: Error: Error when reading '../../../.pub-cache/hosted/pub.flutter-io.cn/process-4.2.4/lib/process.dart': No such file or directory

import 'package:process/process.dart';

^

../lib/src/commands/analyze.dart:6:8: Error: Error when reading '../../../.pub-cache/hosted/pub.flutter-io.cn/process-4.2.4/lib/process.dart': No such file or directory

import 'package:process/process.dart';

^

执行命令获取flutter_tools所需要的依赖包即可解决: 

flutter update-packages

总结 

写完这篇文章,想着不知道有没有人提issue,要是没人提,我去提一个。没想到,老早就有人提了issue,应该是用Android Studio预览版的人提的,最近也还有人不断在重复提。 

最后 

如果这篇文章对你有所帮助,请不要吝啬你的点赞!加星!,谢谢~

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值