GitLab CI/CD Docker执行器运行报JAVA_HOME为无效目录错误
问题根因
这个报错本质是搞混了两种GitLab执行器的运行边界:
- Shell执行器是直接调用macOS宿主机的环境跑命令,本地用sdkman装的Java就在
/Users/qfunz/.sdkman/candidates/java/current路径下,自然能正常运行 - Docker执行器是每次作业都启动一个隔离的Linux容器跑任务,容器有独立的文件系统,宿主机上的用户目录、sdkman安装的Java不会自动同步进容器。硬把宿主机的JAVA_HOME路径配到CI变量里,容器里找不到对应路径的Java,自然报路径无效,执行
java命令也没有输出。
解决方法
优先选第一种方案,改造成本最低,稳定性最好:
方案1:直接用预配置Android构建环境的Docker镜像
这类镜像已经提前装好对应版本的JDK、Android SDK、构建依赖,JAVA_HOME之类的环境变量也预配置完成,不需要手动调整。
你只需要在CI配置最开头加全局镜像配置,同时注意把作业的tag从原来绑定Shell执行器的shell,换成注册Docker执行器时设置的对应tag,不然作业还是会调度到macOS的Shell执行器上运行。
改完的配置参考:
default: image: mingc/android-build-box:latest # 下面tags的值换成你Docker执行器对应的标签,别再用原来的shell标签 tags: - docker-executor before_script: - export GRADLE_USER_HOME=$(pwd)/.gradle - chmod +x ./gradlew stages: - build create common folder to store build: stage: build needs: [] script: - mkdir popa artifacts: paths: - ./popa get debug apk build: stage: build needs: [create common folder to store build] script: - ./gradlew app:assembleDebug - mv app/build/outputs/apk/debug/*.apk ./popa artifacts: paths: - ./popa get release apk build: stage: build needs: [create common folder to store build] script: - ./gradlew app:assembleRelease - mv app/build/outputs/apk/release/*.apk ./popa artifacts: paths: - ./popa get release aab build: stage: build needs: [create common folder to store build] script: - ./gradlew app:bundleRelease - mv app/build/outputs/bundle/release/*.aab ./popa artifacts: paths: - ./popa get one folder build: stage: build needs: [get debug apk build, get release apk build, get release aab build] script: - echo "DONE" artifacts: paths: - ./popa
注意:如果构建时报JDK版本和Android Gradle插件版本不匹配,换对应JDK版本的镜像tag即可。
方案2:自定义基础镜像配置JDK
如果不想用第三方预构建镜像,可以自己基于OpenJDK官方镜像打一个包含Android SDK的自定义镜像,镜像里装好对应版本的JDK后,JAVA_HOME直接填容器内的JDK安装路径(比如OpenJDK17在Debian基础镜像里的默认路径是/usr/lib/jvm/java-17-openjdk-amd64),绝对不能用宿主机的sdkman路径。
方案3:挂载宿主机目录到容器(非常不推荐)
也可以在注册Docker执行器的时候加参数,把宿主机的sdkman Java目录挂载到容器内相同路径,但macOS上编译的Java二进制和Linux容器的系统依赖不兼容,就算挂载进去大概率也跑不起来,没必要折腾。
最后记得把之前在GitLab CI变量里手动加的、配置为宿主机路径的JAVA_HOME项删掉,避免覆盖镜像里预配置好的正确环境变量。
内容的提问来源于stack exchange,提问作者user19358111
相关产品推荐
相关产品推荐

