JUnit 测试有效,但 Maven 测试失败,因为在 macOS 上找不到库 (DYLD_LIBRARY_PATH)
JUnit test works, but maven test fails due to library not found on macOS (DYLD_LIBRARY_PATH)
我有一个简单的 JUnit 测试,我在 macOS Mojave 上的 Eclipse 中成功 运行。 class 对动态库进行 JNA 调用,因此我必须设置运行时环境变量 DYLD_LIBRARY_PATH
当我尝试在 Eclipse 内部或外部 运行 mvn test
时,它们都失败了。
据我了解,原因是 macOS 的 System Integrity Protection which wipes all DYLD
variables。然而,必须能够以某种方式设置它们,因为 Eclipse 中的 JUnit 测试按设计工作。
我试图“破解”mvn
shell 脚本,该脚本最后执行:
exec "$JAVACMD" \
$MAVEN_OPTS \
$MAVEN_DEBUG_OPTS \
-classpath "${CLASSWORLDS_JAR}" \
"-Dclassworlds.conf=${MAVEN_HOME}/bin/m2.conf" \
"-Dmaven.home=${MAVEN_HOME}" \
"-Dlibrary.jansi.path=${MAVEN_HOME}/lib/jansi-native" \
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${CLASSWORLDS_LAUNCHER} "$@"
通过在 exec
命令之前立即设置 DYLD_LIBRARY_PATH
,但没有成功。
还尝试修补 $JAVACMD
以首先设置变量,但没有成功。
我错过了哪些选项(除了禁用 SIP)?
我不是在寻找通用的解决方案,运行宁mvn
是我的目标
类似问题:
- 这里为什么不传播DYLD_LIBRARY_PATH?
- LD_LIBRARY_PATH and DYLD_LIBRARY_PATH not imported on OS X
- How to set LD_LIBRARY_PATH/DYLD_LIBRARY_PATH on macos
我找到了一个解决方案,我不喜欢它,但它似乎有效。 JNA 调用出去加载使用 @executable_path
注释的附加代码。 运行 Java,可执行文件是 JVM,而不是原始应用程序,因此 JNA 调用将失败。
链接整个程序目录(然后清理)对我有用。我对 mvn
的调用如下所示:
#!/bin/bash
# Ugly hack to make mvn play ball
JAVA_HOME=/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home
for onelib in $(ls /Applications/HCL\ Notes.app/Contents/MacOS)
do
echo "Linking /Applications/HCL\ Notes.app/Contents/MacOS/${onelib}"
sudo ln -s /Applications/HCL\ Notes.app/Contents/MacOS/${onelib} ${JAVA_HOME}/jre/bin/${onelib}
done
# Maven test
mvn test
# Cleanup
sudo find $JAVA_HOME/jre/bin -maxdepth 1 -type l -delete
YMMV
我有一个简单的 JUnit 测试,我在 macOS Mojave 上的 Eclipse 中成功 运行。 class 对动态库进行 JNA 调用,因此我必须设置运行时环境变量 DYLD_LIBRARY_PATH
当我尝试在 Eclipse 内部或外部 运行 mvn test
时,它们都失败了。
据我了解,原因是 macOS 的 System Integrity Protection which wipes all DYLD
variables。然而,必须能够以某种方式设置它们,因为 Eclipse 中的 JUnit 测试按设计工作。
我试图“破解”mvn
shell 脚本,该脚本最后执行:
exec "$JAVACMD" \
$MAVEN_OPTS \
$MAVEN_DEBUG_OPTS \
-classpath "${CLASSWORLDS_JAR}" \
"-Dclassworlds.conf=${MAVEN_HOME}/bin/m2.conf" \
"-Dmaven.home=${MAVEN_HOME}" \
"-Dlibrary.jansi.path=${MAVEN_HOME}/lib/jansi-native" \
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${CLASSWORLDS_LAUNCHER} "$@"
通过在 exec
命令之前立即设置 DYLD_LIBRARY_PATH
,但没有成功。
还尝试修补 $JAVACMD
以首先设置变量,但没有成功。
我错过了哪些选项(除了禁用 SIP)?
我不是在寻找通用的解决方案,运行宁mvn
是我的目标
类似问题:
- 这里为什么不传播DYLD_LIBRARY_PATH?
- LD_LIBRARY_PATH and DYLD_LIBRARY_PATH not imported on OS X
- How to set LD_LIBRARY_PATH/DYLD_LIBRARY_PATH on macos
我找到了一个解决方案,我不喜欢它,但它似乎有效。 JNA 调用出去加载使用 @executable_path
注释的附加代码。 运行 Java,可执行文件是 JVM,而不是原始应用程序,因此 JNA 调用将失败。
链接整个程序目录(然后清理)对我有用。我对 mvn
的调用如下所示:
#!/bin/bash
# Ugly hack to make mvn play ball
JAVA_HOME=/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home
for onelib in $(ls /Applications/HCL\ Notes.app/Contents/MacOS)
do
echo "Linking /Applications/HCL\ Notes.app/Contents/MacOS/${onelib}"
sudo ln -s /Applications/HCL\ Notes.app/Contents/MacOS/${onelib} ${JAVA_HOME}/jre/bin/${onelib}
done
# Maven test
mvn test
# Cleanup
sudo find $JAVA_HOME/jre/bin -maxdepth 1 -type l -delete
YMMV