манифест Class-Path не соблюдается в модуле Wildfly

Я пытаюсь создать модуль Wildfly для java-клиента OpenText Documentum. Раньше я запаковывал его jar-файлы в .war-файл, и мое приложение работало, но весило они 23 Мб.

В J2SE вы обычно просто добавляете основную банку, которая является dfc.jar, и ее зависимости добавляются автоматически из-за записи Class-Path: в dfc.jar/META-INF/MANIFEST.MF. Однако, похоже, это не работает в Wildfly 11: я создал модуль, сделал мое веб-приложение зависимым от него, но когда я пытаюсь загрузить класс DfException из основного jar-файла, 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)

Можно ли создать этот модуль, не добавляя все банки вручную?

Вот что я сделал:

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");

сгенерированный модуль.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 находится в той же папке. Почему он не выбран загрузчиком классов модуля?


person basin    schedule 08.02.2020    source источник


Ответы (2)


То, что вы там пытаетесь, кажется мне очень странным. Модули (= библиотеки Java) принадлежат папке модулей, и развертывание должно содержать дескриптор развертывания, в котором перечислены все необходимые модули. В самом простом случае вам нужен только раздел зависимостей внутри файла jboss-deployment-structure.xml. См. http://docs.wildfly.org/12/Developer_Guide.html#jboss-deployment-structure-file

Каждый модуль может содержать несколько файлов jar и зависеть от других модулей. Когда вы посмотрите на некоторые существующие файлы modules.xml, вы увидите, как это происходит. Пути внутри module.xml должны быть относительными, иначе вы не сможете развернуть их на другом компьютере с другой структурой папок.

Для этого вам не нужен файл манифеста.

person Stefan    schedule 08.02.2020
comment
Вы не понимаете. Пути могут быть абсолютными, начиная с Wildfly 10. Я знаю, что в модуле может быть несколько jar-файлов, я просто не хочу добавлять их вручную, потому что эта информация уже есть в файле манифеста. - person basin; 08.02.2020
comment
Я написал вам, что предоставляет Wildfly. Он не использует файл манифеста, как бы вы этого ни хотели. - person Stefan; 08.02.2020

По-видимому, чтобы добавить все зависимые файлы jar из манифеста Class-Path, вы должны явно создать элемент <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/basinila/15db9267ec753941d098cfd2f7ff844d

Инструмент пытается открыть каждый аргумент командной строки как java.util.zip.ZipInputStream, находит и анализирует MANIFEST.MF с помощью java.util.jar.Manifest, а затем делает то же самое для каждой записи в атрибуте Class-Path. Это также гарантирует, что один и тот же файл jar не будет открываться дважды.

person basin    schedule 11.02.2020