개발을 하면서 모델간 매핑을 많이 한다.
DTO, VO, Entity별로도 하고 DTO간 DTO 변환에도 사용한다.
개발자마다 각각 다양한 방식으로 이 부분에 대해 개발을 하는데 문제는 팀 내에서는 동일한 방식을 사용해야 한다.
팀 생산성상 중요하고, 코드리뷰에서 불필요하게 지적하는 시간을 줄일 수 있다.
중요한 점은 팀 내에서 협의하여 공통된 방식에 대해서 합의가 되어야 한다.
정해진 답은 없고, 프로젝트의 성격에 따라 다르겠지만 어느 정도 공통된 점들은 있다.

Model Object

시작하기에 앞서
모델 객체애 대해서 다시 살펴보면
DTO, VO, Entity, Domain Model로 나누어 볼 수 있다.

DTO

  • Data transfer object
  • 목적 : 데이터의 전달
  • 데이터의 전달을 위한 생성자와 getter, setter 로직만 들어가야 하며 기타 로직이 들어가서는 안됨

 

VO

  • Value Object
  • 목적 : 불변 객체로서 데이터 전달
  • 개발자들간 대화를 하다보면 VO에 대해서 특별한 정의를 없이 사용하며 DTO와 크게 다르지 않게 사용하는 경우가 있다.
    • 그러나 프로젝트 내에서 DTO와 VO를 특별한 의미없이 사용해서는 안된다. 나름대로의 목적을 정해야만 함
  • VO의 통상적으로 사용되는 의미는 불변(Immutable)의 의미
  • DDD에서 VO를 불변 객체로 소개

 

불변(Immutable) 객체

  • 한번 생성된 이후 수정되지 않는 의미
  • 데이터를 다룰 때, 종종 수정되어서는 안되는 데이터가 있는데 이를 개발단에서 중간에 수정되지 않게 막음
  • 동시성 프로그래밍(parallel programming)에서 멀티 스레드 처리시 발생하는 문제에서 벗어날 수 있음
  • 생성자 또는 빌더를 통해서만 값을 객체 생성 초기에 넣고, 그 이후로는 getter를 통해서 값을 갖고 오도록 처리

 

Entity & Domain Model

  • Etity는 ORM에서 DB Table와 매핑되는 모델 객체
  • Entity는 데이터 전달의 목적보다 DB Table과 객체를 매핑함으로서, 기존 JDBC API를 이용한 경우 데이터 정보만 전달하게 되면서 객체 지향적이지 않게 생기는 패러다임 불일치 문제를 해결하는 점이 중요
  • DDD를 할 경우에는 Entity를 도메인 모델로 사용한다. 이 경우 Entity에는 도메인 로직이 들어감
  • DDD 관점에서 볼 때, Domain Layer에 위치

 

매핑 개발

Service

여러 서비스에서 사용시 중복코드 발생
서비스 객체에 모델간 매핑 로직은 서비스 객체의 목적에 부합하지 않음

Model Object

  • 장점
    • 빠른 개발시 간편함
  • 단점
    • 서비스가 커지고, 모델간 다양한 매핑이 있을 경우 점점 모델 객체안에 메서드가 많아짐
    • 모델 객체에 모델간 매핑 로직은 모델 객체의 목적에 부합하지 않음
    • Entity안에 VO변환 로직을 넣고, VO안에 Entity 변환 로직을 넣게 된다면 (이러면 안되지만), 양방향 의존으로 인한 스파게티 코드 발생

Mapper

  • 모델간 매핑에 대한 책임
  • 역할 : 모델간 모델 매핑

mapper를 이용한 모델 객체를 사용하게 될 때, 다시 한번 결정을 해야 하는 것이 있다.
라이브러리들을 이용해서 모델간 매핑을 자동화를 할지, 아니면 직접 Mapper를 이용해서 모델간 매핑을 처리할지이다.

여러가지 라이브러리가 있는데 그 중에서 ModelMapper와 MapStruct에 대해 얘기해본다.

ModelMapper

  • 내부적으로 리플렉션을 사용. 그래서 사용을 하지 않는 것이 좋다.
  • 리플렉션으로 인한 성능 이슈 그리고 실제 동작시 발생하다보니 자칫 예상치 못한 결과가 발생할 수 있다.
  • 리플렉션을 쓰는 대표적인 것 중 하나로 Jackson ObjectMapper가 있는데, 이는 모델 변경이 아닌 모델의 포맷에 대한 변경이고 대안이 없기 때문에 사용한다.

MapStruct

  • 리플렉션 사용하지 않음
  • 컴파일시 생성
  • 레퍼런스
    • 국내는 적지만, 미국에서 점점 사용도가 높아지고 있음

 

MapStruct Example

MemberMapper.java

import org.mapstruct.Mapper;

@Mapper(componentModel = "spring")
public interface MemberMapper {

   MemberVO toVO(Member member);

}

 

Member.java

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Getter
@Setter
@EqualsAndHashCode(of = { "memberId" }, callSuper = false)
@Table(name = "member")
public class Member extends BaseEntity {

   @Id
   @Column
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long memberId;

   @Column
   private String memberName;

}

 

MemberVO.java

import lombok.Builder;
import lombok.Value;

import java.time.LocalDateTime;

@Builder
@Value
public class MemberVO {
   private Long memberId;
   private String memberName;
}

 

Kotlin에서 모델 매핑

  • Kotlin에서도 MapStruct를 쓰기도 함
  • 객체 생성 후에 기존 객체에 확장메서드(extenstion function)를 이용한 매퍼

Comments

  1. 이수민 2019.09.06 14:29 Permalink Modify/Delete Reply

    좋은 글 감사합니다~

    혹시 mapper 는 보통 어느 레이어에 두시나요?

    domain.model.member.Member
    domain.model.member.MemberDomainService
    application.member.dto.MemberDto
    application.member.MemberApplicationService

    domain.model.member.MemberMapper
    application.member.MemberMapper
    application.member.dto.MemberMapper
    application.mapper.MemberMapper
    mapper.member.MemberMapper

    Application Layer 에 위치하는게 가장 좋아보이기는 하는데,, 이런거는 정답도 없어서 더 고민되네요

    • 아틴 2019.09.06 15:19 신고 Permalink Modify/Delete

      Mapper는 특정 레이어에 종속적이라고 생각하지 않습니다. Mapper의 목적이 오브젝트와 오브젝트를 변환해주는 것이 목적이기 때문인데요.

      Domain Layer
      Application Layer
      Presentation Layer

      모델 오브젝트의 위치가 중요하다고 생각합니다.
      DTO1을 DTO2로 변경한다고 했을 때, 두 DTO가 모두 Presentation Layer로 같은 Layer에 있다고 하면 Mapper는 Presentation Layer에 있어야 한다고 보구요.

      DTO1은 Domain Layer에 있고
      DTO2는 Application Layer에 있다고 하면 Application Layer에 Mapper가 있어야 한다고 봅니다.

      단순히, 두 모델 오브젝트를 의존할 수 있는 Layer에 Mapper를 두는 것이 맞다고 생각하는 부분입니다.

      DTO1은 Domain Layer에 있고
      DTO2는 Application Layer에 있을 경우
      Mapper가 Domain Layer에 있으면 해당 Mapper는 DTO2를 참조할 수 없어서 매핑을 할 수가 없습니다. (레이어를 패키지로 분리했다면 의존할 수 있겠지만.)
      Application Layer는 Domain Layer를 의존하고 있지만 Domain Layer는 Application Layer를 의존하지 않아야 하기 때문입니다.

      domain.member.dto
      application.member.dto
      application.member.mapper

    • 이수민 2019.09.10 10:49 Permalink Modify/Delete

      모델 오브젝트의 위치에 따라 단순히 생각하면 되겠군요!

      감사합니다

  2. A.S.L 2019.09.09 21:20 신고 Permalink Modify/Delete Reply

    MapStruct 한글로 정리된 글 찾다보니 여기까지 왔네요.
    좋은글 감사해요~

Leave a Comment

코드리뷰를 하다보면 늘 반복적으로 나오는 내용이 있다.
기능상 문제가 되는 것은 아니지만 걸고 넘어갈만한 내용인데 매번 설명하기가 힘들어서 정리를 해본다.

오늘 코드리뷰를 하면서 나온 내용중에 하나가 아래와 같은 선언이다.

일단 LOGGER라는 네이밍이 걸렸지만 그 외에도 리뷰할만한 말이 있는데 설명하자니 이 간단한 한줄이 길어지게 되었다.


참고 소스 [1] - DefaultRedirectStrategy.java


참고 소스 [2] - DefaultSecurityFilterChain.java



1. 왜 private으로 하였는가?
해당 클래스를 다른 클래스가 상속받아 사용하지 않게 하는 경우라면 private으로 사용하는 것이 맞습니다.
상속을 통한 재사용을 고려한다면 protected로 선언할 수 있겠습니다.
[1]과 [2]의 차이인데 [1]에서는 상속을 처리하기 위해서 static을 사용하지 않고 protected final만을 사용해서 선언하였습니다. 선언시에도 상속한 클래스명을 받기 위해 생성자의 메서드를 호출하고 있습니다. 
[2]의 경우는 상속을 허용하지 않는 경우여서 private static final로 선언이 되어 있고 class도 final로 되어 있습니다.

2. 왜 static으로 하였는가?
static으로 선언하는 이유는 객체가 생성이 될 때마다 해당 객체를 매번 생성하지 않고 초기 클래스 로딩시 한번만 생성해서 사용을 하기 위함입니다.
이전의 자바 클래스 코딩 스타일은 static을 많이 사용하는 추세였다고 생각되고 저도 많이 사용했었ㅅ습니다.
그러나 Spring을 사용하게 되면서 객체를 굳이 싱글턴 형태로 디자인하지 않아도 객체를 싱글턴과 같이 한번만 생성해서 사용을 하게 되었습니다.
애플리케이션에서 해당 클래스의 생성 방식이나 사용 형태에 따라서 무조건적인 static을 선언해서 Perm 영역의 공간을 소비할 필요가 없게 되었습니다.
Spring 소스에서도 Logger 사용시 [1]과 같이 static으로 선언하지 않은 경우가 있고 [2]와 같이 static으로 선언하는 경우가 있습니다.


3. 왜 fianl로 하였는가?
로그를 찍는 Logger는 초기 생성된 이후에 변경될 필요가 없습니다.
특별한 경우가 아니라면 변경되는 경우는 거의 없다고 보입니다. 
final로 선언하지 않더라도 이 Logger에 대해 변경하는 경우는 거의 없겠지만 유지보수와 가독성을 위해 final로 선언하는 것이 좋습니다.


4. 왜 LOGGER라는 이름으로 하였는가?
LOGGER라는 이름으로 선언된 이유에 대해서 다른 소스에서도 그렇게 사용되는 것을 보아서 그랬다는 답변을 들은 적이 있다.
내 생각에는 JAVA에서 상수 선언시 이름을 대문자로 많이 쓴다. 통상 static final의 멤버 변수의 경우는 상수 선언시 많이 쓰게 되고 static final은 대문자라는 공식이라는 생각에 대문자로 선언한 분이 있지 않을까 한다.

하지만 static final로 선언한다고 무조건 상수는 아니며, static final로 선언한 객체는 당연히 소문자로 해줘야 된다.
Spring 소스에서도 Logger는 static final을 쓰더라도 소문자를 사용하고 있다.


Reference

[1] https://github.com/spring-projects/spring-security/blob/master/web/src/main/java/org/springframework/security/web/DefaultRedirectStrategy.java

[2] https://github.com/spring-projects/spring-security/blob/master/web/src/main/java/org/springframework/security/web/DefaultSecurityFilterChain.java


(글을 본 선배가 의견을 카톡으로 줘서 업데이트했습니다;ㅋ)


Leave a Comment

java에서 기본으로 제공해주는 MessageFormat을 이용하면 {0}, {1}, {2} 이런 값에 대해 변수를 대입해줄 수 있지만,
문제는 숫자로만 가능한다는 점이다.

숫자가 아닌 특정 템플릿 형태로 값을 주입하고 싶다면 common lang에서 제공해주는 StrSubstitutor을 이용하면 된다.
기본값은 "${name}"과 같은 형태이다. prefix가 "${"이고 suffix가 "}"이다.

이 외에 다른 형태로 값을 넣고 싶으면 메서드 호출시에 prefix와 suffix를 넣어주면 원하는 형태로 사용이 가능하다.


Test.java



Leave a Comment

Jackson에서 알지 못하는 프로퍼티가 있다면 파싱할 때 에러가 발생한다.

이 때, 이런 프로퍼티가 추가되어도 에러가 나지 않게 막는 설정은 다음과 같다.




test.xml




Test.java








Leave a Comment

클린 코드에 null을 리턴하지 말라는 얘기가 있다.

동감이다. null만 검사하다가 코드는 지저분하게 끝나고 만다.


Collections 클래스에 있는 비어있는 객체를 활용한다. list, map, set 종류별로 다 있다.

다만 static final이기 때문에 리턴받은 후에 추가를 하려고 하면 에러가 나기 때문에 쓰임새에 유의해야 한다.

java.util.Collections

  • static <T> Enumeration<T> emptyEnumeration()
  • static <T> Iterator<T> emptyIterator()
  • static <T> List<T> emptyList()
  • static <T> ListIterator<T> emptyListIterator()
  • static <K,V> Map<K,V> emptyMap()
  • static <T> Set<T> emptySet()


String 리턴의 경우 null을 어떻게 해야 할까 고민해 보았는데

common의 StringUtils.EMPTY에 static final로 공백 String이 들어가 있어서 사용해 볼 수 있다.

아쉽게도 spring의 StringUtils에는 EMPTY가 없었다.


org.apache.commons.lang.StringUtils

  • static String EMPTY




Leave a Comment

Could not fetch model of type 'EclipseProject' using Gradle distribution

Could not fetch model of type 'EclipseProject' using Gradle distribution " http://services.gradle.org/distributions/gradle-1.10-bin.zip"

나는 현재 신규 프로젝트를 Gradle로 빌드하고 있다.

이클립스는 STS를 사용중인데, 다른 프로젝트를 임포트하고 신규 프로젝트를 생성하는 과정에서 JBoss가 필요하여 마켓에서 JBoss 플러그인을 설치하였다.


그런데 이전 프로젝트의 Gradle 빌드를 실행하려고 하니 위와 같은 에러가 발생하였다.


자세한 에러도 안 나오고, 네이버는 당연히 안 나오고 Google에서 검색하니 그나마 비슷한 사항이 나오기는 하나 해결책은 나오지 않는다. 맨붕이 오고 어떻게 해결할지는 모르겠고 자세한 로그도 없고

정말 STS 재설치해서 할까 고민했다.


고민 중에 아무래도 이클립스 플러그인 설치 후에 발생했다는 점과 오류 내용이 이클립스에서 Gradle 툴과 연관이 있지 않을까 싶었다.


그래서 마켓에서 내가 사용중이던 "Gradle IDE Pack"을 업데이트 해주었다.


다행히 문제 해결!!!!!!


같은 문제를 겪는 사람이 있다면 도움이 되길 바란다.

휴우..





Leave a Comment

배포파일에 대하여 버전을 확인할 수 있게 해달라는 요청이 있었다.

파일명 뒤에 버전 붙이는 시덥잖은 방법으로는 한계가 있다.

하지만 java의 배포파일에 버전을 넣는 방법은 없다. 내가 모르는 것인가?

그리하여 JAR나 WAR에 공통적으로 들어가는 MANIFEST.MF 파일에 버전을 넣기로 했다.


해당 프로젝트는 Ant로 빌드하기 때문에 ant에 설정값을 추가했다.


<manifest file="MANIFEST.MF">

<attribute name="Manifest-Version" value="4.2013.2" />

</manifest>

<war ... manifest="MANIFEST.MF">

<jar ... manifest="MANIFEST.MF">


JAR나 WAR나 마찬가지이다.


그리고 저 파일을 확인할 수 있게 하기 위하여 bat파일과 sh파일을 만들었다.


check_version.bat

@echo off

if "%1" == "" goto HELP

jar xf %1 META-INF/MANIFEST.MF

TYPE META-INF\MANIFEST.MF

DEL META-INF\MANIFEST.MF

RMDIR META-INF\

goto QUIT


:HELP

echo ERROR: Missing JAR OR WAR file name

echo Usage: check_version.sh $war or jar filename

:QUIT



check_version.sh

#!/bin/ksh


if [ "$1" == "" ]; then

        echo "ERROR: Missing JAR OR WAR file name"

        echo "Usage: check_version.sh $war or jar filename"

        exit

fi


jar xf $1 META-INF/MANIFEST.MF

cat META-INF/MANIFEST.MF

rm META-INF/MANIFEST.MF

rm -r META-INF/




Reference

[1] Ant로 Manifest 설정 ( http://blog.naver.com/PostView.nhn?blogId=taekiblue&logNo=150033090682 )

Leave a Comment

혹시 Java로 TCP서버를 구축하고 계신가요?

JAVA NIO를 공부하면서 서버 설계에 고민하고 계신가요?


서버 코어 설계 및 개발에 투자할 많은 시간 있다면? 그리고 안정성을 높이고 성능을 높이 끌어낼 자신과 시간이 있다면 직접 개발하세요. 하지만 그렇지 않다면 검증된 Java Network Framework인 Netty나 MINA를 사용해보세요.


이렇게 쓰니 제가 홍보하는 사람 같군요.

하지만 저의 경험입니다. 서버 코어 부분을 설계하고 개발하다보면 프로젝트에서 너무 많은 시간을 할애하게 되어버립니다. 그 후에 안정성이나 성능에 대해서도 고민이 되고 제가 나가면서 다른 사람에게 인수인계 할 때의 유지보수도 문제가 되어 버립니다.


그런 면에서 Netty나 MINA를 추천합니다.

사실 저도 어떻게 더 좋은지 모르겠습니다. 파운더이신 이희승씨가 Netty 사용을 권고하고 성능면에서도 Netty가 훌륭하다고 나왔지만, 역사가 길고 사용자가 많고 MINA를 사용해야 할지요. (어떤 분은 Netty 쓰지 말고 MINA를 써야 성능이 좋다고 하는 분도 있습니다.)


저는 netty를 사용합니다만 둘 다 우수한 프레임워크이니 골라서 사용해보시길 바랍니다.

두 개 모두 한국인 이희승씨가 개발하셨습니다. (아래 인터뷰를 읽어보면 이해가 잘 가실겁니다.)




Netty (JBoss)

자바 네트워크 어플리케이션 프레임워크

  • 이벤트 기반이며 비동기 방식
  • Interceptor Chain 패턴 방식
  • Old, New I/O 지원
  • NIO구현 벤더별 최적화
  • 과부하 및 Dos 방어 매커니즘 포함
  • 제한된 환경 지원(Android, Applet, WebStart)
  • 다양한 컨터이너 지원(JbossMc, OSGi, Guice, Spring)



1. 네티 공식 사이트

( http://netty.io/ )


2. netty  한국인 사용자 그룹

( http://groups.google.co.kr/group/netty-ko?hl=ko )


3. Netty, MINA 개발자 이희승님 인터뷰

http://www.bloter.net/archives/11472 )


4. 한국 미나 사용자께 드리는 네티로의 전환 권고

http://gleamynode.net/articles/2223/ )


6. Performance Comparison between NIO Frameworks

http://gleamynode.net/articles/2232/ )


7. Netty 사용에 관한 몇 가지 TIP

http://blog.pointbre.com/351/netty-%EC%82%AC%EC%9A%A9%EC%97%90-%EA%B4%80%ED%95%9C-%EB%AA%87%EA%B0%80%EC%A7%80-tip.html )


8. Netty User Guide

http://docs.jboss.org/netty/3.2/guide/html_single/ )


9. Netty Zero copy

http://clotho95.blog.me/140117229649 )


10. DEV 2012 Netty Internal Session

http://deview.kr/2012/xe/?mid=track&document_srl=379 )


11. Netty Tutorial

http://seeallhearall.blogspot.de/2012/05/netty-tutorial-part-1-introduction-to.html )






Apache MINA

MINA는 네트워크 어플리케이션 프로그래밍에 대한 지식 없이도 고성능 네트워크 어플리케이션을

쉽게 작성할 수 있도록 돕는 프레임워크


MINA 의 특징

  • TCP, UDP 트랜스포트 타입을 모두 지원
  • ByteBuffer 단위의 low-level I/O layer 와 Message object 단위의 high-level protocol layer를 모두 지원
  • Servlet filter 와 유사한 이벤트 필터링 기능을 제공하여 실시간 퍼포먼스 모니터링 및 이벤트 transformation (e.g. SSL 지원, 권한 검사, 클라이언트 블랙리스팅...) 가능
  • 같은 VM 내에 있는 MINA 어플리케이션 간의 통신시 in-VM pipe 를 제공하여 전문의 encode/decode 없이 바로 전달하여 성능을 극대화할 수 있음.


1. MINA
( http://mina.apache.org/ )


2. Javadoc

( http://mina.apache.org/mina-project/apidocs/index.html )


3. 특징

( http://mina.apache.org/mina-project/features.html )


4. Quick start

( http://mina.apache.org/mina-project/quick-start-guide.html )


5. Apache MINA Group

( http://mina.apache.org/mina-project/testimonials.html )


6. Download

( http://mina.apache.org/mina-project/downloads.html )


7. MINA 를 소개합니다. (차세대 Netty) by 이희승 (2004)

( http://www.javaservice.co.kr/~java/bbs/read.cgi?b=news&c=r_p&m=resource&n=1104313609&p=13&s=t )


8. MINA 강좌

http://mckdh.net/130 )






Netty vs MINA

1. MINA vs Netty

http://ellieya.tistory.com/23 )


2. Netty vs Apache MINA stackoverflow

( http://stackoverflow.com/questions/1637752/netty-vs-apache-mina )







Leave a Comment

1. JBoss 설치

다양한 WAS중에서 나는 JBoss를 좋아한다. 회사에서는 주로 5버전을 쓰고 있었는데 최신 버전인 7 버전을 써보았다. 제일 좋은 점은 WAS 구동속도가 엄청나게 향상되었다.


Download URL : http://www.jboss.org/projects


* Admin 계정 생성

jboss-as-7.1.1.Final\bin>add-user.bat


* Server 시작

jboss-as-7.1.1.Final\bin>standalone.bat

$JBOSS_HOME/bin/standalone.sh


2. JBoss 환경변수 설정

linux) export JBOSS_HOME=/home/atin84/work/jboss-as-7.1.1.Final

win) 환경변수 JBOSS_HOME 추가


3. JBoss Admin 생성

JBoss 관리자 창에 접속하거나 Maven과 연동하기 위해서는 관리자 계정을 생성해주어야 한다.

$JBOSS_HOME/bin/add-user.sh

 What type of user do you wish to add?
 a) Management User (mgmt-users.properties)
 b) Application User (application-users.properties)
(a): a

Enter the details of the new user to add.
Realm (ManagementRealm) :
Username : atin84
Password :
Re-enter Password :
About to add user 'rocksea' for realm 'ManagementRealm'
Is this correct yes/no? yes
Added user 'rocksea' to file '$JBOSS_HOME/standalone/configuration/mgmt-users.properties'
Added user 'rocksea' to file '$JBOSS_HOME/domain/configuration/mgmt-users.properties'




4. JBoss Eclipse 플러그인

이클립스에서 기본 지원하는 JBoss 버전은 5에서 멈춰있다. 플러그인을 설치하자.

이클립스 상단메뉴의 Help>Install New Softwares


URL : http://download.jboss.org/jbosstools/updates/development/indigo/


JBoss Tool을 선택해서 설치하면 된다.


5. Maven 개발 환경시 배포

pom.xml에 다음과 같이 설정해준다. 자신의 pom.xml에 맞춰서 추가해주자.

<dependency>
        <groupId>maven</groupId>
        <artifactId>maven-jboss-plugin</artifactId>
        <version>1.5</version>
        <type>plugin</type>
</dependency>

<build>
     <plugins>
             <plugin>
                     <groupId>org.jboss.as.plugins</groupId>
                     <artifactId>jboss-as-maven-plugin</artifactId>
                     <version>7.3.Final</version>
             </plugin>
     </plugins>
</build> 


JBoss를 구동시켜준다. 일반적으로는 war를 배포하고 was를 재기동시켜줘야 하지만 이 방법은 was의 재기동 없이 배포를 해준다.


실행은 다음과 같이 해준다.

 $ mvn jboss-as:deploy


이클립스 환경에서는 실행 goal을 다음과 같이 해준다.

mvn jboss-as:deploy


그리고 웹 페이지에 접속해서 결과를 확인한다.



Reference

[1] JBoss 설치 (http://blog.whitelife.co.kr/entry/jBoss7-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0)

[2] JBoss 플러그인 설치 (http://jangnandev.blogspot.kr/2012/01/eclipse-indigo-jbossas7.html)

[3] Maven + JBoss 설치 및 배포 (http://rocksea.tistory.com/146)



Leave a Comment

Maven & JBoss 개발 환경 구축

 1. Maven 설치

 2. Eclipse Maven Plug-in 설치

 3. JBoss 설치

 4. JBoss Eclipse Plug-in 설치

 5. 


1. Maven 다운로드

URL : http://maven.apache.org/download.cgi

환경변수 설정

MAVEN_HOME=C:\maven\apache-maven-3.0.3 (자신이 설치한 위치로)

path=%MAVEN_HOME%\bin


2. 이클립스 Maven 플러그인

이클립스 상단메뉴의 Help>Install New Softwares


2.1. m2e

http://m2eclipse.sonatype.org/sites/m2e


2.2. m2eclipse Extras

http://m2eclipse.sonatype.org/sites/m2e-extras


3. Maven 프로젝트 생성

콘솔에서 명령어를 쳐서 생성하는 방법이 있지만 별로 좋지 않다. 이클립스 Maven 프로젝트를 통해 생성하자.

신규 프로젝트 생성을 하다보면 메이븐 프로젝트 형태를 지정하는 것이 있는데 나는 jar 타입 프로젝트는 maven-archetype-quick-start로 하고 war타입 프로젝트는 maven-archetype-webapp 형태로 해서 생성을 하였다.


주의할 점이 있는데 프로젝트가 생성된 이후에 디렉토리 형태를 자기 입맛에 맞춰 변경하면 나중에 대참사가 발생한다. 나는 내가 개발하던 디렉토리 구조로 하고 싶어서 이것저것 변경하였는데 pom.xml에서 바꾼 디렉토리 구조를 하나하나 지정해주어야 하여만 하는것이었다. 그렇지 않으면 제대로 maven 실행을 할 수가 없다. 그런데 이 자기 입맛에 맞춰 pom.xml에 상세하게 지정해주는 것은 Maven 초보에게는 힘든 일이다. 덕분에 많이 배웠지만 가능하면 처음 생성된 디렉토리 구조대로 하는 것이 정신건강에 좋을 것이다. 또한 이 기본 디렉토리 구조를 많은 오픈소스에서 그대로 사용하고 있다.


4. Maven 빌드

내가 Maven을 사용하면서 가장 당황한 점은 빌드이다. 내가 Maven을 사용하면서 가장 큰 착각을 한 것은 Maven이 단순히 라이브러리를 관리해주는 툴 정도로 생각했던 점이다. 그러나 Maven의 기능은 그 이상으로 방대했다.

우선 Maven을 사용하면 ant를 사용할 필요가 없다. Maven에는 빌드, 단위테스트, 배포 등의 모든 기능이 포함되어 있다. 그리고 ant처럼 일일히 스크립트를 만들 필요도 없다. 정형화되어있는 goal을 실행함으로서 모든 작업을 한번에 수행할 수 있다.


Maven에서 가장 중요한 것은 pom.xml이다. 여기에 모든 Maven 설정이 들어가 있다.

만약 pom.xml을 클릭했을 때 xml만 나온다면 xml에 오른쪽 버튼을 누르고 open with에 Maven POM Editor을 선택하면 좀 더 편리하게 pom.xml을 관리할 수 있다.


이번 포스팅은 여기까지만 하고 다음에 goal, 그리고 내가 실수했던 빌드 설정들에 대해서 포스팅하도록 하겠다.



Reference

[1] Maven 설치1 (http://blog.whitelife.co.kr/entry/jBoss7-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0

http://blog.naver.com/PostView.nhn?blogId=seban21&logNo=70110678014)

[2] Maven 설치2 (http://blog.naver.com/PostView.nhn?blogId=seban21&logNo=70110678014)

[3] Maven 사용법 (http://maven.apache.org/plugins/maven-war-plugin/usage.html)


Leave a Comment


to Top