在前面的章節中,我們學習了 JAR(Java Archive)和 WAR(Web Application Archive)的打包方式。今天我們要探討企業級應用開發中的另一個重要打包格式:EAR (Enterprise Application Archive)。
EAR 是 Java EE(現在稱為 Jakarta EE)規範中定義的企業應用打包格式,專門用於將多個模組(JAR、WAR、RAR)打包成一個可部署的單元,簡化部署流程
EAR (Enterprise Application Archive) 同JAR檔他也是一個ZIP格式的檔案式,它可以同時將WAR、JAR、RAR檔集於一身包裝成EAR,它需要部署於有實作JavaEE規格的Application Server中,像是常見的Tomcat是無法部署該類型檔案的,需要部署像是TomEE、Jboss EAP、WebSphere這樣類型的Application Server中,EAR相關內容請參考以下圖片
註:圖片來自Jarkata官網
1. META-INF: 通常會有Jarkata EE規格的部署描述檔(Deployment descriptors,簡稱DD檔)與實作Jarkata EE的AppServer的部署描述檔,例如glassfish-application.xml、ibm-ejb-jar-bnd.xmi、 jboss-deployment-structure.xml等等
2. EJB Module: 當開發出企業級元件Enterprise Bean時,就需要透過部署描述檔ejb-jar.xml來與AppServer進行溝通,MAINFEST.MF作為JAR檔相關資訊存放的地方
3. Web Module: 與前一日介紹的相近,不同的是當有使用到Enterprise Bean則會需要新增部署描述檔ejb-jar.xml
4. Application Client Module: 專門用於其他應用程式或其他 Java 應用程式存取到EAR中提供的企業級服務模組。
4. Resource Application Module: 資源配接器模組針對特定 EIS(企業資訊系統,Enterprise Information System)的 連接器架構封裝為副檔名為 .rar(Resource Adapter Archive)的 JAR 檔案。
1.準備TomEE
要執行JavaEE專案我們需要有support的Application Server,我們選用TomEE作為示範,下載並解壓縮
2.創建專案
請參考Day 15 - Project Inheritance 建置專案結構
demoejb
+---demoear-ear (作為打包使用module)
|
+---demoear-ejb (ejb module)
|
+---demoear-web (引用ejb的web module)
|
\---demoejb-client (client呼叫ejb的app)
3.父層pom
<groupId>com.mycompany.demoear</groupId>
<artifactId>demoear</artifactId>
<version>1.0-SNAPSHOT</version>
<name>demoear</name>
<description>demo ear project</description>
<packaging>pom</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- 加入以下編碼設定 -->
<file.encoding>UTF-8</file.encoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<tomee.version>10.1.2</tomee.version>
</properties>
<modules>
<module>demoear-ejb</module>
<module>demoear-web</module>
<module>demoear-client</module>
<module>demoear-ear</module>
</modules>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-api</artifactId>
<version>10.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
4.demoear-ejb模組
pom.xml
<parent>
<artifactId>demoear</artifactId>
<groupId>com.mycompany.demoear</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>demoear-ejb</artifactId>
<name>demoear-ejb</name>
<packaging>ejb</packaging>
HelloLocal.java
@Local
public interface HelloLocal {
String sayHello(String name);
}
HelloLocalBean.java
@Stateless
public class HelloLocalBean implements HelloLocal {
@Override
public String sayHello(String name) {
return "HelloLocal, " + name + "!";
}
}
HelloRemote.java
@Remote
public interface HelloRemote {
String sayHello(String name);
}
HelloRemoteBean.java
@Stateless
public class HelloRemoteBean implements HelloRemote {
@Override
public String sayHello(String name) {
return "HelloRemote, " + name + "!";
}
}
5.demoear-web 模組
<parent>
<artifactId>demoear</artifactId>
<groupId>com.mycompany.demoear</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>demoear-web</artifactId>
<packaging>war</packaging>
<name>demoear-web Maven Webapp</name>
<dependencies>
<dependency>
<groupId>com.mycompany.demoear</groupId>
<artifactId>demoear-ejb</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
HelloServlet.java
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
@EJB
private HelloLocal helloLocal;
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
String message = helloLocal.sayHello("Hi Demoear Webmodule");
response.setContentType("text/plain");
try {
response.getWriter().write(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
6.demoear-client 模組
<parent>
<artifactId>demoear</artifactId>
<groupId>com.mycompany.demoear</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>demoear-client</artifactId>
<name>demoejb-client</name>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>demoear-ejb</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomee</groupId>
<artifactId>openejb-core</artifactId>
<version>${tomee.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
public class App {
public static void main(String[] args) throws Exception {
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.core.LocalInitialContextFactory");
p.put(Context.PROVIDER_URL, "http://localhost:8080/tomee/ejb");
final Context ctx = new InitialContext(p);
HelloRemote helloBean = (HelloRemote) ctx.lookup("HelloRemoteBeanRemote");
String message = helloBean.sayHello("EJB Client");
System.out.println("Result: " + message);
}
}
7.demoear-ear 模組
<parent>
<groupId>com.mycompany.demoear</groupId>
<artifactId>demoear</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>demoear-ear</artifactId>
<packaging>ear</packaging>
<name>ear assembly</name>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>demoear-ejb</artifactId>
<version>${project.version}</version>
<type>ejb</type>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>demoear-web</artifactId>
<version>${project.version}</version>
<type>war</type>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Cargo Plugin for TomEE -->
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven3-plugin</artifactId>
<configuration>
<container>
<containerId>tomee9x</containerId>
<home>H:\Java\apache-tomee-plus-10.1.2</home>
</container>
<configuration>
<type>standalone</type>
</configuration>
<deployables>
<deployable>
<groupId>com.mycompany.demoear</groupId>
<artifactId>demoear-ear</artifactId>
<type>ear</type>
</deployable>
</deployables>
</configuration>
</plugin>
</plugins>
</build>
web執行
client執行
因為對Jarkata EE不熟這一天寫來真不易,透過Web註解的方式就可調用EJB,EJB本身也透過註解進行設定相當方便,大幅簡化過去需要設定ejb-jar.xml的流程,回歸今天的主題,我們演示了JarktaEE的專案,通常會是以多模組的形式出現,會有一個額外的模組進行ear檔打包,另外在打包Web模組時有遇到因為EJB的JAR我們有打包進EAR檔,所以pom.xml只需要設定provided就可以了