พัฒนา Java EE 6 ด้วย Maven

ปกติผมไม่ค่อยชอบ Maven นะ แล้วก็บริษัทที่ผมทำด้วยส่วนมากไม่ใช้ Maven (เรียกว่าผมไม่เคยสัมผัสโปรเจคที่สร้างด้วย Maven เลยก็ว่าได้) แต่นึกครึ้มอกครึ้มใจอยากลอง Maven ในการสร้าง Project ที่ใช้ Java EE 6 คิดซะว่าเป็นการหัด Maven ไปในตัว

Create maven web project

  1. ขั้นตอนการสร้าง Maven web project ก็ยังใช้คำสั่งปกติได้เหมือนเดิมประมาณนี้

    mvn archetype:create -DgroupId=com.magicalcyber.jupiter -DartifactId=jupiter -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false

    ก็จะได้ Project Structure ดังนี้

    Project structure

  2. จากนั้นผมแก้ไขไฟล์ pom.xml โดยตั้ง encoding เป็น UTF-8

    
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      </properties>
    

    และเพิ่ม tomcat plugin และตั้ง jdk ให้เป็น 1.6

    <pluginManagement>
          <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
            <plugin>
              <groupId>org.apache.tomcat.maven</groupId>
              <artifactId>tomcat7-maven-plugin</artifactId>
              <version>2.1</version>
            </plugin>
          </plugins>
        </pluginManagement>
    

    แล้วใช้คำสั่ง mvn tomcat7:run แล้วเปิด browser เข้า url: http://localhost:8080/jupiter ก็พบหน้า Hello world ดังรูป

    tomcat7 run

Hello Servlet!

  1. แก้ไขไฟล์ pom.xml โดยเพิ่ม repository ดังนี้

    <repositories>
        <repository>
          <id>java.net2</id>
          <name>Repository hosting the jee6 artifacts</name>
          <url>http://download.java.net/maven/2</url>
        </repository>
      </repositories>  
    

    และเพิ่ม dependency ดังนี้

    <dependency>
          <groupId>javax</groupId>
          <artifactId>javaee-web-api</artifactId>
          <version>6.0</version>
          <scope>provided</scope>
        </dependency>
    

    เนื่องจากว่า Servlet 3.0+ ไม่จำเป็นต้องใช้ web.xml แล้ว ผมจึง stop tomcat แล้วลบไฟล์นี้ออก จากนั้นก็ run ใหม่ ก็ยังปกติดี

  2. สร้างโฟลเดอร์ java และ test ใน src/main แล้วสร้าง Servlet ขึ้นมาดังนี้

    package com.magicalcyber.jupiter.servlet;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    @WebServlet("/hello")
    public class HelloWorldServlet extends HttpServlet {
    	@Override
        protected void doGet(HttpServletRequest req, HttpServletResponse res)
                throws IOException, ServletException {
        	res.setContentType( "text/html; charset=UTF-8" );
            res.getWriter().write("<h2>Hello Servlet!</h2>");
        }
    }
    

    เราไม่ต้องง้อ web.xml แล้ว แค่เพียงเราเพิ่ม @WebServlet เราก็สร้าง Servlet ได้แล้ว จากนั้นก็รัน servlet ดูผลลัพธ์

    hello servlet

    แต่พอใช้คำสั่ง mvn package ก็จะพบกับปัญหาหลักของเราเลยก็คือ maven ต้องการ web.xml

    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD FAILURE
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time: 2.584s
    [INFO] Finished at: Thu Aug 22 16:10:39 ICT 2013
    [INFO] Final Memory: 9M/247M
    [INFO] ------------------------------------------------------------------------
    [ERROR] Failed to execute goal org.apache.maven.plugins:maven-war-plugin:2.2:war
    (default-war) on project jupiter: Error assembling WAR: webxml attribute is req
    uired (or pre-existing WEB-INF/web.xml if executing in update mode) -> [Help 1]
    [ERROR]
    [ERROR] To see the full stack trace of the errors, re-run Maven with the -e swit
    ch.
    [ERROR] Re-run Maven using the -X switch to enable full debug logging.
    [ERROR]
    [ERROR] For more information about the errors and possible solutions, please rea
    d the following articles:
    [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionE
    xception

    วิธีแก้ไขก็คือไม่ให้ maven สนใจว่าตอนทำ war ไม่ต้องสนใจว่าไฟล์มันหายนั่นเอง (ง่ายเนอะ หาไม่เจอก็บอกไม่ต้องสนใจ) ดังนี้

    		<plugin>
    			<groupId>org.apache.maven.plugins</groupId>
    			<artifactId>maven-war-plugin</artifactId>
    			<version>2.1.1</version>
    			<configuration>
    				<failOnMissingWebXml>false</failOnMissingWebXml>
    			</configuration>
    		</plugin>
    

Hello EJB!

  1. เนื่องจาก Tomcat เป็นแค่ Servlet Container ไม่สามารถรัน EJB ได้ จึงต้องเปลี่ยน Server เป็นตัวอื่น ผมเลือก Apache Tomee เพราะเล็ก และสร้างจาก Tomcat แล้วเอา OpenEJB มาเสริม ซึ่งวิธีเอามาใช้กับ Maven ก็เหมือนกับ Tomcat เลยคือแก้ไข pom.xml ดังนี้

    <plugin>
    		  <groupId>org.apache.openejb.maven</groupId>
    		  <artifactId>tomee-maven-plugin</artifactId>
    		  <version>1.0.1</version>
    		  <configuration>
    			<tomeeVersion>1.5.2</tomeeVersion>
    			<tomeeClassifier>plus</tomeeClassifier>
    		  </configuration>
    		</plugin>
    

  2. สร้าง EJB แบบ Singleton ประมาณนี้

    package com.magicalcyber.jupiter.ejb;
    
    @javax.ejb.Singleton
    public class HelloBean{
    	public String hello(){
    		return "Hello EJB!";
    	}
    }
    

    การสร้าง EJB เวอร์ชั่น 3.1 นี้ง่ายมากขึ้น ถ้าจะสร้างเป็นแบบ Stateless ก็เพียงเปลี่ยนจาก Singleton เป็น Stateless ก็ได้แล้ว

  3. วิธีการเรียกใช้ EJB ก็ง่ายขึ้นเยอะครับ ให้ไปแก้ HelloWorldServlet ดังนี้

    package com.magicalcyber.jupiter.servlet;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.magicalcyber.jupiter.ejb.HelloBean;
    
    @WebServlet("/hello")
    public class HelloWorldServlet extends HttpServlet {
    
    	@javax.ejb.EJB
    	private HelloBean helloBean;
    
    	@Override
        protected void doGet(HttpServletRequest req, HttpServletResponse res)
                throws IOException, ServletException {
        	res.setContentType( "text/html; charset=UTF-8" );
            res.getWriter().write("<h2>Hello Servlet!</h2>");
            res.getWriter().write("<h2>"+helloBean.hello()+"</h2>");
        }
    }
    

    ในการเรียก EJB ก็เพียงแค่ประกาศตัวแปรเป็น EJB ตัวนั้นแล้วเพิ่ม @javax.ejb.EJB เข้าไป
    ส่วนวิธีการ Start Server ตัว tomee ให้ใช้คำสั่ง mvn tomee:start นะครับ
    จากนั้นก็เรียกใช้งานตามปกติ ก็จะได้หน้าจอดังนี้

    hello ejb

EJB Web Service

ง่ายมากครับ เอา HelloEJB มายำเป็น Web Service ก็ได้ โดยแก้ไขโค้ดดังนี้

package com.magicalcyber.jupiter.ejb;

@javax.jws.WebService
@javax.ejb.Singleton
@javax.ejb.LocalBean
public class HelloBean{
	public String hello(){
		return "Hello EJB!";
	}
}

จากนั้น Start tomee หากไม่พบ Error อะไรก็เข้า url ดังนี้
http://localhost:8080/jupiter/webservices/HelloBean?wsdl ก็จะพบกับหน้าจอ WSDL ที่คุ้นเคย

restful web service

EJB RESTful Web Service

แก้ไข Web Service จากข้อก่อนหน้าดังนี้

package com.magicalcyber.jupiter.ejb;

@javax.ws.rs.Path("/rest")
@javax.jws.WebService
@javax.ejb.Singleton
@javax.ejb.LocalBean
public class HelloBean{

	@javax.ws.rs.GET
	public String hello(){
		return "Hello EJB!";
	}
}

เวลา Start Server จะพบ Log ดังนี้

INFO: REST Service: http://localhost:8080/jupiter/rest/* -> EJB HelloBean

หากยังไม่ขึ้นว่า /rest ให้สั่ง clean ก่อนแล้ว Start ใหม่ แล้วลองเข้า URL ข้างบนก็จะได้หน้าตาดังนี้

restful web service

ก่อนจาก

หน้าตาของไฟล์ pom.xml เวอร์ชั่นเต็มครับ

<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.magicalcyber.jupiter</groupId>
  <artifactId>jupiter</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>jupiter Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
   <repositories>
    <repository>
      <id>java.net2</id>
      <name>Repository hosting the jee6 artifacts</name>
      <url>http://download.java.net/maven/2</url>
    </repository>
  </repositories>  
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
	<dependency>
      <groupId>javax</groupId>
      <artifactId>javaee-web-api</artifactId>
      <version>6.0</version>
      <scope>provided</scope>
    </dependency>
	<dependency>
		<groupId>org.slf4j</groupId>
		<artifactId>slf4j-log4j12</artifactId>
		<version>1.7.5</version>
	</dependency>
	<dependency>
		<groupId>org.mockito</groupId>
		<artifactId>mockito-all</artifactId>
		<version>1.8.4</version>
	</dependency>				
  </dependencies>
  <build>
    <finalName>jupiter</finalName>
	<pluginManagement>
      <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
            </configuration>
        </plugin>
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-war-plugin</artifactId>
			<version>2.1.1</version>
			<configuration>
				<failOnMissingWebXml>false</failOnMissingWebXml>
			</configuration>
		</plugin>
        <plugin>
          <groupId>org.apache.tomcat.maven</groupId>
          <artifactId>tomcat7-maven-plugin</artifactId>
          <version>2.1</version>
        </plugin>
		<plugin>
		  <groupId>org.apache.openejb.maven</groupId>
		  <artifactId>tomee-maven-plugin</artifactId>
		  <version>1.0.1</version>
		  <configuration>
			<tomeeVersion>1.5.2</tomeeVersion>
			<tomeeClassifier>plus</tomeeClassifier>
		  </configuration>
		</plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

ส่งท้าย

แต่ก่อนเราชอบบ่นว่า EJB พัฒนายาก เดี๋ยวนี้ EJB ไม่ได้ยากเหมือนแต่ก่อนแล้วนะครับ ลองดูแล้วจะติดใจ

One thought on “พัฒนา Java EE 6 ด้วย Maven

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s