在Linux环境下将文件打入ear包(Enterprise Archive,企业级归档文件)是Java EE应用开发中的常见操作,ear包主要用于打包企业级应用,包含EJB模块、Web模块、客户端JAR模块以及依赖库等,本文将详细介绍在Linux系统中手动使用jar命令和使用构建工具(如Maven、Gradle)创建ear包的具体步骤、注意事项及最佳实践。

了解ear包的基本结构
在开始打包前,需先明确ear包的标准目录结构,这是确保应用能正确部署和运行的基础,一个典型的ear包包含以下核心内容:
| 目录/文件 | 说明 |
|---|---|
| META-INF/ | 必需目录,存放ear包的描述文件,如application.xml、MANIFEST.MF等。 |
| application.xml | ear包的部署描述文件,定义模块、安全约束、上下文参数等。 |
| lib/ | 可选目录,存放ear包依赖的第三方JAR包(如数据库驱动、工具库等)。 |
| EJB模块/ | 必需或可选,存放EJB组件的JAR包,结构需符合EJB规范(如包含META-INF/ejb-jar.xml)。 |
| Web模块/ | 可选,存放Web应用的WAR包,包含Web资源(HTML、JSP、Servlet等)和WEB-INF/web.xml。 |
| 客户端JAR模块/ | 可选,存放客户端应用程序的JAR包,包含客户端类和META-INF/application-client.xml。 |
一个简单的ear包结构可能如下:
myapp.ear
├── META-INF/
│ ├── application.xml
│ └── MANIFEST.MF
├── lib/
│ ├── mysql-connector-java-8.0.33.jar
│ └── log4j-1.2.17.jar
├── ejb/
│ └── EjbModule.jar
└── web/
└── WebModule.war
手动使用jar命令创建ear包
在Linux中,可通过Java自带的jar命令手动打包ear包,适合小型项目或快速验证场景,以下是详细步骤:
准备目录和文件
首先创建ear包的根目录(如myapp)及子目录,并放入对应模块文件。
# 创建目录结构 mkdir -p myapp/META-INF myapp/lib myapp/ejb myapp/web # 复制模块文件到对应目录(假设已有EJB模块EjbModule.jar和Web模块WebModule.war) cp EjbModule.jar myapp/ejb/ cp WebModule.war myapp/web/ cp mysql-connector-java-8.0.33.jar myapp/lib/
创建application.xml
application.xml是ear包的核心描述文件,需放在META-INF目录下,示例内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/application_7.xsd"
version="7">
<!-- 模块声明:EJB模块 -->
<module>
<ejb>EjbModule.jar</ejb>
</module>
<!-- 模块声明:Web模块 -->
<module>
<web>
<web-uri>WebModule.war</web-uri>
<context-root>/myapp</context-root>
</web>
</module>
<!-- 可选:定义上下文参数 -->
<context-param>
<param-name>configLocation</param-name>
<param-value>/WEB-INF/spring-config.xml</param-value>
</context-param>
</application>
创建文件并写入内容:
cat > myapp/META-INF/application.xml << EOF
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="7">
<module><ejb>EjbModule.jar</ejb></module>
<module>
<web>
<web-uri>WebModule.war</web-uri>
<context-root>/myapp</context-root>
</web>
</module>
</application>
EOF
使用jar命令打包
进入myapp目录的上一级,执行jar命令打包(-c创建归档,-v显示过程,-f指定文件名,-C切换目录):
cd /path/to/myapp_parent jar -cvf myapp.ear -C myapp .
命令说明:

-c:创建新的归档文件。-v:生成详细输出,显示打包的文件列表。-f myapp.ear:指定归档文件名为myapp.ear。-C myapp .:先切换到myapp目录,再将该目录下所有文件(表示当前目录所有内容)打包到归档中。
执行后,当前目录会生成myapp.ear文件,可通过jar tf myapp.ear查看包内结构:
jar tf myapp.ear # 输出示例: META-INF/ META-INF/application.xml META-INF/MANIFEST.MF lib/mysql-connector-java-8.0.33.jar ejb/EjbModule.jar web/WebModule.war
使用Maven构建ear包
实际开发中,推荐使用Maven等构建工具管理依赖和打包,能自动处理模块依赖、路径问题,并支持标准化构建流程。
创建Maven项目
执行Maven命令创建ear项目骨架:
mvn archetype:generate -DgroupId=com.example -DartifactId=myapp-ear -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-ear -DinteractiveMode=false
配置pom.xml
进入项目目录(cd myapp-ear),编辑pom.xml,添加ear插件和模块依赖,核心配置如下:
<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>
<!-- 基本信息 -->
<groupId>com.example</groupId>
<artifactId>myapp-ear</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>ear</packaging>
<!-- 依赖管理:定义ear包含的模块 -->
<dependencies>
<!-- EJB模块依赖(需先创建EJB项目并install到本地仓库) -->
<dependency>
<groupId>com.example</groupId>
<artifactId>ejb-module</artifactId>
<version>1.0-SNAPSHOT</version>
<type>ejb</type>
</dependency>
<!-- Web模块依赖(需先创建Web项目并install到本地仓库) -->
<dependency>
<groupId>com.example</groupId>
<artifactId>web-module</artifactId>
<version>1.0-SNAPSHOT</version>
<type>war</type>
</dependency>
<!-- 第三方依赖(如数据库驱动) -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
</dependencies>
<!-- ear插件配置 -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<!-- ear包输出名称(可选,默认为${artifactId}.ear) -->
<finalName>myapp</finalName>
<!-- 是否将依赖的JAR包打入ear的lib目录(默认仅对scope=provided的依赖) -->
<defaultLibBundleDir>lib</defaultLibBundleDir>
<!-- 自定义application.xml路径(可选,默认使用模板生成) -->
<applicationXml>${project.basedir}/src/main/application/META-INF/application.xml</applicationXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
创建自定义application.xml(可选)
Maven默认会生成application.xml,但推荐自定义以控制模块和上下文根,在src/main/application/META-INF/下创建application.xml:
mkdir -p src/main/application/META-INF
cat > src/main/application/META-INF/application.xml << EOF
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="7">
<module><ejb>ejb-module-1.0-SNAPSHOT.jar</ejb></module>
<module>
<web>
<web-uri>web-module-1.0-SNAPSHOT.war</web-uri>
<context-root>/myapp</context-root>
</web>
</module>
</application>
EOF
执行打包命令
在项目根目录执行Maven打包命令:
mvn clean package
执行成功后,target目录会生成myapp.ear文件(finalName配置的名称),可通过mvn dependency:copy-dependencies将第三方依赖复制到target/lib目录,确保ear包包含所有必需库。
使用Gradle构建ear包
Gradle是另一种流行的构建工具,通过配置build.gradle文件也能实现ear包打包。

创建Gradle项目
初始化Gradle项目:
gradle init --type java-application --dsl groovy --test-framework junit-jupiter --project-name myapp-ear
配置build.gradle
编辑build.gradle,添加ear插件和依赖:
plugins {
id 'ear'
id 'java'
}
group 'com.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
// 依赖配置
dependencies {
// EJB模块(需先创建并发布到本地或远程仓库)
earLib 'com.example:ejb-module:1.0-SNAPSHOT@jar'
// Web模块
earLib 'com.example:web-module:1.0-SNAPSHOT@war'
// 第三方依赖(自动打入ear的lib目录)
earLib 'mysql:mysql-connector-java:8.0.33'
}
// ear插件配置
ear {
// 自定义ear包名称
archiveName = 'myapp.ear'
// 将依赖的JAR包放入lib目录(默认行为)
libDirName = 'lib'
// 自定义application.xml路径
deploymentDescriptor {
filePath = 'META-INF/application.xml'
}
}
执行打包命令
在项目根目录执行:
gradle ear
构建完成后,build/libs目录会生成myapp.ear文件。
注意事项
- 模块依赖顺序:确保EJB模块、Web模块等依赖模块已提前构建并安装到本地仓库(Maven)或发布(Gradle),否则打包时会报错。
- application.xml规范:
application.xml需符合Java EE版本规范(如Java EE 7使用version="7"),模块路径需与ear包内实际路径一致。 - 依赖范围:使用Maven时,第三方依赖的
scope默认为compile,会自动打入ear的lib目录;若依赖仅在运行时需要(如Servlet API),需设置为provided,避免重复打包。 - 路径问题:手动使用
jar命令时,-C参数指定的目录需准确,否则可能导致文件路径错误(如将myapp目录本身打入ear包,导致内部结构嵌套)。
相关问答FAQs
问题1:在Linux中使用jar命令打包ear时,提示“java.util.zip.ZipException: duplicate entry”,如何解决?
解答:该错误通常是因为ear包中存在重复文件,可通过以下步骤排查:
- 使用
jar tf myapp.ear查看ear包内容,定位重复文件(如多个同名JAR或类文件)。 - 检查模块依赖:若EJB模块和Web模块同时依赖了同一第三方库(如log4j),需确保仅在一个模块中引入,或通过
<scope>provided</scope>排除重复依赖。 - 手动删除重复文件后重新打包。
问题2:使用Maven构建ear包时,如何将第三方JAR包(如自定义工具库)一同打入ear的lib目录?
解答:有两种方式实现:
- 直接依赖:在
pom.xml的<dependencies>中添加第三方JAR依赖,并确保<scope>为compile(默认),Maven ear插件会自动将其打入lib目录:<dependency> <groupId>com.example</groupId> <artifactId>custom-utils</artifactId> <version>1.0</version> </dependency> - 手动复制:若JAR不在Maven仓库中,可通过
maven-dependency-plugin复制到项目lib目录,再配置ear插件包含该目录:<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>3.6.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>copy</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/lib</outputDirectory> <artifactItems> <artifactItem> <groupId>com.example</groupId> <artifactId>custom-utils</artifactId> <version>1.0</version> <type>jar</type> <overWrite>false</overWrite> <destFileName>custom-utils.jar</destFileName> </artifactItem> </artifactItems> </configuration> </execution> </executions> </plugin>之后在ear插件配置中添加
<libsDirectory>${project.build.directory}/lib</libsDirectory>,确保手动复制的JAR被打包。
原创文章,发布者:酷番叔,转转请注明出处:https://cloud.kd.cn/ask/15914.html