Tomcat(作为服务)是否不为 Java 网络应用程序加载本机库?
Does Tomcat (as a Service) not load native libraries for a Java web application?
我正在使用 Tomcat7 和 Ubuntu。我有一个 Java Web 应用程序,它使用了一些本机库。当我 运行 Eclipse 中的 Web 应用程序时,它在调试期间通过 Eclipse 内部 Tomcat 服务器工作。但是,当我将应用程序部署到托管 Tomcat 服务时,应用程序在到达加载这些库的点时失败。
- 我把原生库放在/home/me/my_shared_libs,给了
文件夹和文件所有权归用户 "Tomcat7" -- sudo chown
- 我将本机库的所有权限授予 "Tomcat7" 用户
--
sudo chmod
- 在
sudo vi /usr/share/tomcat7/bin/setenv.sh
中,并放入以下内容
在文件中 export CATALINA_OPTS="-Djava.library.path=/home/me/my_shared_libs"
- 然后我重新启动 Tomcat --
sudo service tomcat7 restart
而且,每当
已达到加载本机库的引用,我收到有关 InvocationTargetException
. 的错误
我也愿意选择将本机库添加为应用程序 .WAR 文件的一部分。 (虽然我不确定如何在 Eclipse 中执行此操作)。
/var/log/tomcat7/catalina.out
的日志-->
Jun 30, 2016 8:11:50 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 3643 ms
Load my_native_lib_called. libmachoman.so: cannot open shared object file: No such file or directory
编辑:
我发现了一件非常有趣的事情。 Tomcat 确实选择了我在上面设置的库位置。发生的情况是我在该位置有两种类型的库 (.so) 文件。第一个库 (libcore.so) calls/loads 第二个库 (libmachoman.so)。 libcore.so 已找到并加载,libmachoman.so 未找到,即使两者位于同一位置。
可以从代码本身完成。这应该会让您对库的加载充满信心。
为此,您可以使用 System.load()
以库的绝对路径为例
System.load("/PATH/TO/.so");
运行这段代码在应用程序启动时调用库函数之前一次。
您必须将您的图书馆放在所有服务器上的自定义位置。
System.loadLibrary() 也用于相同的目的,但不同之处在于它会按名称加载库并查看 Java 环境变量 java.library.path
指定的位置。
但是正如您所提到的,设置起来可能会很痛苦,必须在 tomcat 的所有实例中进行此更改。
头疼了几天,终于有了解决办法。
编辑文件
sudo vi /etc/ld.so.conf
在文件中追加本机库的位置
包括/etc/ld.so.conf.d/*.conf
/home/me/my_shared_lib
加载配置
sudo ldconfig
查看新变化
ldconfig -p | grep my_shared_lib
这告诉动态链接器在哪里寻找本机库。
我的问题解决了。
还有其他替代解决方案 here,它们可能有也可能没有一些缺点。
或者(也发现),您可以在 /usr/share/tomcat7/bin/ 下的 setenv.sh 文件中导出 LD_LIBRARY_PATH 而不是上述步骤。设置成为 Tomcat 的一部分;更清洁的方法。
我正在使用 Tomcat7 和 Ubuntu。我有一个 Java Web 应用程序,它使用了一些本机库。当我 运行 Eclipse 中的 Web 应用程序时,它在调试期间通过 Eclipse 内部 Tomcat 服务器工作。但是,当我将应用程序部署到托管 Tomcat 服务时,应用程序在到达加载这些库的点时失败。
- 我把原生库放在/home/me/my_shared_libs,给了
文件夹和文件所有权归用户 "Tomcat7" --sudo chown
- 我将本机库的所有权限授予 "Tomcat7" 用户
--
sudo chmod
- 在
sudo vi /usr/share/tomcat7/bin/setenv.sh
中,并放入以下内容 在文件中export CATALINA_OPTS="-Djava.library.path=/home/me/my_shared_libs"
- 然后我重新启动 Tomcat --
sudo service tomcat7 restart
而且,每当 已达到加载本机库的引用,我收到有关InvocationTargetException
. 的错误
我也愿意选择将本机库添加为应用程序 .WAR 文件的一部分。 (虽然我不确定如何在 Eclipse 中执行此操作)。
/var/log/tomcat7/catalina.out
的日志-->
Jun 30, 2016 8:11:50 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 3643 ms
Load my_native_lib_called. libmachoman.so: cannot open shared object file: No such file or directory
编辑: 我发现了一件非常有趣的事情。 Tomcat 确实选择了我在上面设置的库位置。发生的情况是我在该位置有两种类型的库 (.so) 文件。第一个库 (libcore.so) calls/loads 第二个库 (libmachoman.so)。 libcore.so 已找到并加载,libmachoman.so 未找到,即使两者位于同一位置。
可以从代码本身完成。这应该会让您对库的加载充满信心。
为此,您可以使用 System.load()
以库的绝对路径为例
System.load("/PATH/TO/.so");
运行这段代码在应用程序启动时调用库函数之前一次。
您必须将您的图书馆放在所有服务器上的自定义位置。
System.loadLibrary() 也用于相同的目的,但不同之处在于它会按名称加载库并查看 Java 环境变量 java.library.path
指定的位置。
但是正如您所提到的,设置起来可能会很痛苦,必须在 tomcat 的所有实例中进行此更改。
头疼了几天,终于有了解决办法。
编辑文件
sudo vi /etc/ld.so.conf
在文件中追加本机库的位置
包括/etc/ld.so.conf.d/*.conf /home/me/my_shared_lib
加载配置
sudo ldconfig
查看新变化
ldconfig -p | grep my_shared_lib
这告诉动态链接器在哪里寻找本机库。
我的问题解决了。
还有其他替代解决方案 here,它们可能有也可能没有一些缺点。
或者(也发现),您可以在 /usr/share/tomcat7/bin/ 下的 setenv.sh 文件中导出 LD_LIBRARY_PATH 而不是上述步骤。设置成为 Tomcat 的一部分;更清洁的方法。