我可以将原生DLL打包到WAR中吗?

时间:2012-03-30 09:25:05

标签: java maven java-native-interface

我正在开发一个通过JNI使用本机代码的Web服务。 我可以将这些dll打包进我的战争中吗? 我已经厌倦了独立管理它们......

PS我正在使用maven PPS我正在使用Tomcat 7.x

6 个答案:

答案 0 :(得分:4)

来自src/main/webapp的所有内容都以root身份打包为war,所有来自src/main/resources的内容都打包到WEB-INF/classes。你可以打包你想要的东西

答案 1 :(得分:4)

是的,但是你会遇到很多问题。

  1. DLL从文件系统加载,而不是类路径 这不是一个严重的问题:只需将DLL作为资源存储在WAR中,然后将其复制到文件系统上的某个位置。属性java.io.tmpdir应该指向可写目录,或者您可以使用File.createTempFile()(只需确保在该文件上调用deleteOnExit())。然后你拨打System.load() System.loadLibary()

  2. 您必须为不同的架构管理DLL的不同副本
    如果您完全控制部署,并且知道您只能部署到一台计算机,那么这不是问题。否则,您需要编写代码来确定要加载的库。

  3. 您只能加载一次共享库
    这会对您造成伤害:当您加载共享库时,它会链接到JVM的可执行代码中。您无法重新加载相同的库,这意味着您无法重新部署。

  4. 当我上次不得不加载共享库以支持Web应用程序时,我最终将它放在app-servers共享目录中。这种方式要容易得多。

答案 2 :(得分:3)

DLL文件不是通过类路径加载的。 Classpath机制仅用于加载类文件和其他属性文件等java资源。

一种方法是指定DLL的完整路径或使用java.library.path系统变量指定它。请查看this link以获取更多详细信息。

答案 3 :(得分:3)

不,你不能。必须从文件系统加载DLL。您需要(1)铸铁保证应用程序服务器将WAR解压缩到文件系统,以及(2)知道DLL将在文件系统中解压到的确切位置,以便您可以调用{{1}使用正确的文件名。

答案 4 :(得分:2)

如果您的依赖项没有<scope>provided</scope>,它将被包含在war文件中,无论类型(jar,zip等,除非是另一场战争)。

虽然这是事实,但是您需要在.so上拥有本机库(.dlljava.library.path)。 EJP的担忧是有效的。但是,如果您使用程序集插件并将dll放在war文件的/META-INF目录下,则可以轻松地从类路径/META-INF/my.dll中获取一些代码并放置它在java.library.path

的目录中

这远非接近良好做法,但我相信你可以像这样破解它。

答案 5 :(得分:1)

@carlspring:你必须幸运地拥有对java.library.path中任何目录的写访问权。 (即Program Files \ Java等)更好的做法可能是将dll解压缩到临时目录,并在运行时将此目录添加到java.library.path。这是可能的:http://fahdshariff.blogspot.nl/2011/08/changing-java-library-path-at-runtime.html