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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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