В java EE, какие банки следует положить в библиотечный каталог?

У меня есть проект Java EE. Проект построен с использованием maven в архиве. Существует библиотека, содержащая блок сохранения JPA 2, который находится в библиотечном каталоге уха (поэтому несколько других модулей могут его использовать).

При добавлении реализации интерфейса Shiro Permission в качестве объекта в этом персистентном блоке у меня возникли проблемы с правильной установкой уха, потому что классы siro, которые недоступны в модуле сохранения. В конце концов, я понял, что мне нужно было поместить все зависимости (применимые также к транзитивным папкам) библиотеки jar в библиотечном каталоге, чтобы он был развернут.

Итак, окончательный макет выглядит примерно так:

ear
`- lib
   `- persistence-unit.jar
    - shiro-core.jar
    - slf4j-api.jar
 - module1
 - moduleN
 - library1.jar
 - libraryN.jar

Теперь, для вопросов:

  • Существуют ли какие-либо направляющие строки для того, что должно быть помещено в каталог библиотеки, и приемлемо ли мое решение?
  • Почему библиотеки в корне уха недоступны для jars в каталоге lib?
  • Почему maven не выясняет это автоматически?

EDIT: pom.xml для уха

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <artifactId>ear</artifactId>
    <packaging>ear</packaging>

    <parent>
        <groupId>com.example</groupId>
        <artifactId>project</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-ear-plugin</artifactId>
                <version>2.7</version>
                <configuration>
                    <modules>
                        <webModule>
                            <!-- ... -->
                        </webModule>
                        <ejbModule>
                            <!-- ... -->
                        </ejbModule>
                        <jarModule>
                            <groupId>com.example</groupId>
                            <artifactId>persistence-unit</artifactId>
                            <bundleDir>lib</bundleDir>
                        </jarModule>

                        <-- I added these to get the deployment working -->
                        <jarModule>
                            <groupId>org.apache.shiro</groupId>
                            <artifactId>shiro-core</artifactId>
                            <bundleDir>lib</bundleDir>
                        </jarModule>
                        <jarModule>
                            <groupId>org.slf4j</groupId>
                            <artifactId>slf4j-api</artifactId>
                            <bundleDir>lib</bundleDir>
                        </jarModule>
                    </modules>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>persistence-unit</artifactId>
        </dependency>
        <dependency>
            <!-- ... -->
            <type>war</type>
        </dependency>
        <dependency>
            <!-- ... -->
            <type>ejb</type>
        </dependency>

        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
        </dependency>
    </dependencies>
</project>

И для единицы сохранения:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <artifactId>persistence-unit</artifactId>
    <packaging>jar</packaging>

    <parent>
        <groupId>com.example</groupId>
        <artifactId>project</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.jboss.spec</groupId>
            <artifactId>jboss-javaee-6.0</artifactId>
            <type>pom</type>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
        </dependency>
    </dependencies>
</project>

Ответ 1

Существуют ли какие-либо направляющие строки для того, что должно быть помещено в каталог библиотеки, и приемлемо ли мое решение?

Вы довольно много прибивали его, JAR, которые должны быть доступны для всех модулей EAR, должны идти здесь.

Почему библиотеки в корне уха не доступны для jars в каталоге lib?

Как правило, это работает наоборот, JAR в папке lib доступны для тех, что находятся в корне. Однако я считаю, что вы можете достичь этого, используя <includeInApplicationXml>:

<jarModule>
    <groupId>org.nisse</groupId>
    <artifactId>hue</artifactId>
    <includeInApplicationXml>true</includeInApplicationXml>
</jarModule>

Почему maven не выясняет это автоматически?

Предполагаю, вы имеете в виду, что maven автоматически не помещает все транзитивные зависимости в lib? Я считаю, что он должен это делать, и делает - можете ли вы показать соответствующую часть своего ПОМ?

Изменить:. Ваш EAR-модуль должен ссылаться только на JJ файлы EJB и WARs в качестве зависимостей. Любые транзитивные зависимости должны быть включены в EAR автоматически, на верхнем уровне по умолчанию - это можно переопределить тегом <defaultLibBundleDir> в плагине уха <configuration>:

<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<version>2.7</version>
<configuration>
    <defaultLibBundleDir>lib</defaultLibBundleDir>
    <archive>
        <manifest>
            <addClasspath>true</addClasspath>
        </manifest>
    </archive>
    <modules>
       ... etc.

Кроме того, раздел <archive>/<addClasspath> должен гарантировать правильную настройку пути класса MANIFEST. Возможно, это именно то, чего вам не хватает?

Приветствия,

Ответ 2

Я не буду комментировать конфигурацию Maven, но просто там, где должны идти библиотеки.

Существует два основных механизма для обмена библиотеками между модулями EAR - Библиотеки с добавлением (описанные в EE.8.2.1 в спецификация Java EE 6) и Установленные библиотеки (EE.8.2.2).

Установленные библиотеки устанавливаются отдельно от EAR и поэтому распределяются между многими EAR на сервере приложений.

Связанные библиотеки могут быть установлены в lib (каталог библиотеки по умолчанию), каталог, указанный элементом library-directory дескриптора развертывания EAR и/или в любом каталоге, на который будут ссылаться заголовок манифеста Class-Path модуля (или банку, на который ссылается модуль, который в свою очередь определяет транзитивную библиотеку).

Мое понимание спецификации Java EE 6 заключается в том, что Class-Path может ссылаться на любую библиотеку в любом месте EAR, но содержимое jar становится не-Java EE-модулем. Это означает, что persistence.xml не рассматривается при развертывании, а потенциальные контексты персистентности, определенные в файле, не будут вступать в силу во время выполнения.

В вашем случае persistence-unit.jar, похоже, содержит конфигурации единиц сохранения и чтобы сделать их доступными для других модулей, он должен быть помещен в каталог lib. Остальные две банки - shiro-core.jar и slf4j-api.jar - могут быть в любом месте EAR (включая каталог lib для простого развертывания - нет необходимости иметь элемент Class-Path в любой из библиотек ссылок/модулей).

Объединяя его, чтобы облегчить развертывание, ваши библиотеки находятся в каталоге lib, если не используется Class-Path и указывает на другой каталог. В этом случае вам лучше проверить, не является ли связанный файл jar не ява Java EE с определением единицы продолжительности, поскольку он не будет правильно развернут (и PU не будут доступны для модулей).

Ответ 3

В этой статье есть отличная таблица, объясняющая вещи:

Таблица 2 Стандартный архив может загружать классы, упакованные внутри него или из любых других архивов, на которые он зависит.

Module      Code Sources
EAR 
            All JARs in the /lib directory of the EAR
            Manifest Class-Path of any JARs in 1
EJB-JAR 
            EJB-JAR file itself
            JARs referenced by manifest Class-Path of EJB-JAR
            JARs referenced by manifest Class-Path of above JARs (in 2)
WAR 
            WEB-INF/classes
            JARs in WEB-INF/lib
            JARs referenced by manifest Class-Path of WAR
            JARs referenced by manifest Class-Path of JARs in 2 and 3