제9장 EJB 사용하기

본 장에서는 예제를 이용해서 Stateless Session Bean과 Java Persistence API를 이용하여 Entity를 개발하고 deploy하는 과정에 대해 설명한다.

9.1. Session Bean 예제

Session Bean은 기본적으로 Business Interface와 Bean Class로 구성된다.

9.1.1. 예제

EJB 예제

다음의 예제 코드는 helloejb를 출력하는 Business 메소드를 가진 간단한 Stateless Session Bean 예제이다.

  • Business Interface

    [예 9.1] Stateless Session Bean 예제 : <Hello.java>

    package helloejb;
    
    import javax.ejb.Remote;
    
    @Remote
    public interface Hello {
        String sayHello();
    }


  • Bean Class

    [예 9.2] Stateless Session Bean 예제 : <HelloBean.java>

    package helloejb;
    
    import javax.ejb.Stateless;
    
    @Stateless(mappedName="helloejb.Hello")
    public class HelloBean implements Hello {
    
        public String sayHello() {
            return "Hello EJB!";
        }
    }


예제 코드는 다음의 디렉터리에서 찾아볼 수 있다.

JEUS_HOME/samples/getting_started/helloejb/helloejb-ejb/src/java/helloejb

서블릿 클라이언트 예제

helloejb를 호출하는 서블릿 클라이언트를 다음과 같이 구현한다.

[예 9.3] 서블릿 클라이언트 예제 : <HelloClient.java>

package helloejb;

import java.io.*;
import javax.ejb.EJB;

import javax.servlet.*;
import javax.servlet.http.*;

public class HelloClient extends HttpServlet {
    @EJB(mappedName="helloejb.Hello")
    private Hello hello;

    protected void processRequest(HttpServletRequest request,
        HttpServletResponse response)
    throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        try {
            // Call session bean business method.
            String msg = hello.sayHello();

            response.setContentType("text/html");
            out.println("<html>");
            out.println("<head>");
            out.println("<title>HelloClient</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<center><h1>" + msg + "</h1></center>");
            out.println("</body>");
            out.println("</html>");
            out.close();
        } catch(Exception ex){
            response.setContentType("text/plain");
            ex.printStackTrace(out);
        }
    }

    protected void doGet(HttpServletRequest request,
        HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }

    protected void doPost(HttpServletRequest request,
        HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }
}


예제 코드는 다음 위치의 디렉터리에서 찾아볼 수 있다.

JEUS_HOME/samples/getting_started/helloejb/helloejb-war/src/java/helloejb

9.1.2. 컴파일

작성된 예제는 Ant를 이용하여 다음과 같이 빌드할 수 있다.

%JEUS_HOME%/samples/getting_started/helloejb>jant build

빌드가 정상적으로 완료되면 %JEUS_HOME%/samples/getting_started/helloejb/dist/helloejb.ear 애플리케이션 EAR 파일이 생성된다.

9.1.3. Deploy

패키징한 EJB 애플리케이션을 WebAdmin과 콘솔 툴로 deploy할 수 있다.

WebAdmin 사용

WebAdmin을 사용하여 deploy하는 과정은 다음과 같다.

  1. WebAdmin 메인 화면에서 Master Server를 선택하면 JEUS Master 화면으로 이동한다. 상단 메뉴에서 [애플리케이션]을 선택한 후 애플리케이션 목록 화면에서 [설치] 버튼을 클릭한다.

    [그림 9.1] Deployed Application 화면

    figure webadmin deploy1

  2. 설치 화면'Id' 항목에 사용할 ID 값을 입력한다. 'Path' 항목의 [선택] 버튼을 클릭해서 생성된 애플리케이션을 선택한 뒤 [설치] 버튼을 클릭한다.

    [그림 9.2] Deployed Application 화면 - EJB 모듈 install 대상선택

    figure webadmin deploy6

  3. 설치 후 애플리케이션 목록 화면에서 MASTER에 install된 애플리케이션을 조회할 수 있다. MS에 배포하기 위해 목록에서 애플리케이션을 선택한 후 [배포] 버튼을 클릭한다.

    [그림 9.3] Deployed Application 화면 - EJB 모듈 install 결과

    figure webadmin deploy7

  4. 배포 화면'Target Server'에서 deploy할 서버를 선택하고 [배포] 버튼을 클릭한다. MASTER를 선택할 수도 있지만 MS에 deploy하여 애플리케이션을 서비스하는 것을 권장한다.

    [그림 9.4] Deployed Application 화면 - 모듈 deploy

    figure webadmin deploy12

  5. 성공적으로 deploy하면 다음과 애플리케이션의 상태가 RUNNING인 것을 확인할 수 있다.

    [그림 9.5] Deployed Application 화면 - EJB 모듈 deploy 결과

    figure webadmin deploy9

콘솔 툴 사용

콘솔 툴을 사용하여 deploy하는 과정은 다음과 같다.

  1. 위에서 작성한 helloejb.ear 파일을 임의의 경로에 위치시킨다.

  2. jeusadmin으로 JEUS에 접속한다.

    jeusadmin –u jeus –p  <password>
  3. 다음과 같이 실행하여 애플리케이션을 MASTER에 install한다.

    [MASTER]domain1.adminServer>install-application -id helloejb C:\TmaxSoft\JEUS\samples\getting_started\helloejb\dist\helloejb.ear
    Successfully installed application[helloejb].
  4. 다음과 같이 실행하여 애플리케이션을 MS(server1)에 deploy한다.

    [MASTER]domain1.adminServer>deploy helloejb -servers server1
    Succeeded to deploy the application : helloejb

9.1.4. 실행 및 결과

deploy가 완료되면 작성된 화면를 실행해서 결과를 확인한다.

다음은 웹 클라이언트를 실행하는 과정에 대한 설명이다.

  1. 웹 브라우저를 통해 다음 URL로 접속하면 HelloEJB 웹 클라이언트로 접속할 수 있다.

    http://localhost:8088/helloejb/

    [그림 9.6] HelloEJB 클라이언트 화면

    figure webmanager jarmodule5

  2. 화면의 [Invoke HelloEJB Client] 버튼을 클릭하면 EJB를 호출하는 HelloClient 서블릿을 실행시키며 다음과 같은 결과를 확인할 수 있다.

    [그림 9.7] HelloEJB 서블릿 클라이언트 수행 결과

    figure webmanager jarmodule6

9.2. Java Persistence API 예제

본 절에서는 Java Persistence API를 통해 Entity를 작성하고 컴파일하여 deploy하는 과정을 설명한다.

9.2.1. 예제

EJB 예제

예제는 Product Entity와 이를 다루는 EJB인 ProductManager Session Bean으로 구성되어 있다.

  • Entity

    [예 9.4] Java Persistence API 예제 : <Product.java>

    package hellojpa;
    
    import java.io.Serializable;
    import javax.persistence.Entity;
    import javax.persistence.Id;
    import javax.persistence.NamedQuery;
    
    @Entity
    @NamedQuery(name="findAllProducts", query="SELECT p FROM Product p")
    public class Product implements Serializable {
        @Id
        private String productId;
        private double price;
        private String description;
    
        public Product() {
        }
    
        public Product(String productId, double price,
            String description){
            this.productId = productId;
            this.price = price;
            this.description = description;
        }
    
        public String getProductId() {
            return productId;
        }
    
        public void setProductId(String id) {
            this.productId = id;
        }
    
        public double getPrice() {
            return price;
        }
    
        public void setPrice(double price) {
            this.price = price;
        }
    
        public String getDescription() {
            return description;
        }
    
        public void setDescription(String description) {
            this.description = description;
        }
    
        public String toString() {
            return "Product[productId=" + productId + ", price=" +
                price + ", description=" + description + "]";
        }
    }


  • Business Interface

    [예 9.5] Java Persistence API 예제 : <ProductManager.java>

    package hellojpa;
    
    import java.util.Collection;
    import javax.ejb.Local;
    
    @Local
    public interface ProductManager {
        Product createProduct(String productId, double price, String desc);
    
        Product getProduct(String productId);
    
        Collection findAllProducts();
    
        Collection findProductsByDescription(String desc);
    
        Collection findProductsInRange(double low, double high);
    
        void updateProduct(Product product);
    
        void removeProduct(Product product);
    
        void removeAllProducts();
    }


  • Bean Class

    [예 9.6] Java Persistence API 예제 : <ProductManagerBean.java>

    package hellojpa;
    
    import java.util.Collection;
    import javax.ejb.Stateless;
    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;
    import javax.persistence.Query;
    
    @Stateless(mappedName="hellojpa.ProductManager")
    public class ProductManagerBean implements ProductManager {
        @PersistenceContext
        private EntityManager em;
    
        public ProductManagerBean() {
        }
    
        public Product createProduct(String productId, double price, String desc){
            Product product = new Product(productId, price, desc);
            em.persist(product);
            return product;
        }
    
        public Product getProduct(String productId){
            return (Product)em.find(Product.class, productId);
        }
    
        public Collection findAllProducts() {
            return em.createNamedQuery("findAllProducts").getResultList();
        }
    
        public Collection findProductsByDescription(String desc){
            Query query = em.createQuery("SELECT p FROM Product p WHERE
                p.description=:desc");
            query.setParameter("desc", desc);
            return query.getResultList();
        }
    
        public Collection findProductsInRange(double low, double high){
            Query query = em.createQuery("SELECT p FROM Product p WHERE
                p.price between :low and :high");
            query.setParameter("low", low).setParameter("high", high);
            return query.getResultList();
        }
    
        public void updateProduct(Product product){
            Product managed = em.merge(product);
            em.flush();
        }
    
        public void removeProduct(Product product){
            Product managed = em.merge(product);
            em.remove(managed);
        }
    
        public void removeAllProducts(){
            em.createQuery("DELETE FROM Product p").executeUpdate();
        }
    }


예제 코드는 다음의 디렉터리에서 찾아볼 수 있다.

JEUS_HOME/samples/getting_started/hellojpa/hellojpa-ejb/src/java/hellojpa

서블릿 클라이언트 예제

ProductManager EJB를 사용하여 데이터베이스에 데이터를 저장하고 데이터를 다루는 서블릿 클라이언트를 다음과 같이 구현한다.

[예 9.7] 서블릿 클라이언트 예제 : <ProductManagerClient.java>

package hellojpa;

import java.io.*;
import java.util.Collection;
import javax.ejb.EJB;

import javax.servlet.*;
import javax.servlet.http.*;

public class ProductManagerClient extends HttpServlet {
    @EJB
    private ProductManager productManager;

    protected void processRequest(HttpServletRequest request,
        HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/plain");
        PrintWriter out = response.getWriter();
        out.println("SERVLET CLIENT CONSOLE OUTPUT:\n");

        productManager.removeAllProducts();
        out.println("Cleaned up existing products.\n");

        out.println("Creating products...");
        Product p1 = productManager.createProduct("1", 10.00, "Ceramic Dog");
        Product p2 = productManager.createProduct("2", 13.00, "Wooden Duck");
        Product p3 = productManager.createProduct("3", 19.00, "Ivory Cat");
        Product p4 = productManager.createProduct("4", 33.00, "Ivory Cat");
        Product p5 = productManager.createProduct("5", 22.00, "Chrome Fish");

        Collection products;

        out.println("Created products:");
        products = productManager.findAllProducts();
        for(Object product : products){
             out.println(product);
        }
        out.println();

        out.println("Find product with productId 1:");
        Product pp1 = productManager.getProduct("1");
        out.println("Found = " + pp1.getDescription() + " $" + pp1.getPrice());

        out.println("Update the price of this product to 12.00");
        pp1.setPrice(12.00);
        productManager.updateProduct(pp1);

        Product pp2 = productManager.getProduct("1");
        out.println("Product " + pp2.getDescription() + " is now $" + pp2.getPrice());
        out.println();

        out.println("Find products with description:");
        products = productManager.findProductsByDescription("Ivory Cat");
        for(Object product : products){
            out.println(product);
        }
        out.println();

        out.println("Find products with price range between 10.00 and 20.00");
        products = productManager.findProductsInRange(10.00, 20.00);
        for(Object product : products){
            out.println(product);
        }
        out.println();

        out.println("Removed all products.");
        productManager.removeProduct(p1);
        productManager.removeProduct(p2);
        productManager.removeProduct(p3);
        productManager.removeProduct(p4);
        productManager.removeProduct(p5);

        out.close();
    }

    protected void doGet(HttpServletRequest request,
        HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }

    protected void doPost(HttpServletRequest request,
        HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }
}


예제코드는 다음의 디렉터리에서 찾아볼 수 있다.

JEUS_HOME/samples/getting_started/hellojpa/hellojpa-war/src/java/hellojpa

9.2.2. 컴파일

jant를 이용하여 예제 코드를 다음과 같이 빌드할 수 있다. 빌드와 데이터베이스 설정이 완료되었다면 패키징된 모듈을 deploy할 준비가 완료되었다.

  1. 예제가 작성된 경로에서 다음과 같이 ant build 명령어를 실행한다.

    C:\TmaxSoft\JEUS\samples\getting_started\hellojpa>jant build
  2. 빌드가 정상적으로 완료되면 dist\hellojpa.ear 애플리케이션 EAR 파일이 생성된다.

    이번 예제는 데이터베이스를 필요로 하므로 Derby를 시작시키도록 한다. 또한 데이터베이스가 jdbc/sample 데이터소스로 설정되어 있어야 한다. 자세한 내용은 “제7장 시스템 설정”을 참고한다.

    Derby가 시작되었다면 다음과 같이 데이터베이스 테이블을 생성한다. 본 예제에서는 "sample"이라는 데이터베이스를 사용할 것이다.

    CREATE TABLE PRODUCT (PRODUCTID VARCHAR(255) NOT NULL, PRICE FLOAT,
        DESCRIPTION VARCHAR(255), PRIMARY KEY (PRODUCTID));
  3. 다음과 같이 ant setup 명령어를 실행해서 데이터베이스 테이블을 생성한다.

    C:\TmaxSoft\JEUS\samples\getting_started\hellojpa>jant setup 

9.2.3. Deploy

패키징한 EJB 애플리케이션을 WebAdmin과 콘솔 툴로 deploy할 수 있다.

WebAdmin 사용

다음 과정에 따라 패키징된 모듈을 WebAdmin을 사용하여 deploy한다.

  1. WebAdmin 메인 화면에서 Master Server를 선택하면 JEUS Master 화면으로 이동한다. 상단 메뉴에서 [애플리케이션]을 선택한 후 애플리케이션 목록 화면에서 [설치] 버튼을 클릭한다.

    [그림 9.8] Deployed Application 화면

    figure webadmin deploy1

  2. 설치 화면에서 'Id' 항목에 사용할 ID 값을 입력한다. 'Path' 항목의 [선택] 버튼을 클릭해서 생성된 애플리케이션을 선택한 뒤 [설치] 버튼을 클릭한다. 생성된 애플리케이션은 'JEUS_HOME/samples/getting_started/hellojpa/dist'에 저장된다.

    [그림 9.9] Deployed Application 화면 - JPA 모듈 install 대상선택

    figure webadmin deploy10

  3. 설치 후 애플리케이션 목록 화면에서 MASTER에 설치된 애플리케이션을 조회할 수 있다. 목록에서 MS에 배포할 애플리케이션을 선택한 후 [배포] 버튼을 클릭한다.

    [그림 9.10] Deployed Application 화면 - JPA 모듈 install 결과

    figure webadmin deploy11

  4. 애플리케이션 화면에서 '타겟 추가 ' 항목에서 배포할 서버를 선택하고 [확인] 버튼을 클릭한다. MASTER를 선택할 수도 있지만 MS에 배포하여 애플리케이션을 서비스하는 것을 권장한다.

    [그림 9.11] Deployed Application 화면 - JPA 모듈 deploy 결과(1)

    figure webadmin deploy14

  5. 성공적으로 deploy하면 다음과 같이 애플리케이션의 State가 'RUNNING'으로 출력된 것을 확인할 수 있다.

    [그림 9.12] Deployed Application 화면 - JPA 모듈 deploy 결과(2)

    figure webadmin deploy13

참고

“7.4. 데이터소스 추가”에서 데이터소스 설정 관련 부분에서 설명했지만, 데이터소스 설정에서 패스워드나 IP 주소가 정확하지 않을 경우에 배포는 실패한다.

콘솔 툴 사용

콘솔 툴을 사용하여 deploy하는 방법은 다음과 같다.

  1. jeusadmin으로 JEUS에 접속한다.

    jeusadmin –u jeus –p <password>
  2. 애플리케이션을 MASTER에 install한다.

    [MASTER]domain1.adminServer>install-application -id hellojpa C:\TmaxSoft\JEUS\samples\getting_started\hellojpa\dist\hellojpa.ear
    Successfully installed application[hellojpa].
  3. 애플리케이션을 MS(server1)에 deploy한다.

    [MASTER]domain1.adminServer>deploy hellojpa -servers server1
    Succeeded to deploy the application : hellojpa
  4. 모듈이 정상적으로 deploy되었는지 확인한다.

9.2.4. 실행 및 결과

배포가 완료되면 다음의 과정으로 작성된 화면을 실행해서 결과를 확인한다.

  1. 웹 브라우저를 통해 다음 URL로 접속하면 HelloJPA 웹 클라이언트로 접속할 수 있다.

    http://localhost:8088/hellojpa/

    [그림 9.13] HelloJPA 클라이언트 화면

    figure webmanager jpamodule5

  2. 화면의 [Invoke ProductManager Client] 버튼을 클릭하면 EJB에 요청을 내리는 서블릿 클라이언트를 수행하고 다음과 같이 결과가 표시된다.

    [그림 9.14] HelloJPA 서블릿 클라이언트 수행 결과

    figure image080