返回顶部
首页 > 资讯 > 精选 >Flutter问题记录 - Unable to find bundled Java version
  • 899
分享到

Flutter问题记录 - Unable to find bundled Java version

androidstudioflutterandroid 2023-08-16 18:08:03 899人浏览 薄情痞子
摘要

文章目录 前言开发环境问题描述问题分析解决方案补充说明1补充说明2总结最后 前言 有个紧急问题需要修复,本以为很快就能解决继续休假,没想到项目打开运行后Android端跑不起来了,iOS端正常运行,这就有点莫名其妙,明明放假前


前言

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

开发环境

问题描述

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

2023/08/14更新:当前问题已被修复,如果你还遇到以上报错,可以参考这篇文章Android问题记录 - Unable to make field private final java.lang.String java.io.File.path accessible(持续更新)。当然,如果你是Flutter开发者,当前文章也值得一读。

问题分析

先网上搜一搜,大部分都是说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

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

  1. Android license status unknown

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

flutter doctor --android-licenses

执行输出:

Error: A JNI error has occurred, please check your installation and try againException 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.0at 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。

2023/08/14更新:当前问题已被修复,如果你还遇到以上报错,那么可能是JDK版本太低导致的,可以参考本篇文章评论中的方法,尝试升级JDK版本解决。

  1. Unable to find bundled Java version

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

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

screenshot1

关键代码(位于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/ContentsjavaPath: /Applications/Android Studio.app/Contents/jre/Contents/HomejavaExecutable: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java

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

screenshot2

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

screenshot3

搜了一下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目录或者软链接。

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

  1. 简单粗暴的方法
  • 如果是macOS系统,在jbr同目录下创建一个jre目录,然后将jbr目录内的全部文件复制一份到jre目录下即可。
  • 如果是Windows系统,jre目录是存在的,不过里面几乎没东西,可以直接将jbr目录内的全部文件复制一份到jre目录下即可。
  1. 创建软链接的方法
  • 如果是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命令方式创建的,文件大小和占用空间等属性和目标文件属性一致。

2023/02/05更新:通过以上两种方法解决后,Android Studio后续升级可能会遇到如下所示问题:

screenshot4

如果你当前的Flutter版本已经修复了该问题,点击Proceed删除添加的jre目录或者软链接即可。如果还未修复又想继续升级(点击Proceed),请按之前的方法将被删除的jre目录或者软链接添加回去。

  1. 修改Flutter框架代码的方法(不推荐,有点麻烦,感兴趣的可以看看)

前面问题分析中尝试修改代码是可行的,但是那是在Flutter框架项目下改的,现在我们要做的是对当前电脑上的Flutter SDK进行修改。首先找到Flutter SDK目录:

screenshot5

如果你见过Flutter框架项目的目录结构,你会发现一模一样,那是不是说,直接修改目录下的packages/flutter_tools/lib/src/android/android_studio.dart文件就好了,将jre改为jbr,实测没变化。这难道还需要编译?是的,确实还要做一些处理。

flutter doctor命令的执行开始分析,首先找到flutter可执行文件(位于Flutter SDK的bin目录下),这个本质是一个shell脚本,可以用文本工具打开,有点长就贴一个脚本的关键部分:

source "$BIN_DIR/internal/shared.sh"shared::execute "$@"

在脚本的最后执行了shared::execute::是命名约定,用于分隔库)函数,并将命令执行时的参数传递下去。找到shared.sh文件(位于Flutter SDK的bin/internal目录下)中的shared::execute函数:

# This function is intended to be executed by entrypoints (e.g. `//bin/flutter`# and `//bin/dart`). PROG_NAME and BIN_DIR should already be set by those# entrypoints.function shared::execute() {  export FLUTTER_ROOT="$(cd "${BIN_DIR}/.." ; pwd -P)"  # If present, run the bootstrap script first  BOOTSTRAP_PATH="$FLUTTER_ROOT/bin/internal/bootstrap.sh"  if [ -f "$BOOTSTRAP_PATH" ]; then    source "$BOOTSTRAP_PATH"  fi  FLUTTER_TOOLS_DIR="$FLUTTER_ROOT/packages/flutter_tools"  SNAPSHOT_PATH="$FLUTTER_ROOT/bin/cache/flutter_tools.snapshot"  STAMP_PATH="$FLUTTER_ROOT/bin/cache/flutter_tools.stamp"  SCRIPT_PATH="$FLUTTER_TOOLS_DIR/bin/flutter_tools.dart"  DART_SDK_PATH="$FLUTTER_ROOT/bin/cache/dart-sdk"  DART="$DART_SDK_PATH/bin/dart"  # If running over git-bash, overrides the default UNIX executables with win32  # executables  case "$(uname -s)" in    MINGW*)      DART="$DART.exe"      ;;  esac  # Test if running as superuser – but don't warn if running within Docker or CI.  if [[ "$EUID" == "0" && ! -f /.dockerenv && "$CI" != "true" && "$BOT" != "true" && "$CONTINUOUS_INTEGRATION" != "true" ]]; then    >&2 echo "   Woah! You appear to be trying to run flutter as root."    >&2 echo "   We strongly recommend running the flutter tool without superuser privileges."    >&2 echo "  /"    >&2 echo "📎"  fi  # Test if Git is available on the Host  if ! hash git 2>/dev/null; then    >&2 echo "Error: Unable to find git in your PATH."    exit 1  fi  # Test if the flutter directory is a git clone (otherwise git rev-parse HEAD  # would fail)  if [[ ! -e "$FLUTTER_ROOT/.git" ]]; then    >&2 echo "Error: The Flutter directory is not a clone of the GitHub project."    >&2 echo "       The flutter tool requires Git in order to operate properly;"    >&2 echo "       to install Flutter, see the instructions at:"    >&2 echo "       https://flutter.dev/get-started"    exit 1  fi  upgrade_flutter 7< "$PROG_NAME"  BIN_NAME="$(basename "$PROG_NAME")"  case "$BIN_NAME" in    flutter*)      # FLUTTER_TOOL_ARGS aren't quoted below, because it is meant to be      # considered as separate space-separated args.      exec "$DART" --disable-dart-dev --packages="$FLUTTER_TOOLS_DIR/.dart_tool/package_config.json" $FLUTTER_TOOL_ARGS "$SNAPSHOT_PATH" "$@"      ;;    dart*)      exec "$DART" "$@"      ;;    *)      >&2 echo "Error! Executable name $BIN_NAME not recognized!"      exit 1      ;;  esac}

函数有点长,直接看最后面就好。最后有个分支语句,根据BIN_NAME的值走不同分支,把相关的变量打印出来看看:

echo "PROG_NAME: $PROG_NAME"echo "BIN_NAME: $BIN_NAME"

执行flutter doctor输出(省略部分):

PROG_NAME: /usr/local/Caskroom/flutter/3.3.10/flutter/bin/flutterBIN_NAME: flutter

根据输出结果可以判断,走的是第一个分支,执行exec "$DART" --disable-dart-dev --packages="$FLUTTER_TOOLS_DIR/.dart_tool/package_config.JSON" $FLUTTER_TOOL_ARGS "$SNAPSHOT_PATH" "$@"。之所以会有这个分支判断,是因为Dart命令最终也会执行到这个函数,执行Dart相关命令输出(省略部分):

PROG_NAME: /usr/local/Caskroom/flutter/3.3.10/flutter/bin/dartBIN_NAME: dart

分析到这,好像也没用到SCRIPT_PATH变量(flutter_tools.dart的路径,请看上述脚本函数代码中的定义),前面问题分析中提到执行flutter doctor命令时,会执行到packages/flutter_tools/bin/flutter_tools.dart文件,这难道是假的?不能说是假的,只能说有点偏差。如果是在这直接执行packages/flutter_tools/bin/flutter_tools.dart文件的,那前面一开始修改代码就可以生效了,原因在于这边是用Dart命令执行SNAPSHOT_PATH所指向的快照文件(flutter_tools.snapshot)去了。

flutter_tools.snapshot是通过Dart命令生成的快照文件,那我们是不是也可以生成一个快照文件替换掉自带的?切换到Flutter SDK目录的packages/flutter_tools/bin路径下执行命令:

dart --snapshot=flutter_tools.snapshot flutter_tools.dart

2023/01/26更新:如果生成快照文件报错,请看补充说明2

然后将生成的flutter_tools.snapshot文件复制到bin/cache目录下,注意,最好先备份原先的flutter_tools.snapshot文件。对比文件大小,发现相差很小,那应该稳了,执行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 directoryimport '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 directoryimport '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 directoryimport '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 directoryimport '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 directoryimport '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 directoryimport '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 directoryimport '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 directoryimport '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 directoryimport '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 directoryimport 'package:process/process.dart';       ^

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

flutter update-packages

总结

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

最后

如果这篇文章对你有所帮助,点赞👍加星🌟支持一下吧,谢谢~


本篇文章由@crasowas发布于CSDN。

来源地址:https://blog.csdn.net/crasowas/article/details/128756923

--结束END--

本文标题: Flutter问题记录 - Unable to find bundled Java version

本文链接: https://lsjlt.com/news/371900.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作