M1 Mac中从Java调用Python脚本执行失败问题求助
问题:M1芯片下Java调用Python脚本出现架构不兼容错误
环境与代码
Bash脚本
#!/bin/bash restest-env/bin/python3 script.py $1 $2 $3
Java调用代码
ProcessBuilder pb = new ProcessBuilder(command, String.join(" ",commandArgs)); Process proc = pb.start(); proc.getOutputStream(); String stdout = IOUtils.toString(proc.getInputStream(), Charset.defaultCharset()); String stderr = IOUtils.toString(proc.getErrorStream(), Charset.defaultCharset()); proc.waitFor();
错误信息
回溯(最近的调用最后): 文件 "/Users/giulianomirabella/Desktop/RESTest/ml/restest-env/lib/python3.8/site-packages/numpy/core/__init__.py",第23行,在<module>中 from . import multiarray 文件 "/Users/giulianomirabella/Desktop/RESTest/ml/restest-env/lib/python3.8/site-packages/numpy/core/multiarray.py",第10行,在<module>中 from . import overrides 文件 "/Users/giulianomirabella/Desktop/RESTest/ml/restest-env/lib/python3.8/site-packages/numpy/core/overrides.py",第6行,在<module>中 from numpy.core._multiarray_umath import ( ImportError: dlopen(/Users/giulianomirabella/Desktop/RESTest/ml/restest-env/lib/python3.8/site-packages/numpy/core/_multiarray_umath.cpython-38-darwin.so, 0x0002): tried: '/Users/giulianomirabella/Desktop/RESTest/ml/restest-env/lib/python3.8/site-packages/numpy/core/_multiarray_umath.cpython-38-darwin.so' (mach-o文件,但架构不兼容(现有'arm64',需要'x86_64')) 在处理上述异常期间,发生了另一个异常: 回溯(最近的调用最后): 文件 "ml/python-scripts/al_predictor.py",第2行,在<module>中 import numpy as np 文件 "/Users/giulianomirabella/Desktop/RESTest/ml/restest-env/lib/python3.8/site-packages/numpy/__init__.py",第140行,在<module>中 from . import core 文件 "/Users/giulianomirabella/Desktop/RESTest/ml/restest-env/lib/python3.8/site-packages/numpy/core/__init__.py",第49行,在<module>中 raise ImportError(msg) ImportError: 重要提示:请阅读以下内容获取解决此问题的建议! 导入numpy C扩展失败。此错误可能由多种原因导致,通常与您的设置或numpy的安装方式有关。 请注意并检查以下内容: * Python版本:来自 "/Users/giulianomirabella/Desktop/RESTest/ml/restest-env/bin/python3" 的Python3.8 * NumPy版本:"1.23.1" 原始错误:dlopen(/Users/giulianomirabella/Desktop/RESTest/ml/restest-env/lib/python3.8/site-packages/numpy/core/_multiarray_umath.cpython-38-darwin.so, 0x0002): tried: '/Users/giulianomirabella/Desktop/RESTest/ml/restest-env/lib/python3.8/site-packages/numpy/core/_multiarray_umath.cpython-38-darwin.so' (mach-o文件,但架构不兼容(现有'arm64',需要'x86_64'))
核心问题
- 终端直接执行bash脚本或Python脚本均正常
- Java调用时触发numpy架构不兼容错误(arm64 vs x86_64)
- 无法使用conda解决
解决思路
1. 切换Java为arm64架构版本
M1芯片下部分Java版本默认通过Rosetta以x86_64模式运行,会强制子进程也采用该架构,与arm64版本的numpy冲突:
- 执行
java -version检查当前Java架构,若显示x86_64,则更换为arm64版本的JDK(如Azul Zulu、OpenJDK的arm64发行版) - 切换后再次验证Java架构,确保输出包含
aarch64
2. 重新构建通用架构的Python虚拟环境
创建支持arm64和x86_64的虚拟环境,让numpy以通用架构编译:
# 删除现有虚拟环境 rm -rf restest-env # 创建通用架构虚拟环境 ARCHFLAGS="-arch arm64 -arch x86_64" python3 -m venv restest-env # 激活环境并重新安装依赖 source restest-env/bin/activate pip install numpy==1.23.1 [其他所需依赖]
3. 在Java调用时强制指定arm64架构
通过arch -arm64前缀调用脚本,强制子进程以arm64模式运行:
// 修改ProcessBuilder,添加arch -arm64前缀 ProcessBuilder pb = new ProcessBuilder("arch", "-arm64", "/path/to/your/bash/script.sh", String.join(" ",commandArgs)); Process proc = pb.start(); // 后续读取流、等待进程的代码不变
或通过环境变量强制Python架构:
ProcessBuilder pb = new ProcessBuilder(command, String.join(" ",commandArgs)); Map<String, String> env = pb.environment(); env.put("ARCHFLAGS", "-arch arm64"); Process proc = pb.start();
4. 检查Java进程的运行架构
打开Activity Monitor,找到Java进程,右键选择"显示检查器",查看"架构"字段。若为Intel(x86_64),则必须切换到arm64版本的Java。
内容的提问来源于stack exchange,提问作者Giuliano Mirabella
相关产品推荐
相关产品推荐

