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

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

일단 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

http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-javase6-419409.html#jre-6u18-oth-JPR


막상 오라클 가서 찾으려고 하니 이전 마이너 버전을 찾기가 쉽지가 않다.

오라클 홈페이지에서 제공하고 있는데도 불구하고 말이다. 찾기 힘들어서 최신 버전만 올려두었나 싶었을 정도였다.



Leave a Comment


to Top