【问题标题】:Tomcat 7 + JNI: UnsatisfiedLinkError: cannot open shared object file: No such file or directoryTomcat 7 + JNI:UnsatisfiedLinkError:无法打开共享对象文件:没有这样的文件或目录
【发布时间】:2017-09-03 01:19:27
【问题描述】:

这是我的问题:我有一个包含我的 webapp 的 WAR 文件,以及它的 WEB-INF/lib 中的一个 .jar,它依赖于运行 Tomcat 的主机上的 .so 文件。当我通过应用程序管理器部署我的 WAR 文件时,当从 .jar 加载 JNI 包装器类时,我会在启动日志中得到一个 UnsatisfiedLinkError: file not found。当我查看链接库所在的目录时,它们清楚地存在,并且具有世界读取和执行权限,我什至将所有者更改为与执行 tomcat 的用户相同的运行。我相当肯定这是一个权限问题,因为我可以在命令行上执行 WAR 文件,而我没有收到错误消息。我希望有人能发现我遗漏的东西,或者指导我阅读我误读的一些 Tomcat 文档。

以下是通过 Tomcat 管理器部署时的错误全文:

07 Apr 2017 10:45:53,140 [ERROR] [... omitted irrelevant log output ...] java.lang.UnsatisfiedLinkError: /opt/omitted-sdk-name/linux_x86_64/bin/libjni_emdq.so: libemdq.so: cannot open shared object file: No such file or directory

如果我通过systemctl stop tomcat 关闭tomcat 并像这样(以root 身份)执行我的war 文件,我不会得到UnsatisfiedLinkError

java -Djava.library.path=/opt/omitted-sdk-name/linux_x86_64/bin -jar /path/to/my/app##0.1.war

其他一些有用的信息:

  • CentOS 7
  • 通过 yum 进行全新的香草安装(与默认配置没有偏差,除了启用管理器上的管理员用户并切换默认 jvm)。
  • /usr/sbin/tomcat version 表示:
服务器版本:Apache Tomcat/7.0.69 服务器建成:2016 年 11 月 6 日 01:55:51 UTC 服务器号:7.0.69.0 操作系统名称:Linux 操作系统版本:3.10.0-514.10.2.el7.x86_64 架构:amd64 JVM版本:1.8.0_121-b13 JVM 供应商:甲骨文公司
  • Tomcat 以用户tomcat 运行
  • 我尝试将这个 sdk 中所有 .so 文件的所有权从 root 更改为 tomcat。改变所有者并没有改变实际行为。例如,此所有者/模式会产生问题 - 与 tomcat 运行身份用户相同的所有者,以及完整的读取+可执行权限,我预计这会解决问题:
[root@omimitted-host bin]# ls -la | grep emdq -rwxr-xr-x 1 tomcat tomcat 403153 Nov 10 03:10 libemdq.so -rwxr-xr-x 1 tomcat tomcat 76850 Nov 10 03:11 libjni_emdq.so
  • 编辑:这台机器上似乎有两个版本的 Java。 root的路径是1.8.0_77,配置给tomcat的是1.8.0_121:
[root@omimitted-host tomcat]# java -version java版本“1.8.0_77” Java(TM) SE 运行时环境 (build 1.8.0_77-b03) Java HotSpot(TM) 64 位服务器 VM(内部版本 25.77-b03,混合模式) [root@omimitted-host tomcat]# /etc/alternatives/jre_1.8.0_openjdk/bin/java -version openjdk 版本“1.8.0_121” OpenJDK 运行时环境(内部版本 1.8.0_121-b13) OpenJDK 64 位服务器 VM(内部版本 25.121-b13,混合模式)
  • file 在两个有问题的 .so 上的输出显示它们是 64 位库,所以我认为在 64 位 JVM 中运行没有问题:
[root@omimitted-host bin]# 文件 libjni_emdq.so libjni_emdq.so:ELF 64 位 LSB 共享对象,x86-64,版本 1 (SYSV),动态链接,未剥离 [root@omimitted-host bin]# 文件 libemdq.so libemdq.so:ELF 64 位 LSB 共享对象,x86-64,版本 1 (SYSV),动态链接,未剥离
  • 我在$CATALINA_HOME/conf/conf.d/omittedname.conf 的文件中有这些行。在过去的某个时候,我将它们放在 tomcat.conf 中,但任何一个位置似乎都产生了相同的结果。
MY_BIN="/opt/省略-sdk-name/linux_x86_64/bin" LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$MY_BIN" JAVA_OPTS="$JAVA_OPTS -Djava.library.path=$MY_BIN -Djava.security.egd=file:/dev/./urandom -Djava.awt.headless=true -XX:+UseConcMarkSweepGC" # 需要运行应用程序 JAVA_OPTS="$JAVA_OPTS -Dprofile=test"
  • 编辑:发布后,我注意到root 在其路径中有不同的jvm。上面的 Java 版本也进行了编辑。
[root@omited-host tomcat]# echo $PATH /java/jdk1.8.0_77/bin:/opt/省略-sdk-name/linux_x86_64/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/斌

还有什么我可以尝试看的吗?我可能需要add a java.io.FilePermissions permission吗?

另外,只是一个谦虚的声明,我知道以 root 身份运行/拥有事物的含义。我的目标只是回到正常工作的 tomcat 管理器配置,以解开这个开发服务器。

【问题讨论】:

  • *.so 文件位于何处?它在您的路径环境变量中吗?如果没有,您可以将 -Djava.library.path="directory\contain\your\so\file" 指定给 Tomcat。
  • 以 root 身份登录,$PATH 确实包含 .so 文件的位置。用户 tomcat 没有分配给他们的登录 shell (/sbin/nologin)。我在JAVA_OPTS 中有java.library.path(见底部)。我应该在其他地方指定 jvm 参数吗?
  • 我注意到,然而,这台机器上有几个版本的java。 Oracle jdk-1.8.0_77 位于 root 路径中,但 Tomcat 配置为使用来自 /etc/alternatives/jdk-1.8.0_121 的 OpenJDK 版本。
  • 是否可以,将so文件复制到tomcat\bin,并将库路径设置为tomcat\bin,并测试是否有效?
  • 我可以在几个小时后再次重新启动 Tomcat 时尝试。现在我不能碰它。但是,我不清楚为什么将文件复制到 $CATALINA_HOME/bin 文件夹并设置路径与我现在所拥有的有什么不同? .so 文件显然存在,没有符号链接,并且世界可读+可执行。

标签: java linux tomcat tomcat7 centos7


【解决方案1】:

这个答案不太令人满意,但它是解决我问题的关键。我不得不将声明 LD_LIBRARY_PATH=/opt/omitted-sdk-name/linux_x86_64/bin$CATALINA_HOME/conf/conf.d/myapp.conf 移动到 $CATALINA_HOME/conf/tomcat.conf。在我这样做之后,UnsatisfiedLinkError 消失了。

【讨论】:

    猜你喜欢
    • 2018-12-03
    • 1970-01-01
    • 1970-01-01
    • 2015-04-12
    • 2018-11-26
    • 2019-11-27
    • 2020-02-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多