I'm trying to create a Wildfly Module for OpenText Documentum java client. Previously I was packing its jars to the .war file and my app was working, but they weight 23Mb.
In J2SE you usually just add the main jar which is dfc.jar
and its dependencies are automatically added, because of Class-Path:
entry in dfc.jar/META-INF/MANIFEST.MF
. However, it doesn't seem to work in Wildfly 11: I created the module, made my webapp depend on it, but when I try to load the DfException
class from the main jar Wildfly fails to find one of the dependencies which are in the same folder:
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)
Is it possible to create this module without adding all the jars by hand?
Here's what I did:
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");
generated 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
is in the same folder. Why isn't it picked by the module classloader?
Apparently, to add all the dependent jar files from the manifest Class-Path you have to explicitly create a <resource-root>
element for each jar.
For cases when there is too many jars or there's a deep hierarchy I made a tool that parses the manifests recursively and prints the jboss-cli
command to create the desired module.
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
The tool tries to open each command line argument as a java.util.zip.ZipInputStream
, finds and parses MANIFEST.MF
with java.util.jar.Manifest
and then does the same for each entry in the Class-Path
attribute. It also ensures to not open the same jar file twice.