清单 Class-Wildfly 模块中不支持的路径
manifest Class-Path not honored in a Wildfly module
我正在尝试为 OpenText Documentum java 客户端创建一个 Wildfly 模块。之前我将其 jar 打包到 .war 文件中,我的应用程序可以正常运行,但它们的重量为 23Mb。
在 J2SE 中,您通常只需添加 dfc.jar
的主 jar,并且会自动添加其依赖项,因为 dfc.jar/META-INF/MANIFEST.MF
中有 Class-Path:
条目。但是,它似乎在 Wildfly 11 中不起作用:我创建了模块,使我的 webapp 依赖于它,但是当我尝试从主 jar 加载 DfException
class 时,Wildfly 找不到同一文件夹中的依赖项之一:
Caused by: java.lang.NoClassDefFoundError: org/aspectj/lang/Signature
at com.documentum.fc.common.DfException.<clinit>(DfException.java:710)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at org.foo.PrintClassloaders.printClassloader0(PrintClassloaders.java:50)
是否可以在不手动添加所有 jar 的情况下创建此模块?
这是我所做的:
module add --name=documentum.dfc2 --absolute-resources="C:\Program Files\Documentum\Shared\dfc.jar"
src/main/resources/META-INF/MANIFEST.MF:
Dependencies: documentum.dfc2
PrintClassloaders.java:
Class.forName("com.documentum.fc.common.DfException");
生成module.xml:
<module xmlns="urn:jboss:module:1.1" name="documentum.dfc2">
<resources>
<resource-root path="C:\Program Files\Documentum\Shared\dfc.jar"/>
</resources>
</module>
dfc.jar/META-INF/MANIFEST.MF:
Class-Path: All-MB.jar activation.jar aspectjrt.jar certj.jar commons-
codec-1.3.jar commons-lang-2.4.jar configservice-api.jar configservic
e-impl.jar cryptoj.jar cryptojce.jar cryptojcommon.jar dms-client-api
.jar jaxb-api.jar jaxb-impl.jar jcifs-krb5-1.3.1.jar jcm.jar jcmFIPS.
jar jcmandroidfips.jar jsr173_api.jar krbutil.jar log4j.jar questFixF
orJDK7.jar util.jar vsj-license.jar vsj-standard-3.3.jar xtrim-api.ja
r xtrim-server.jar
aspectjrt.jar
在同一文件夹中。为什么模块 classloader 没有选择它?
你在那里尝试的东西对我来说看起来很奇怪。模块(=Java 库)属于模块文件夹,部署应该包含一个部署描述符,其中列出了它需要的所有模块。在最简单的情况下,您只需要 jboss-deployment-structure.xml 文件中的依赖项部分。参见 http://docs.wildfly.org/12/Developer_Guide.html#jboss-deployment-structure-file
每个模块可以包含多个jar 文件并依赖于其他模块。当您查看一些现有的 modules.xml 文件时,您将了解它是如何进行的。 module.xml 中的路径名称应该是相对的,否则您无法将它们部署到具有不同文件夹结构的另一台计算机上。
为此您不需要任何清单文件。
显然,要从清单 Class-Path 添加所有依赖的 jar 文件,您必须为每个 jar 显式创建一个 <resource-root>
元素。
对于 jar 太多或层次结构很深的情况,我制作了一个递归解析清单并打印 jboss-cli
命令以创建所需模块的工具。
Example:
C:\> java -cp org.foo.modulegen.Modulegen C:\some\main-jar.jar
Output:
--absolute-resources="C:\some\main-jar.jar;C:\some\jar2.jar;..."
https://gist.github.com/basinilya/15db9267ec753941d098cfd2f7ff844d
该工具尝试将每个命令行参数作为 java.util.zip.ZipInputStream
打开,使用 java.util.jar.Manifest
查找并解析 MANIFEST.MF
,然后对 [=16= 中的每个条目执行相同的操作] 属性。它还确保不会打开同一个 jar 文件两次。
我正在尝试为 OpenText Documentum java 客户端创建一个 Wildfly 模块。之前我将其 jar 打包到 .war 文件中,我的应用程序可以正常运行,但它们的重量为 23Mb。
在 J2SE 中,您通常只需添加 dfc.jar
的主 jar,并且会自动添加其依赖项,因为 dfc.jar/META-INF/MANIFEST.MF
中有 Class-Path:
条目。但是,它似乎在 Wildfly 11 中不起作用:我创建了模块,使我的 webapp 依赖于它,但是当我尝试从主 jar 加载 DfException
class 时,Wildfly 找不到同一文件夹中的依赖项之一:
Caused by: java.lang.NoClassDefFoundError: org/aspectj/lang/Signature
at com.documentum.fc.common.DfException.<clinit>(DfException.java:710)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at org.foo.PrintClassloaders.printClassloader0(PrintClassloaders.java:50)
是否可以在不手动添加所有 jar 的情况下创建此模块?
这是我所做的:
module add --name=documentum.dfc2 --absolute-resources="C:\Program Files\Documentum\Shared\dfc.jar"
src/main/resources/META-INF/MANIFEST.MF:
Dependencies: documentum.dfc2
PrintClassloaders.java:
Class.forName("com.documentum.fc.common.DfException");
生成module.xml:
<module xmlns="urn:jboss:module:1.1" name="documentum.dfc2">
<resources>
<resource-root path="C:\Program Files\Documentum\Shared\dfc.jar"/>
</resources>
</module>
dfc.jar/META-INF/MANIFEST.MF:
Class-Path: All-MB.jar activation.jar aspectjrt.jar certj.jar commons-
codec-1.3.jar commons-lang-2.4.jar configservice-api.jar configservic
e-impl.jar cryptoj.jar cryptojce.jar cryptojcommon.jar dms-client-api
.jar jaxb-api.jar jaxb-impl.jar jcifs-krb5-1.3.1.jar jcm.jar jcmFIPS.
jar jcmandroidfips.jar jsr173_api.jar krbutil.jar log4j.jar questFixF
orJDK7.jar util.jar vsj-license.jar vsj-standard-3.3.jar xtrim-api.ja
r xtrim-server.jar
aspectjrt.jar
在同一文件夹中。为什么模块 classloader 没有选择它?
你在那里尝试的东西对我来说看起来很奇怪。模块(=Java 库)属于模块文件夹,部署应该包含一个部署描述符,其中列出了它需要的所有模块。在最简单的情况下,您只需要 jboss-deployment-structure.xml 文件中的依赖项部分。参见 http://docs.wildfly.org/12/Developer_Guide.html#jboss-deployment-structure-file
每个模块可以包含多个jar 文件并依赖于其他模块。当您查看一些现有的 modules.xml 文件时,您将了解它是如何进行的。 module.xml 中的路径名称应该是相对的,否则您无法将它们部署到具有不同文件夹结构的另一台计算机上。
为此您不需要任何清单文件。
显然,要从清单 Class-Path 添加所有依赖的 jar 文件,您必须为每个 jar 显式创建一个 <resource-root>
元素。
对于 jar 太多或层次结构很深的情况,我制作了一个递归解析清单并打印 jboss-cli
命令以创建所需模块的工具。
Example:
C:\> java -cp org.foo.modulegen.Modulegen C:\some\main-jar.jar
Output:
--absolute-resources="C:\some\main-jar.jar;C:\some\jar2.jar;..."
https://gist.github.com/basinilya/15db9267ec753941d098cfd2f7ff844d
该工具尝试将每个命令行参数作为 java.util.zip.ZipInputStream
打开,使用 java.util.jar.Manifest
查找并解析 MANIFEST.MF
,然后对 [=16= 中的每个条目执行相同的操作] 属性。它还确保不会打开同一个 jar 文件两次。