" I guess you download the package and unzip or just put it into Eclipse's directory, without using the Software Updates tool in Help menu in Eclipse." 라고 하는군요

1. Delete the site.xml file in your Eclipse directory.

와 같이 하면 됩니다 ^^
개발/자바 | Posted by 은우 아빠 2009. 1. 16. 16:43

[펌]log4j 설정법


=============================================

본문서는 자유롭게 배포/복사 할수 있지만

이문서의 저자에 대한 언급을 삭제하시면 안됩니다

저자 : GoodBug (unicorn@jakartaproject.com)

최초 : http://www.jakartaproject.com 

=============================================


LOG4J

I. 들어가면서.. 그리고 log4j


log4j는 자바 어플리케이션에서 빠르고 효과적으로 로깅 할 수 있도록 도와주는 오픈 소스 프로젝트입니다.


로깅(logging)은 코드의 가독성을 떨어뜨리는 단점이 있지만 애플리케이션에 문제가 있을 때 개발자가 자세한 상황을 파악할 수 있도록 해 주며 테스팅시 빠질 수 없는 요소입니다.


아마도 여러분들은 여러 어플리케이션이 추가되면서 각 개발자들만의 독특한 로깅방식이 서로 썩이고 얽혀서 화면에 나타나는것을 많이 봤을겁니다 -_-;
즉 로깅방법을 통일할 필요가 있는것이죠. 모든 개발자가 특정 포맷에 맞추어서 로깅 한다면 한결 로깅하기도 편하겠지요


오픈 소스 프로젝트인 Log4j는 개발자들이 매우 손쉽고 다양한 형태로 로깅을 할 수 있도록 도와줍니다. 성능또한 우수해 더이상 System.out.println을 사용할 필요가 없습니다.



II. 다운로드


다운로드 http://logging.apache.org/log4j/docs/download.html

매뉴얼 http://logging.apache.org/log4j/docs/documentation.html

API spec http://logging.apache.org/log4j/docs/api/index.html



III. LOG4J 구조


일단 log4j를 잘 모르지만 그 구조만 살짝 살펴보고 넘어갑시다

log4j는 크게 3가지 요소로 구성되며 그 구조는 다음과 같습니다

① Logger(Category) : 로깅 메세지를 Appender에 전달합니다.

② Appender : 전달된 로깅 메세지를 파일에다 기록할 것인지, 콘솔에 출력할 것인지

                   아니면 DB에 저장할 것인지 매개체 역활을 합니다.

③ Layout : Appender가 어디에 출력할 것인지 결정했다면 어떤 형식으로 출력할 것이지

                출력 layout을 결졍합니다.

쉽죠?



IV. LOG4J 로깅 레벨


log4j는 다양한 로깅레벨을 지원합니다.


① FATAL : 가장 크리티컬한 에러가 일어 났을 때 사용합니다.

② ERROR : 일반 에러가 일어 났을 때 사용합니다.

③ WARN : 에러는 아니지만 주의할 필요가 있을 때 사용합니다.

④ INFO : 일반 정보를 나타낼 때 사용합니다.

⑤ DEBUG : 일반 정보를 상세히 나타낼 때 사용합니다.


만약 로깅 레벨을 WARN 으로 설정하였다면 그 이상 레벨만 로깅하게 됩니다.

즉 WARN, ERROR, FATAL 의 로깅이 됩니다.



V. 샘플코드 1


jsp에서 사용하는 예제가 없어 만들어 봤습니다.


test.jsp


<%@ page contentType="text/html;charset=MS949"
 import="org.apache.log4j.Logger" %>

<%!
 static Logger logger = Logger.getLogger("test.jsp");
%>

<%
logger.fatal("fatal!!");

logger.fatal("fatal2!!", new NullPointerException("널입니다요"));

logger.error("error!", new NumberFormatException());

logger.error("error!2");

logger.warn("warn");

logger.info("info");

logger.debug("debug");
%>


결과 콘솔화면








static Logger logger = Logger.getLogger("test.jsp");

static 메소드 getLogger를 통해 logger 인스턴스를 가져옵니다.
getLogger에는 파라미터로 스트링 혹은 클래스를 사용하는데 jsp에서는 클래스를 파라미터로 주기에는 좀 애매합니다. 그냥 스트링으로 주도록 하지요


logger.fatal("fatal!!");
logger.fatal("fatal2!!", new NullPointerException("널입니다요"));
  
logger에 fatal 레벨의 메세지를 전달합니다. 다음 두가지 메소드를 지원하는군요

fatal(Object message)

fatal(Object message, Throwable t)

각 레벨마다 위처럼 두가지 메소드를 지원합니다.


지원 메쏘드
logger.fatal(Object message) logger.fatal(Object message, Throwable t)
logger.error(Object message) logger.error(Object message, Throwable t)
logger.warn(Object message) logger.warn(Object message, Throwable t)
logger.info(Object message) logger.info(Object message, Throwable t)
logger.debug(Object message) logger.debug(Object message, Throwable t)


VI. 샘플코드 2


서블릿의 경우 다음과 같이 코딩하면 되겠군요

TestServlet.java


import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class TestServlet extends HttpServlet {


    static Logger logger = Logger.getLogger(TestServlet.class);


    public void init(ServletConfig config) throws ServletException {
         super.init(config);
    }


    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

         try {
              ...
   
              logger.info("Hellow World~");

              ...

          } catch (Exception e) {
              logger.error("Error at TestServlet", e);
          }
     }
}



VII. LOG4J 설정


log4j 설정은 프로그램 내에서 할 수 있지만 설정파일을 사용함으로서 좀더 유연하게 log4j환경을 만들 수 있습니다.


프로그램에서 설정

<%@ page contentType="text/html;charset=MS949"
 import="org.apache.log4j.*,java.io.* "
%>

<%!
 static Logger logger = Logger.getLogger("log4j.jsp");
%>

<%
String layout = "%d %-5p [%t] %-17c{2} (%13F:%L) %3x - %m%n";
String logfilename = "DailyLog.log";
String datePattern = ".yyyy-MM-dd ";

PatternLayout patternlayout = new PatternLayout(layout);
DailyRollingFileAppender appender = new DailyRollingFileAppender(patternlayout, logfilename, datePattern);
logger.addAppender(appender);
logger.setLevel(Level.INFO);
logger.fatal("fatal!!");
%>


property 파일에 설정
log4j.properties를 만들어 /WEB-INF/classes 밑에 놓으세요



log4j.rootLogger=INFO, stdout, rolling

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

log4j.appender.stdout.layout.ConversionPattern=%d %-5p [%t] %-17c{2} (%13F:%L) %3x - %m%n

log4j.appender.rolling=org.apache.log4j.DailyRollingFileAppender

log4j.appender.rolling.File=output.log

log4j.appender.rolling.Append=true

log4j.appender.rolling.MaxFileSize=500KB

log4j.appender.rolling.DatePattern='.'yyyy-MM-dd

log4j.appender.rolling.layout=org.apache.log4j.PatternLayout

log4j.appender.rolling.layout.ConversionPattern=%d %-5p [%t] %-17c{2} (%13F:%L) %3x - %m%n


#최상위 카테고리에 INFO로 레벨 설정 및 appender로 stdout, rolling을 정의

log4j.rootLogger=INFO, stdout, rolling

#stdout 어펜더는 콘솔에 뿌리겠다는 정의

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

#stdout 어펜더는 patternlayout을 사용하겠다는 정의

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

#페턴은 다음과 같이 포맷팅 하겠다는 것을 정의

log4j.appender.stdout.layout.ConversionPattern=%d %-5p [%t] %-17c{2} (%13F:%L) %3x - %m%n


#역시나 rolling 어펜더는 파일로 처리한다라고 정의

log4j.appender.rolling=org.apache.log4j.DailyRollingFileAppender

#로그 파일 이름은 output.log

log4j.appender.rolling.File=output.log

#true면 톰캣을 내렸다 올려도 파일이 리셋되지 않습니다.

log4j.appender.rolling.Append=true

#파일 최대 사이즈는 500KB로 설정

log4j.appender.rolling.MaxFileSize=500KB

#파일 포맷은 output.log.2005-03-10 으로 관리하겠다고 정의

log4j.appender.rolling.DatePattern='.'yyyy-MM-dd

#역시나 rolling 어펜더는 패턴 레이아웃을 사용하겠다고 정의

log4j.appender.rolling.layout=org.apache.log4j.PatternLayout

#rolling 어펜더는 패턴 레이아웃 포맷

log4j.appender.rolling.layout.ConversionPattern=%d %-5p [%t] %-17c{2} (%13F:%L) %3x - %m%n



VIII. 설정 포맷


로그파일명 포맷 (DatePattern)
로그파일명 포맷입니다. 날짜, 시간 및 분단위로까지 로그 파일을 분리할 수 있습니다.

형식 설명
'.'yyyy-MM 매달 첫번째날에 로그파일을 변경합니다
'.'yyyy-ww 매주의 시작시 로그파일을 변경합니다.
'.'yyyy-MM-dd 매일 자정에 로그파일을 변경합니다.
'.'yyyy-MM-dd-a 자정과 정오에 로그파일을 변경합니다.
'.'yyyy-MM-dd-HH 매 시간의 시작마다 로그파일을 변경합니다.
'.'yyyy-MM-dd-HH-mm 매분마다 로그파일을 변경합니다.



PatternLayout 포맷
로그자체를 어떤 포맷으로 남길지 결정합니다.
layout에는 HTMLLayout, PatternLayout, SimpleLayout, XMLLayout등이 있으며 PatternLayout이 일반적으로 가장 많이 쓰입니다.


형식 설명
%p debug, info, warn, error, fatal 등의 priority 가 출력된다.
%m 로그내용이 출력됩니다
%d 로깅 이벤트가 발생한 시간을 기록합니다.
포맷은 %d{HH:mm:ss, SSS}, %d{yyyy MMM dd HH:mm:ss, SSS}같은 형태로 사용하며 SimpleDateFormat에 따른 포맷팅을 하면 된다
%t 로그이벤트가 발생된 쓰레드의 이름을 출력합니다.
%% % 표시를 출력하기 위해 사용한다.
%n 플랫폼 종속적인 개행문자가 출력된다. \r\n 또는 \n 일것이다.
%c 카테고리를 표시합니다
예) 카테고리가 a.b.c 처럼 되어있다면 %c{2}는 b.c가 출력됩니다.
%C 클래스명을 포시합니다.
예) 클래스구조가 org.apache.xyz.SomeClass 처럼 되어있다면 %C{2}는 xyz.SomeClass 가 출력됩니다
%F 로깅이 발생한 프로그램 파일명을 나타냅니다.
%l 로깅이 발생한 caller의 정보를 나타냅니다
%L 로깅이 발생한 caller의 라인수를 나타냅니다
%M 로깅이 발생한 method 이름을 나타냅니다.
%r 어플리케이션 시작 이후 부터 로깅이 발생한 시점의 시간(milliseconds)
%x 로깅이 발생한 thread와 관련된 NDC(nested diagnostic context)를 출력합니다.
%X 로깅이 발생한 thread와 관련된 MDC(mapped diagnostic context)를 출력합니다.

예시) (같은 색끼리 보시면 됩니다)

위의 test.jsp를 다음 포맷으로 출력해본다면

[%c] [%C] [%d] [%F] [%l] [%L] [%m] [%M] [%n] [%p] [%r] [%t] [%x] [%X]는 다음과 같다

[test.jsp] [org.apache.jsp.test_jsp] [2005-03-10 12:37:23,561] [test_jsp.java] [org.apache.jsp.test_jsp._jspService(test_jsp.java:64)] [64] [fatal!!] [_jspService] [개행] [FATAL] [765567] [http-8080-Processor25] [] []

개발/자바 | Posted by 은우 아빠 2009. 1. 16. 10:08

Java (j2se 1.4.1) 메모리 영역 구조


출처 : http://cafe.naver.com/ArticleRead.nhn?articleid=69&sc=e0d433130b4a2d9c18&query=gc+java+%B8%DE%B8%F0%B8%AE&clubid=10092843

1. Sun Microsystyems의 자바 HotSpot VM은 힙을 세 개의 영역으로 나누고 있다.
 힙의 세 영역은 다음과 같다:
 1) Permanent space: JVM 클래스와 메소드 개체를 위해 쓰인다.
 2) Old object space: 만들어진지 좀 된 개체들을 위해 쓰인다.
 3) New object space: 새로 생성된 개체들을 위해 쓰인다.

New object space는 세 부분으로 다시 나누어진. 
모든 새로 생성된 개체들이 가는 Eden, 그리고 그 개체들이 나이들게(Old) 되기 전에 가는 Survivor space1(From), Survivor space2(To) 가 있다.

 

2. Garbage Collector
프로그램은 프로그램을 진행하면서 데이터들을 저장하는 것이 필요하다. 
데이터들은 모두 메모리에 저장이 되는데, 저장할 데이터가 있으면 메모리의 일정 공간을 할당받아서 사용하게 된다. 
프로그램 내에서 사용하게 되는 메모리를 'heap'이라고 한다. 
더 이상 사용되지 않는 데이터에게 메모리를 계속 할당해 주는 것은 메모리를 낭비하는 것이므로, 그 데이터가 사용하던 메모리를 회수하는 것이 필요하다. 
이러한 사용되지 않는 메모리에 대한 회수를 'Garbage Collection'이라고 한다. 자바에서는 프로그램이 사용하는 메모리를 JVM(Java Virtual Machine)이 모두 관리한다.

 

3. OutOfMemory Error 및 해결방법
자바는 객체, 변수등의 생성과 동시에 메모리(Heap)를 차지하게 되고, 문제는 이 객체와 변수를 너무 많이 발생시킴으로 해서 현재 할당된 메모리(Heap)를 초과하게 된다 
그래서 더이상 할당받을 메모리(Heap)가 부족하게 되면 OutOfMemory Error 발생하게 된다. 
OutOfMemory Error 해결방법으로는 
jdk1.4에서 -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC 옵션을 사용한 GC는 현재상태의 Heap메모리 정보출력 한다. 
GC정보를 통하여 New, Old, Perm 등의 영역중 실제 어느 부분이 부족하여 OutOfMemory가 발생하는지 찾은후 부족한 영역의 충분하 size를조절해 주는 방법으로 해결할 수 있다.

 
4. Heap layout 할당에 영향을 주는 스위치들


5. New Generation 메모리 할당 공식
   Eden = NewSize - ((NewSize/(SurvivorRatio + 2)) * 2)
   From space = (NewSize - Eden)/2
   To space = (NewSize - Eden)/2

 
6. Old Generation 메모리 할당 공식
   Old = Xmx - MaxNewSize
 

7.  JVM 스위치 설정 예제
 1) 현재 
http://www.affis.net 서비스는 2200개의 Jsp파일을 가지고 있고 주로 정적인 페이지들이므로 Jsp 파일 로딩에 필요한 Perm size 위주로 메모리 튜닝을 하였다.
 2) 현재 
http://club.affis.net 서비스는 어플리케이션 동적이페이지들로 작성되어 있고 어플리케이션처리에 필요한  New size 위주로 메모리 튜닝을 하였다.
 

8. 맺음말
OutOfMemory 발생한다면 GC로그를 찍어본다. 
로그를 분석해보면 New(eden, from, to), Old, Perm 등의 영역중에서 GC가 발생해도  메모리 영역이 계속 100%로 할당되는 영역이 보일것이다. 
부족한 영역에 충분한 size 메모리를 할당해 주면 OutOfMemory 해결 된다.
그러나 부족한 영역에 계속해서 메모리 할당을 해주어도 사용률이 100%가 나온다면 프로그램 누수일수 있으니 프로그램을 점검해 봐야 할 것이다.

개발/자바 | Posted by 은우 아빠 2009. 1. 15. 16:25

[JVMSTAT]jvmstat 3.0 설치방법



# java JVM Memory Perf 분석


- Tools : jvmstat-5.zip
   J2SE 1.5 이상


- 구성 환경 :
 Host A에 설치 동작중인 Java Applicaton( Unix )에 대한 메모리 이용율을
 Host B( Windows )에서 Remote로 확인


- Host A 설치내용
 J2SE 1.5 이상의 버젼이 설치 되었는지 확인
  참고 : Java 1.5부터는 jvmstat의 내용이 일부 포함되어 배포가 됨.

 jvmstat를 위한 Home Directory 생성 ( /usr/local/jvmstat )
 $ mkdir /usr/local/jvmstat/

 RMI Connection 권한 설정 파일 생성
 $ cd /usr/local/jvmstat/
 $ vi jstatd.all.policy
 grant codebase "file:${java.home}/../lib/tools.jar" {
     permission java.security.AllPermission;
 };

 jvmstat를 위한 환경 변경 설정
 $ export JAVA_HOME=/usr/local/java
 $ export JVMSTAT_HOME=/usr/local/jvmstat
 $ export PATH=$JVMSTAT_HOME/bin:$JAVA_HOME/bin:$PATH

 jstatd 실행 ( jvmstat 2.0의 perfagent와 같음. )
 $ cd /usr/local/jvmstat/
 $ cat start.sh
 #!/bin/bash

 export JVMSTAT_HOME=/usr/local/jvmstat
 export JAVA_HOME=/usr/local/jdk1.5.0_02
 export PATH=$JAVA_HOME/bin:$JVMSTAT_HOME:$PATH

 # RMI Registry Start
 $JAVA_HOME/bin/rmiregistry &

 # JSTAT PerfAgent Start
 nohup \
 $JAVA_HOME/bin/jstatd \
 -J-Djava.security.policy=$JVMSTAT_HOME/jstatd.all.policy
 \
 -J-Djava.rmi.server.logCalls=true \
 &
 $ sh start.sh

 local test 수행
 $ jps
 $ jstat -gcutil 11216 1000 10   ( 11216은 jvmps에서 vmid )

 Java RMI Connection을 위한 설정
 $ vi /etc/hosts
 위 hostname ( backup )을 RMI로 호출될 Interface의 IP로 변경 한다.
 127.0.0.1       localhost.localdomain localhost
 192.168.1.117 backup


- Host B 설치 내용
 J2SE 1.5 이상의 버젼이 설치 되었는지 확인

 jvmstat-3.zip를 C:\에 압축 풀기 ( visualgc에 대한 내용만이 포함되어 있음. )

 jvmstat를 위한 환경 변경 설정
 SET JAVA_HOME="C:\Program Files\Java\jdk1.5.0_02"
 SET JVMSTAT_HOME="C:\jvmstat"
 SET JVMSTAT_JAVA_HOME="C:\Progra~1\Java\jdk1.5.0_02"
 SET PATH=%JVMSTAT_HOME%\bat;%JAVA_HOME%\bin;%PATH%

 remote test 수행 ( Host A와의 RMI 통신여부 확인 )
 C:\jvmstat\bat\> jps 192.168.1.117
 C:\jvmstat\bat\> jstat -gcutil rmi://11216@192.168.1.117 1000 10


- Host A의 Java Application 모니터링
 상기의 설치 내용이 정상적으로 완료 확인

 Host B에서
 C:\jvmstat\bat\> visualgc 11216@192.168.1.117:1099 5000
  11216 : vmid
  192.168.1.117 : host A's IP Address
  1099 : Host A's RMI TCP Port
  5000 : Interval , millisecond

개발/시스템 | Posted by 은우 아빠 2009. 1. 9. 14:49

netstat의 TCP 연결 상태 의미


netstat의 TCP 연결 상태 의미  

netstat의 State 필드에 표시되는 TCP 상태표시가 갖는 의미를 알아봅시다.
RFC 793 문서에 있는 TCP 기본 연결, 종료 과정을 보면 이해가 더 빠를 거라 생각한다.

-----------------------------------------------------------
# netstat -atn
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address          Foreign Address       State
... 생략 ...
tcp        0      0 0.0.0.0:25             0.0.0.0:*             LISTEN      <-- 포트가 열렸음
tcp        0      0 192.168.123.10:32799   207.46.106.141:1863   ESTABLISHED <-- 서로 연결중
tcp        0      0 192.168.123.10:32794   218.xxx.xx.xx:22      ESTABLISHED
tcp        0      0 192.168.123.10:32802   207.46.108.46:1863    CLOSE_WAIT  <-- 종료 대기중
tcp        0      0 192.168.123.10:33244   211.xxx.xx.x:80       ESTABLISHED
... 생략 ...
-----------------------------------------------------------

1) TCP 연결관련 상태

* RFC 793문서에 나온 기본적인 TCP 연결 과정

      TCP A                                                      TCP B

  1.  CLOSED                                                     LISTEN
  2.  SYN-SENT    --> < SEQ=100>< CTL=SYN>                   --> SYN-RECEIVED
  3.  ESTABLISHED <-- < SEQ=300>< ACK=101>< CTL=SYN,ACK>     <-- SYN-RECEIVED
  4.  ESTABLISHED --> < SEQ=101>< ACK=301>< CTL=ACK>         --> ESTABLISHED
  5.  ESTABLISHED --> < SEQ=101>< ACK=301>< CTL=ACK>< DATA>  --> ESTABLISHED

LISTEN      : 데몬이 요청을 발을 수 있도록 연결 요구를 기다리는 상태
  즉, 포트가 열려있음을 의미. http(80), mail(25), ftp(21), telnet(23) 등
  위에서 포트 25(mail)이 메일을 받을 수 있도록 열려 있는 상태
  윈도우즈에서는 LISTENING으로 표시
SYN_SENT    : 로컬에서 원격으로 연결 요청(SYN 신호를 보냄)을 시도한 상태
SYN_RECV    : 원격으로 부터 연결 요청을 받은 상태
  요청을 받아 SYN+ACK 신호로 응답은 한 상태이지만 ACK는 받지 못했다.
  netstat로 확인할 때 SYN_RECV가 상당히 많다면 TCP SYN 플러딩(Flooding) 공격일
  가능성이 있다.
  윈도우즈와 솔라리스에서는 SYN_RECEIVED으로, FreeBSD는 SYN_RCVD으로 표시
ESTABLISHED : 서로 연결이 되어 있는 상태
  위에서 192.168.123.10의 포트 32794과 218.xxx.xx.xx의 포트 22(ssh)이 서로
  연결되어 있는 상태

2) TCP 종료관련 상태

* 정상적인 연결 종료 과정

      TCP A                                                   TCP B

  1.  ESTABLISHED                                             ESTABLISHED
  2.  (Close)
      FIN-WAIT-1  --> < SEQ=100>< ACK=300>< CTL=FIN,ACK>  --> CLOSE-WAIT
  3.  FIN-WAIT-2  <-- < SEQ=300>< ACK=101>< CTL=ACK>      <-- CLOSE-WAIT
  4.                                                         (Close)
      TIME-WAIT   <-- < SEQ=300>< ACK=101>< CTL=FIN,ACK>  <-- LAST-ACK
  5.  TIME-WAIT   --> < SEQ=101>< ACK=301>< CTL=ACK>      --> CLOSED
  6.  (2 MSL)
      CLOSED                                                    

FIN_WAIT1   : 소켓이 닫히고 연결이 종료되고 있는 상태. 원격의 응답은 받을 수 있다.
  솔라리스에서는 FIN_WAIT_1로 표시
FIN_WAIT2   : 로컬이 원격으로 부터 연결 종료 요구를 기다리는 상태
  솔라리스에서는 FIN_WAIT_2로 표시
CLOSE_WAIT  : 원격의 연결 요청을 받고 연결이 종료되기를 기다리는 상태
  원격으로 부터 FIN+ACK 신호를 받고 ACK 신호를 원격에 보냈다.
TIME_WAIT   : 연결은 종료되었으나 원격의 수신 보장을 위해 기다리고 있는 상태
  이 상태를 특히 자주 보게되는 Apache에서 KeepAlive를 OFF로 해둔 경우,
  Tomcat 서버를 쓰는 경우 등
LAST_ACK    : 연결은 종료되었고 승인을 기다리는 상태
CLOSED      : 완전히 연결이 종료된 상태

※ 위의 FIN_WAIT1, FIN_WAIT2, CLOSE_WAIT 3개 상태는 연결 종료를 위해 서로간에
   신호를 주고받는 과정에 나타나는 상태로 이해하면 된다.
   종료 요청을 한 곳에서는 FIN_WAIT1, FIN_WAIT2, TIME_WAIT 상태가
   종료 요청을 받는 곳에서는 CLOSE_WAIT, LAST_ACK 상태가 표시된다.

3) 기타

CLOSING     : 연결은 종료되었으나 전송도중 데이타가 분실된 상태
UNKNOWN     : 소켓의 상태를 알 수 없음

솔라리스의 netstat 명령에서는 다음 2개의 상태를 더 표시한다.

IDLE        : 소켓이 열렸지만 binding 되지 않은 상태
BOUND       : listen이나 연결을 위한 준비 상태

개발/자바 | Posted by 은우 아빠 2009. 1. 8. 16:06

printStackTrace를 Log4j에 출력하기


package com.qnsolv.wipi.exception;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class ExceptionUtil
{
 Log log = null;
 
 
 public ExceptionUtil( Object obj)
 {
  log = LogFactory.getLog(obj.getClass().getName());
 }
 public ExceptionUtil()
 {
  log = LogFactory.getLog(this.getClass().getName());
 }
 public void writePrintStckTrace(Exception e)
 {
  writePrintStckTrace(e, "");
 }
 
 public void writePrintStckTrace(Exception e, String MIN)
 {
  try
  {
   ByteArrayOutputStream out = new ByteArrayOutputStream();
   PrintStream pinrtStream = new PrintStream(new ByteArrayOutputStream());
   e.printStackTrace(pinrtStream);
   String stackTraceString = out.toString();
   log.error("MIN=" + MIN + ":" + stackTraceString.toString());
  }
  catch (Exception e2)
  {
  }
 }
}

개발/소프트웨어공학 | Posted by 은우 아빠 2009. 1. 2. 17:57

[UML] Component Diagram



고층빌딩을 건축할 때 흔히 볼 수 있는 것이 타워 크레인입니다. 이 중장비는
빌딩의 뼈대가 되는 철골 구조물이나 콘크리트 벽체를 높은 곳으로 들어올려 한 층,
한 층 "조립"해 나가는데 필수적인 장비입니다. 요즈음의 빌딩들은 철골 구조물과
콘크리트 구조물을 공장에서 미리 만든 후 현장으로 옮겨와 조립하는 방식으로
만들어 나갑니다.

이러한 부품(컴포넌트)과 조립에 의한 생산방식은 근대 이후 제조업에서는
필수적인 전제 조건이 되었습니다. SW분야에서도 이러한 부품화 및 조립개념이
도입되고 있습니다. CBD(Component Based Development)가 그것입니다.

컴포넌트 다이어그램은 이러한 부품을 정의할 수 있게 도움을 주는 모델입니다.

자, 그럼 시작해 볼까요?
 
1.개요
 
컴포넌트 다이어그램은 "시스템의 구현관점에서
실행모듈(컴포넌트)을 정의하고 실행모듈간의 정적
상호작용
을 정의한 모델"입니다.

이 다이어그램은 시스템이 어떠한 물리적
구성요소들로 -실행모듈(컴포넌트)- 구성되고,
그들간의 연관성을 정의한 것입니다.
여기서 컴포넌트는 매우 광범위한 의미로 사용되는 용어입니다. 여러 분야에서 쓰이는
컴포넌트의 많은 의미 중에서, SW 분야에서 사용되는 컴포넌트를 정의하면 다음과
같습니다.
Reusable application building block.
컴포넌트는 시스템의 재사용 가능한 구성요소입니다.
Physically replaceable or upgradeable parts of a system
컴포넌트는 시스템의 교체단위이자 업그레이드 단위입니다.
An independently deliverable piece of functionality providing access to its
services through interfaces
컴포넌트는 인터페이스를 통해 그 기능이 사용되어지는, 독립적으로 인도되는
기능조각입니다.
 
다음은 UML에서 정의한 컴포넌트의 정의입니다.
A component is a physical, replaceable part of a system that
packages implementation and provides the realization of a set of interfaces.
A component represents a physical piece of implementation of a system,
including software code(source, binary or executable) or equivalents such
as scripts or command files. As such, a Component may itself conform to
and provide the realization of a set of interfaces, which represent services
implemented by the elements resident in the component. These services
define behavior offered by instances of the Component as a whole to other
client Component instances.
(참고자료 : UML 1.3 Specification, OMG)
 
 
컴포넌트 다이어그램을 작성하는 목적은 다음과 같습니다.
시스템의 실행모듈(컴포넌트)들을 정의합니다.
컴포넌트 다이어그램은 시스템이 구축될 때, 어떤 실행모듈(컴포넌트)들로 구축될
것인지를 정의하는 용도로 사용됩니다. 이러한 컴포넌트는 독립적으로 배치, 교체가
가능한 단위입니다. 개발 플랫폼에 따라 이러한 실행모듈의 특성은 달라집니다.
컴포넌트간 Dependency를 정의합니다.
컴포넌트 다이어그램은 실행모듈(컴포넌트)간의 정적인 상호작용을 정의하는 용도로
사용됩니다. 컴포넌트 사이의 종속관계를 표현함으로써 실행 시 상호참조하는
연관성을 표현합니다.
실행모듈뿐 아니라 소스코드, 데이터베이스 등의 상호작용을 모델링합니다.
컴포넌트외에 소스코드나 데이터 베이스등 조각으로 나누어 정의할 수 있는 대상들에
대해, 그 대상들의 상호작용을 정의하기도 합니다. 그러나 이런 용도로 사용되는
경우는 흔치 않습니다.
그럼, 이러한 컴포넌트 다이어그램은 언제 작성하는 것이 적절할까요?

컴포넌트 다이어그램은 시스템의 설계단계의 막바지에 작성합니다. 즉, 모든 클래스가
물리적으로 완전히 정의되고, 그 상호관계도 정의된 후 컴포넌트 다이어그램이 작성될
수 있습니다.
 
2.구성요소
 
컴포넌트 다이어그램의 구성요소는 다음과 같습니다.
Things 혹은 심볼 : 컴포넌트(Component), 인터페이스(Interface)
Relationships : Dependency, Realization
 


컴포넌트의 표기
컴포넌트는 탭이 달린 직사각형으로 표기하며,
컴포넌트 명은 심볼 내에 표기합니다.
컴포넌트의 정의
컴포넌트는 독립적으로 배포되고 교체되며 재사용될 수 있는 SW조각
의미합니다. 보통의 경우 실행모듈을 말하지만, 실제 통용되는 컴포넌트라는
용어는 항상 실행모듈만을 가리키지는 않습니다.
컴포넌트가 가끔은 아주 광의로 사용되어서 소스코드나 UI(User Interface), 분석,
설계 산출물들을 포함한 것을 의미하기도 합니다.
컴포넌트라는 용어의 의미는 문맥에서 말하는 사람의 의도를 생각해서 받아들여야
합니다.
컴포넌트의 예
컴포넌트는 매우 다양한 크기로 정의되며. 아래 예들은 한정된 컴포넌트의 사례일
뿐입니다.
결재 시스템에서 결재, 사원 등
전자 상거래 시스템에서 우편번호 검색, 신용카드 결제 등
인터페이스의 표기
인터페이스는 두 가지 형태로 표기가 가능합니다.

하나는 icon형태의 표기로 원으로 표현하는데, 이 경우 인터페이스 명은 아래쪽에
표기합니다. 다른 하나는 보통의 클래스에 <>라는 스테레오 타입이 부가된
표기입니다.
인터페이스의 정의
Interface는 Class의 일종입니다.
interface는 class나 Component의 기능을 외부에 공개할 목적으로 쓰이며,
구현은 하지 않습니다.
interface의 구현은 클래스나 컴포넌트에서 하게 되며, 이 클래스는 interface를
상속하여 단지 선언뿐인 interface의 구현을 담당합니다.
Interface는 단독으로 표시되는 경우는 거의 없으며 해당 Interface를 구현하는
Class나 Component에 붙어 다닙니다.
Dependency의 표기
점선 화살표로 표현하고 필요에 따라 선 위에 설명을
붙이기도 합니다.
컴포넌트의 정의
객체나 컴포넌트가 다른 객체나 컴포넌트의 실행을 요청하는 경우, 즉 사물 간의
실행 혹은 참조관계를 표현합니다.
Class와 Class , Package와 package , Component와 Component에 주로
사용되는 관계이고, 때로는 Class-Package-Component 상호 간에도 사용되는
관계입니다.
Realization의 표기
속이 빈 삼각형의 화살표가 한쪽에 달린 점선으로 표현합니다. 그러나 특별히
컴포넌트 다이어그램에서는 인터페이스와 컴포넌트간의 실선으로 표현됩니다.
Realization의 표기 인터페이스와 컴포넌트 간 표기
Realization의 정의
정의하는 사물과 이를 구현하는 사물 간에 표현하는 관계입니다.
Realization은 인터페이스(정의) - 컴포넌트(구현), 유즈케이스(정의) -
컬레버레이션(구현)과 인터페이스(정의) - 클래스(구현) 사이에 허용되는
관계입니다.
삼각형이 붙은 쪽이 정의하는 사물, 반대쪽이 구현하는 사물입니다.

3.사례연구
 
다음은 간단한 컴포넌트 다이어그램 사례입니다. 지금까지 배운 내용으로 아래 모델을
나름대로 해석해 봅시다.
위 컴포넌트 다이어그램은 시스템(혹은 서브시스템)이 GUI, Planner, Scheduler의
3개 컴포넌트로 구성됨을 의미합니다. 그리고 다음과 같은 컴포넌트간의 의존관계가
존재함을 표현합니다.
GUI 컴포넌트가 Update 인터페이스를 통해 Planner 컴포넌트의 실행을 요청
Planner 컴포넌트가 Reservations 인터페이스를 통해 Scheduler 컴포넌트의
실행을 요청
다음은 컴포넌트 다이어그램의 두 번째 사례입니다.
첫 번째 사례와는 달리 인터페이스가 없습니다. 이 모델이 무엇을 말하고 있는지
해석해 봅시다.
위 컴포넌트 다이어그램은 umlviewer.exe라는 실행 모듈이 동작하면서 graphics.dll,
dbhandler.dll , umlcore.obj라는 실행 모듈들에게 서비스를의 실행을 요청한다는
것을 모델링한 것입니다.
 
4.작성단계 및 주의사항
 
먼저, 컴포넌트 다이어그램의 작성순서를 알아보겠습니다.
컴포넌트 대상을 정의합니다.
컴포넌트 다이어그램을 그리기 전에 무엇을 컴포넌트로 표현할지 클래스를
구성요소로 하는 실행모듈로 할지, 소스코드를 정의할 지 기타 무엇을 컴포넌트로
표현할 지를 정해야 합니다.
컴포넌트를 식별합니다.
컴포넌트 다이어그램에 등장할 컴포넌트를 정합니다. 소스 파일일 경우 그 대상은
쉽게 식별되지만 실행모듈일 경우 간단치 않습니다. 여러 가지 가능한 방법으로
컴포넌트를 식별해 내는 작업을 수행 합니다.
컴포넌트를 배치하고 필요시 인터페이스를 붙입니다.
컴포넌트 다이어그램에 컴포넌트를 배치하고 이름을 정의합니다. 그리고
인터페이스를 정의할 필요가 있을 경우 인터페이스를 정의하고 컴포넌트와
realization관계로 연결합니다.
Dependency를 정의합니다.
컴포넌트와 컴포넌트간 의존관계를 분석하여 Dependency 관계를 정의합니다.
 

다음은 컴포넌트 다이어그램 작성 시 주의사항입니다.
컴포넌트는 응집도는 높고 결합도는 낮은 단위로 정의되어야 합니다.
실행모듈로서의 컴포넌트를 식별할 때, 컴포넌트는 다른 컴포넌트와 독립적이고,
기능 차별성을 갖추는 단위로 정의되어야 합니다. 즉, 기능 측면에서 컴포넌트 내부는
강한 유사성을 갖는 단위들로 구성되어야 하고(높은 응집도), 다른 컴포넌트에 강하게
종속되지는 않는(낮은 결합도) 단위로 정의되어야 합니다.
컴포넌트 크기(Granularity)의 일관성을 고려해야 합니다.
한 시스템에서 컴포넌트의 크기에 너무 차이가 나면 바람직하지 않습니다. 컴포넌트의
크기는 기술구조와 시스템 특성들이 고려되어 적절한 크기로 정의해야 하며, 그 크기도
되도록 많이 차이나지 않도록 하는 것이 좋습니다.
추상화 수준에 맞는 상세성을 일관되게 제공합니다.
모든 모델이 마찬가지 입니다만, 한 장의 모델에는 동일한 상세화 레벨이 유지되어야
합니다. 서로 다른 추상화 레벨의 컴포넌트가 섞여 있으면 의미를 파악하기 힘들게
됩니다. 소스와 실행모듈을 한 장에 정의한 컴포넌트는 좋은 예가 아닙니다.
목적을 전달할 수 있는 명칭을 부여해야 합니다.
컴포넌트,인터페이스를 비롯해 쓰이는 모든 명칭들은 명확한 표현을 사용해야 합니다.
모호한 명칭으로 정의하면 혼란만 야기 시키는 결과가 됩니다.


RUP (Rational Unified Process)

지난 시간에는 UML의 필요성과 간단한 개념을 살펴보았습니다. 이번 시간부터는 UML을 구성하는 각종 다이어그램들을 하나씩 살펴봅시다. 또한 깊은 이해와 함께 몸으로 익힐 수 있도록 UML 모델링 도구로 가장 유명한 Rational Rose를 이용하여 간단한 실습을 해보도록 하죠. 실습을 위한 소프트웨어는 UML 관련 책자의 부록이나 Rational 사의 웹사이트를 통해 평가판을 구하실 수 있습니다. 평가판을 다운로드 할 수 있는 웹 페이지의 URL은 다음과 같습니다.

본 내용을 진행하기에 앞서 다음의 서적들을 참고로 이 글을 작성했음을 밝힙니다. 더 깊은 이해를 위해서는 이들 서적을 참고하세요.
  Visual Modeling with Rational Rose and UML, Terry Quatrani, Addison Wesley
  UML Distilled Second Edition, Martin Fowler with Kendall Scott, Addison Wesley
  초보자를 위한 UML, Joseph Schmuller, 곽용재 역, 인포북
  The Rational Unified Process An Introduction Second Edition, Philippe Kruchten
  The Unified Modeling Language Reference Manual, James Rumbaugh, Ivar Jacobson, Grady Booch, Addison Wesley
예제 화면은 rose2001A.04.00 버전을 기준으로 사용했습니다. 다른 버전을 사용하시더라도 UML을 배우는 입장에서 큰 차이는 없을 것입니다. 예제 내용은 일반적이고 검증된 것을 사용하고자 Visual Modeling with Rational Rose and UML의 예제를 인용했습니다. UML 구성 요소들의 이름을 한글로 사용할 수 있지만, 코드와의 일관성 유지 등의 목적으로 영어를 사용했습니다. 다만, 한글로 충분히 설명을 기술하도록 하겠습니다.

RUP (Rational Unified Process)
유즈케이스(Use Case)에 대해 본격적으로 설명하기에 앞서 RUP에 대한 언급을 하지 않을 수가 없습니다. UML은 모델링을 위한 표기법입니다. UML이 시스템 개발에 매우 중요하다 하겠지만, UML만으로는 아무 것도 되지 않습니다. 객체 지향으로 시스템 개발을 하겠다고 UML을 사용하면서 개발은 기존의 전통적인 방식을 따른다면 효과가 높지 않을 것입니다.

객체 지향의 시스템 개발을 하려고 한다면 개발의 방법론 역시 객체 지향을 따라야 할 것입니다. 수많은 객체 지향 방법론이 존재한다고 합니다. 이 중에 가장 부각되고 있는 것이 RUP입니다. 무엇보다 RUP는 Rational의 소프트웨어 군을 이용한 개발 방법론으로서 이론뿐만 아니라 구체적인 솔루션이 동반된다는 강점을 지니고 있습니다.

쉽게 얘기하면Rational의 도구들과 RUP에 맞춰서 UML을 사용하여 개발 한다면 삼박자를 갖추게 된다는 매력적인 제안이죠. 우리는 RUP를 배우는 게 아니고 UML을 배우는 것이지만, 시스템을 개발하는 과정을 염두에 두지 않고 UML을 논하는 것은 공허할 수 있습니다. UML이 어떻게 쓰이는지를 생각하지 않겠다는 것이 될 수 있으니까요.
RUP가 최상의 개발 방법론은 아니지만, 개발 공정에 대한 한 예로 RUP를 간단하게 엿보도록 하죠.
다음은 RUP의 개발 공정에 대한 개괄적 그림입니다.
[RUP 개발 공정]

RUP의 개발 공정은 크게 두 축으로 나눠 볼 수 있습니다. 우선 그림의 가로축으로 시간의 흐름에 따른 네 가지 단계(Phases)로 구분할 수 있고, 세로축의 9가지 웍플로우(Workflow)로 나눌 수 있습니다. 웍플로우는 컴포넌트처럼 작업의 성격에 따라 일을 분리한 것입니다.

기존의 방법론이 도입기에는 주로 타당성 검증 등을 하고, 분석 및 설계, 구현, 검증 및 배포와 같은 식으로 일원적인 관점에서 개발을 했다면 RUP는 이차원적인 관점을 갖는다고 하겠습니다. 도입기라고 할 수 있는 도입(Inception) 단계에서는 주로 비즈니스 모델링(Business Modeling)을 수행하지만 이를 위해 상당량의 요구사항 분석을 수행해야 하고, 개발 프로젝트의 타당성이나 위험도 등의 검증을 위해 프로토타입을 만들어 본다든가 하는 구현도 일부분 수행하게 됩니다. 마찬가지로 향후 프로젝트를 정교하게 발전시켜가는 정련(Elaboration) 단계에서도 요구사항 수집과 분석 설계는 물론 도입 단계에서 만들어진 비즈니스 모델링(Business Modeling)을 검증하고 더욱 정교하게 수정하는 일도 계속하게 됩니다. RUP는 이와 같은 식으로 점진적인 개발 방법을 채택하고 있습니다. 이러한 단계들과 웍플로우의 적절한 조합은 두말할 필요 없이 매우 중요하다고 하겠죠. 프로젝트 관리자에 의해서 이러한 적절한 조합이 계획되는데 이를 이터레이션(Iteration)이라고 합니다. 결국 RUP는 이터레이션의 연속으로 개발을 수행하게 되는 것이죠.

유즈케이스 이해하기
이제야 본격적으로 유즈케이스를 얘기할 차례군요. 유즈케이스는 우리말로는 쓰임새라고도 합니다. 두 가지를 동시에 사용하는 혼돈을 막기 위해서 여기서는 원어로 유즈케이스라고 표기하는 것을 원칙으로 하겠습니다.

유즈케이스라 함은 말 그대로 ‘쓰이는 경우’라던가 ‘용도’ 같은 의미로 받아들여도 큰 무리가 없다고 보여집니다. 어떤 일에 쓰느냐 하는 것이죠. 시스템이 쓰여지는 용도를 모아서 시스템을 만들어낸다면 다용도 시스템이 만들어지겠죠. 유즈케이스들을 모아서 시스템으로 매핑 시키는 것을 개발 과정의 간단한 정의로 보아도 무리가 없을 만큼 유즈케이스는 가치 있는 것입니다.

제가 한국 Rational 이사님의 세미나를 들은 일이 있습니다. 그때 UML에 관한 부분에서는 유즈케이스를 유난히 강조하시더군요. 유즈케이스는 사용자 시각에 맞춘 분석입니다. 어떤 시스템을 만드느냐를 사용자 입장에서 조명하는 것이죠. 최근 비즈니스가 발전함에 따라 고객 지향 마인드가 널리 퍼져 있습니다. 당연한 결과라 하겠죠. 마찬가지로 시스템 개발에 있어서도 고객 관점에서 바라보는 시각이 부각되는 것은 당연한 일이라 하겠습니다.

객체 지향 개발 자체가 기존 개발 방법들에 비해 상당히 인간위주의 개발 방법론이라는 느낌이 드는데 유즈케이스는 이러한 휴머니즘의 선봉에 서있다고 해도 큰 비약은 아니라는 생각이 듭니다. 아무튼 유즈케이스는 시스템 보다는 그것을 사용하는 인간, 즉 사용자의 입장을 우선해서 시스템이 어때야 하는가를 알아보는 것입니다. 아무리 잘 만든 시스템도 인간에게 가치를 주지 못하면 무의미한 것이죠.

이러한 휴머니즘을 잊지 마시고, 유즈케이스를 배워 봅시다. 유즈케이스는 시스템의 행위를 결정하는 것입니다. 구체적으로는 시스템의 기능을 정의하고, 범위를 결정함으로써 시스템과 외부 환경 변수를 구분하고, 상호 관계를 정립하는 것이라고 볼 수 있습니다.
개발 공정과 연관해서 보면 도입 단계에서 주요 유즈케이스를 뽑아내고, 차츰 이를 정련하게 됩니다.
유즈케이스를 나타내는 유즈케이스 모델(Use case Model)은 유즈케이스 다이어그램으로 표현됩니다. 유즈케이스 다이어그램은 액터(Actor, 행위자)와 유즈케이스, 그리고 관계(Relationship)로 나타냅니다.


 
유즈케이스, 액터, 관계

액터(Actors)
액터는 시스템의 일부가 아닙니다. 액터는 시스템과 상호작용을 하는 모든 것들을 나타냅니다. 시스템을 사용하게 될 사람은 물론이고, 연관된 다른 시스템도 액터입니다. 대체로 액터의 행위는 정보의 입력과 출력으로 살펴 볼 수 있습니다. 정보를 입력하거나 출력하는 액터가 있고, 입출력을 모두 행하는 액터가 있을 것입니다.

액터를 뽑아내는 일은 매우 중요한 일입니다. 모든 주요 액터를 고려해야만 모두에게 가치 있는 시스템이 될 수 있을 테니까요. Visual Modeling with Rational Rose and UML에 따르면 다음과 같은 질문들이 액터를 뽑아내는데 도움을 준다고 합니다.
   특정 요구사항에 이해관계자는 누구인가?
   어떠한 부서나 집단에서 시스템을 사용하는가?
   시스템을 사용함으로써 이익을 얻는 이는 누구인가?
   누가 시스템에 정보를 입력하고 사용하며 삭제하는가?
   누가 시스템의 유지보수를 수행하는가?
   시스템이 외부 자원을 사용하는가?
   한 사람이 복수의 역할을 수행하는가?
   여러 사람이 한 가지 역할을 수행하는가?
   시스템이 레거시 시스템(Legacy System)과 상호 작용 하는가?

액터는 다이어그램 상에서 막대인간(stickman)으로 표현됩니다.
[액터의 UML 표기법]

유즈케이스 (Use Cases)
유즈케이스 모델은 시스템과 액터와의 의사소통을 표현합니다. 각각의 유즈케이스는 시스템이 제공해야 하는 기능을 묘사하고, 이러한 유즈케이스들이 시스템 전체의 기능을 나타냅니다. 하나의 유즈케이스는 액터가 원하는 기능을 수행하기 위해 시스템이 수행하는 일련의 처리들의 연속입니다. Visual Modeling with Rational Rose and UML에 따르면 다음과 같은 질문들이 유즈케이스를 뽑아내는데 도움을 준다고 합니다.
   각각의 액터의 업무는 무엇인가?
   액터가 시스템의 정보를 생성, 저장, 수정, 삭제하고 읽는가?
   어떠한 유즈케이스가 시스템의 정보를 생성, 저장, 수정, 삭제하고 읽는가?
   액터가 돌연한 외부 변화에 대한 정보를 시스템에게 알릴 필요가 있는가?
   시스템에 갑자기 발생한 일들을 액터가 알아야 하는가?
   어떠한 유즈케이스들이 시스템을 지원하고 유지하는가?
   유즈케이스들이 모든 요구되는 기능을 포괄하여 수행하는가?

유즈케이스의 UML 표기법은 타원(Oval)입니다.
[Use Case의 UML 표기법]

관계(Relationship)
관계는 크게 두 가지로 볼 수 있습니다. 하나는 액터와 유즈케이스의 관계이고, 다른 하나는 유즈케이스간의 관계입니다. 액터와 유즈케이스와의 관계는 연관(Association) 혹은 커뮤니케이션 연관(Communicates Association)이라고 합니다. 액터와 유즈케이스간의 의사소통을 나타내기 때문이겠죠.

연관은 양방향으로 진행될 수 있습니다. 연관의 방향성은 어느 쪽이 연관을 유발하느냐에 따라 달라집니다. 오직 액터 혹은 유즈케이스만이 연관을 유발하는 단방향 연관이 있고, 양쪽 모두에서 연관을 일으키는 양방향 연관이 있습니다.

유즈케이스간의 관계는 두 가지 형태가 있습니다. 포함(Inclusion 혹은 사용 Use)과 확장(Extension)입니다. 여러 유즈케이스들이 하나의 기능 조각을 공유할 때 이를 모든 유즈케이스에 각각 집어넣는 것 보다는 이를 분리해두고 필요한 유즈케이스들이 이를 포함해서 사용하게 됩니다. 예를 들어 회원제를 기반으로 한 인터넷 사이트에 접속하셔서 각종 서비스를 제공받기에 앞서 늘 수행하는 회원 인증과 같은 유즈케이스가 포함 관계입니다.

확장 관계는 기본 유즈케이스에서 특정 조건이나 액터의 선택에 따라 발생하는 유즈케이스입니다. 가령, ATM에서 사용자의 메뉴 선택에 따라 달라지는 유즈케이스의 경우나 긴급 상황 시에 발생할 수 있는 유즈케이스가 확장의 예로 생각할 수 있습니다.

관계는 선으로 표기하며 관계의 방향성은 화살표로 나타냅니다. UML에는 스테레오타입(Stereotype)이라는 개념이 있습니다. 이는 기본적인 모델링 요소 이외의 새로운 타입을 나타내는 것입니다. 따라서 확장을 가능하게 해줍니다. 스테레오타입이라는 것이 인쇄소의 연판을 나타내는 것입니다. 어느 정도 변화를 줄 수 있는 유연한 판형이라는 것이죠. 이처럼 스테레오타입은 기본 모델링 요소에 확장성을 부여할 수 있는 개념입니다.
개발/자바 | Posted by 은우 아빠 2008. 12. 30. 19:22

Java FX for Eclipse


JavaFX가 넷빈즈에서만 돌아가는 줄 알았는데 역시나 이클립스 용 플러그인이 나와 있습니다.


위 링크를 통해 다운로드 받은 파일을 eclipse 설치 폴더에 압축해제하면 설치는 완료 됩니다.

사용방법은 다음과 같습니다.

아래 이미지와 내용은 해당 사이트의 Getting Start 문서를 옮겨왔습니다.

JavaFX SDK 설치

JavaFX SDK for Windows or Mac Os X 다운로드 받아 설치합니다.

Eclipse 설치

Eclipse 3.4 이상이 필요하며. Eclipse IDE for Java EE Developers for Windows or Mac OS X 설치가 필요합니다.

Plugin 설치

  1. plugin을 다운로드 받습니다.:
  2. com.sun.javafx.eclipse.feature-win32-win32-x86-1.0.zip for Windows
  3. com.sun.javafx.eclipse.feature-macosx-carbon-x86-1.0.zip for Mac OS X
  4. eclipse 설치 디렉토리에 압축을 해제합니다.
  5. Eclipse 을 실행합니다.

JavaFX 프로젝트 만들기 와 JavaFX SDK 설정하기
  1. 이클립스를 시작하면 이클립스 workbench의 기본 레이 아웃이 보입니다.
    New empty workbench
  2. Package Explorer에서 오른쪽 클릭하여 New > Java Project 를 선택합니다.
    New Java Project menu
  3. Create a new JavaTM project 로 자바 프로젝트를 생성합니다. 
    New empty workbench
  4. MyJavaFXProject 라는 프로젝트 명과 Finish 버튼을 누릅니다. 새로운 프로젝트가 Package Explorer에 나타납니다. 
    New project created
  5. 프로젝트 이름을 선택하고 오른쪽 클릭하여 JavaFX > Add JavaFX Nature 를 선택합니다.
    Add JavaFX nature to Java Project
  6. 그럼 JavaFX perspective가 활성화 됩니다. JavaFX nature 를 Java Project 에 처음 추가 하는것이라면 JAVAFX_HOME 속성값을 물어볼수도 있습니다.
    Error, JavaFX SDK home not set up.
    JAVAFX_HOME 속성 설정은 아래 단계를 따릅니다.:
    1. 다이얼로그 메시지의 OK 버튼을 누르고 No thanks, I prefer Cancel 버튼을 누릅니다.
    2. 아래와 같은 다이얼로그 창이 그면 JAVAFX_HOME 값을 (empty)로 추가시킵니다.
      Preferences: Classpath Variables
    3. 그리고 Edit... 버튼을 누르면 아래와 같은 창이 뜹니다.
      Edit classpath variable
    4. Folder... 버튼을 눌러 the JavaFX SDK 설치 폴더를 지정해줍니다. 
      Select instalation folder of JavaFX SDK
    5. 폴더선택창의 OK 버튼을 누르고, 변수 Edit 창의 OK 버튼을 누릅니다. 
      Result of setting JAVAFX_HOME property
    6. Preferences 다이얼로그의 OK버튼을 누릅니다. 그럼 JAVAFX_HOME 변수의 세팅이 끝납니다. 만약 Cancel 버튼을 누르면 에러 다이얼로그 창이 뜨며 다시 반복하여 묻게 됩니다.
  7. 이로서 첫번째 JavaFX Project 생성이 완료되었습니다. 
    Opened JavaFX Perspective with Java Project with JavaFX nature

Adding Files

  1. MyJavaFXProject 를 확장해보자. src 폴더를 선택하고. 오른쪽 클릭을 하여 New > Package를 선택한다. 그리고 package 이름에 com.sun.eclipse.example를 입력해보자.
    Adds new Empty Script file into folder.
  2. src/com.sun.eclipse.example 폴더를 오른쪽 클릭후. New > Empty Script 를 선택하자.
    Adds new Empty Script file into folder.
  3. New File 마법사가 보일것이다. Name 필드에 Main 이라고 입력하자.
    New file wizzard
  4. Finish 버튼을 누르면 새로운 JavaFX 스크립트 창이 열린다. 
    New empty FX script
  5. Snippets view를 보자. 여기엔 애플리케이션 개발을 도와줄 여러 가지 code snippets 이 있다. Applications 항목을 열어 Stage를 선택해보자.
    Snippets View
  6. Stage 노드를 editor window로 Drag and drop 하면. Insert Template: Stage 다이얼로그가 보인다. title 변수값을 Hello World 로 바꾸자.
    Result after drop
  7. Insert 버튼을 누르면 template 의 결과가 소스 코드로 변환되어 insert 된다. 
    Result in editor
  8. Mission accomplished, Sir!

Running

Eclipse 로 실행하는 것은 매우 쉽다.

  1. 툴바의 Run 버튼을 누른다. 
    Run icon
  2. 첫번째 실행이라면 Edit Configuration 다이얼로그가 보인다. 
    Configuration
    모든 옵션은 default 값이다. 가장 흥미로운 부분은 Profile - Target 옵션이다. 여기서 실행환경을 조정할 수 있다. 가능한 옵션은 아래와 같다.:
    • Desktop profile - Run as Application
    • Desktop profile - Run as Applet
    • Desktop profile - Run with WebStart
    • Mobile Profile[?] - Run in Emulator
  3.  Run 버튼을 눌러 애플리케이션을 작동시킨다. console 창에 실행 프로그레스가 뜰것이다. 
    Running application

Building

Eclipse 에서의 Build 작업은 default로 자동으로 제공된다. Project 메뉴에서 Build와 관련된 좀 더 많은 옵션을 볼 수 있다.

Configuration Options

  1. Package Explorer 에서 프로젝트 선택 후 오른쪽 클릭하여 Properties를 선택한다. 
    Menu: Project Properties
  2. Properties 창이 보이면 JavaFX Defaults 를 선택한다.
    Properties: JavaFX Defaults
    여기서 JavaFX Project의 실행과 디플로이 프로세스 동안 사용되는 몇가지 기본 파라미터 값을 수정할 수 있다. 좀 더 많은 정보는 JavaFX Packager Documentation 을 통해 볼 수 있다.

JavaFX Help

이 플러그인은 JavaFX SDK documentation로의 접근을 매우 쉽게 해준다. Help > Java FX > JavaFX Script Documentation or press Ctrl + F1 를 누르므로서 Document에 접근 할 수 있다.
JavaFX SDK Help

Footnotes:

  • 언제든 JAVAFX_HOME 변수를 아래와 같은 방법으로 수정 할 수 있다.:
    1. Open Window > Preferences
    2. Expand Java > Build Path and select Classpath Variables
    3. Edit JAVAFX_HOME
  • SDK의 profile을 아래 단계를 통해 수정 할 수 있다.:
    1. Right click on project name. Select Properties > Java Build Path > Libraries
    2. Double click on JavaFX System Library. The Edit Library dialog appears. Here you can set the profile to use.
      Dialog: Edit JavaFX System Library


출처 : http://javaora.tistory.com/entry/Java-FX-for-Eclipse
개발/DB_공통 | Posted by 은우 아빠 2008. 12. 30. 19:18

토드(Toad)에서 실행중인 sql 중지하는 법



저도 배운 겁니다.
^^;
default 옵션은 꺼져 있는데, 이것만 활성화시키면 토드에서 sql 결과가 나오지 않아서 프로세스를 죽이지 않아도 됩니다.
옵션
View 메뉴의 Options... 를 선택합니다.

SQL Editor에 숨어있는 옵션

Options 창에서 우측에 SQL Editor를 선택하고 우측 목록에서 Process statesments in threads / allow queries to be cancelled 항목을 체크합니다. 영어로 되어있어서 눈에 안 들어왔던 거죠... 그리고 우측 하단의 OK 를 클릭합니다.  cancel활성화 시켰다고 지금 Cancel 버튼 클릭하면 안됩니다.

메뉴에 있는 활성화된 Cancel
이제 실행 오래 걸리는 쿼리를 날리더라도 메뉴에 있는 Cancel 만 클릭해주면 다음과 같이 현 조작의 취소가 요구되었습니다 라는 메시지와 함께 중지 시킬 수 있습니다.

상태바 메시지