javawildflywildfly-11jboss-modules

manifest Class-Path not honored in a Wildfly module


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?


Solution

  • 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.