在java EE中,我应该将哪些jar放入库目录?

时间:2013-02-14 00:39:24

标签: java-ee maven classpath ear maven-ear-plugin

我有一个Java EE项目。该项目使用maven构建为.ear存档。有一个包含JPA 2持久性单元的库jar,它位于耳朵的库目录中(因此多个其他模块可以使用它)。

虽然在此持久性单元中将Shiro的Permission接口的实现添加为实体,但我无法正确部署,因为shiro类在持久性单元中不可用。我最终发现我需要将库jar的所有依赖项(也适用于传递deps)放在库目录中以使其部署。

所以最终的布局大致如下:

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

现在,对于问题:

  1. 是否有任何指南应该放在库目录中,我的解决方案通常是否可以接受?
  2. 为什么lib目录中的jar中没有可用于耳根的库?
  3. 为什么maven不会自动解决这个问题?
  4. 编辑:耳朵的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>
    

3 个答案:

答案 0 :(得分:7)

  

是否有任何指南应该放在库目录中,我的解决方案通常是否可以接受?

你几乎已经把它钉了,所有EAR模块应该可用的JAR应该放在这里。

  

为什么lib目录中的jar中没有可用于耳根的库?

它通常以相反的方式工作,lib文件夹中的JAR可供根目录中的JAR使用。但是,我相信您可以使用<includeInApplicationXml>

来实现这一目标
<jarModule>
    <groupId>org.nisse</groupId>
    <artifactId>hue</artifactId>
    <includeInApplicationXml>true</includeInApplicationXml>
</jarModule>
  

为什么maven不会自动解决这个问题?

我认为你的意思是maven不会自动将所有传递依赖项放在lib中?我相信它应该做,并且确实 - 你能展示POM的相关部分吗?

编辑:您的EAR模块应仅将EJB JAR和WAR引用为依赖项。任何传递依赖项都应自动包含在EAR中,默认情况下位于顶级 - 这可以使用ear-plugin <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类路径。也许这正是你所缺少的?

干杯,

答案 1 :(得分:6)

我不会评论Maven的配置,而只是库应该去的地方。

在EAR模块中共享库有两种主要机制 - 捆绑库(在the Java EE 6 specification中的EE.8.2.1中描述)和已安装的库(EE.8.2.2)。

已安装的库与EAR分开安装,因此在应用程序服务器上的许多EAR之间共享。

捆绑库可以安装在lib(默认库目录)中,这是由EAR部署描述符的library-directory元素指定的目录和/或任何目录中使用模块的Class-Path清单标头(或模块引用的jar来引用,而模块又定义了一个传递库)。

我对Java EE 6规范的理解是Class-Path可以引用EAR中任何位置的任何库,但是jar的内容就变成了非Java EE模块。这意味着部署时不考虑persistence.xml,文件中定义的潜在持久化上下文在运行时不会生效。

在您的情况下,persistence-unit.jar似乎包含持久性单元配置,并使其可供其他模块使用,它应放在lib目录中。其他两个jar - shiro-core.jarslf4j-api.jar - 可以在EAR中的任何位置(包括lib目录进行简单部署 - 不需要在任何一个中使用Class-Path元素引用库/模块)。

为了简化部署,将其包含在lib目录中,除非使用Class-Path并指向另一个目录。在这种情况下,您宁愿检查引用jar文件是否不是具有持久性单元定义的Java EE jar,因为它将无法正确部署(并且PU将无法用于模块)。

答案 2 :(得分:3)

This article有一个很好的表格解释:

  

表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