달력

5

« 2024/5 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
2006. 11. 3. 10:29

code analysis plugin 2006. 11. 3. 10:29

:
Posted by codetemplate
2006. 11. 1. 09:53

iBatis 1:N mapping 프레임워크2006. 11. 1. 09:53

게시판 시스템에 Article과 ArticleFile이라는 객체가 있고 이들이 1:N의 관계가 있다면 Article에는 아래와 같은 attribute이 존재할 것이다.

private Collection articleFiles;

이러한 경우 Article을 읽을 때 n개의 ArticleFile을 outer join을 이용하여 eager fetching하기 위한 맵핑은 아래와 같다.

<resultMap id="articleFilesResultMap" class="articleFile">
   <result property="fhandle" column="fhandle"/>
   <result property="articleId" column="articleFileArticleId"/>
   <result property="fileName" column="fileName"/>
   <result property="contentType" column="articleFileContentType"/>
   <result property="size" column="articleFileSize"/>
   <result property="regDate" column="articleFileRegDate"/>
</resultMap>

<resultMap id="latestArticleDetailMap" class="article" extends="articleResultMap" groupBy="id">
   <result property="articleContent.id" column="contentId" />
   <result property="articleContent.content" column="content" />
   <result property="commentCount" column="commentCount"/>
   <result property="articleFiles" resultMap="Article.articleFilesResultMap"/>
</resultMap>

<select id="getLatestArticles" parameterClass="map" resultMap="latestArticleDetailMap">
   SELECT
       a.*,
       ac.id contentId, ac.content,
       af.fhandle, af.articleId articleFileArticleId, af.fileName,
       af.contentType articleFileContentType, af.size articleFileSize,
       af.regDate articleFileRegDate,
       (SELECT COUNT(c.id) FROM articleA000001comment c WHERE c.articleId = a.id) commentCount
   FROM
       articleA000001 a , articleA000001content ac
   LEFT OUTER JOIN articleA000001file af ON af.articleId = a.id
   WHERE
       a.id = ac.id
   AND
       (status='S' OR status='L' OR deletedButDisplay=1)
   ORDER BY
       a.depth DESC
   LIMIT 0, 100
</select>


여기서 latestArticleDetailMap의 groupBy="id"가 키포인트이다.

:
Posted by codetemplate
2006. 11. 1. 09:14

멀티 탭을 지원하는 터미널 2006. 11. 1. 09:14

http://software.jessies.org/terminator/

mac, cygwin, linux에서 멀티 탭 터미널을 제공하는 오픈소스 툴...

cygwin에 벌써 깔았고, 이제 맥에 깔야쥐...
:
Posted by codetemplate
2006. 10. 30. 20:16

Spring Web Flow 1.0 Released !! 프레임워크2006. 10. 30. 20:16

:
Posted by codetemplate
2006. 10. 30. 19:58

한글이 들어가 프로퍼티 파일이 깨지는 문제 Java2006. 10. 30. 19:58

navite2ascii를 이용하여 프로퍼티 파일을 변환한다.

:
Posted by codetemplate
2006. 10. 30. 19:57

inetd 다시 기동하기 명령어2006. 10. 30. 19:57

pkill -HUP inetd
:
Posted by codetemplate

java.lang.SecurityException: Could not lockSystem prefs.Lock file access denied.
       at java.util.prefs.FileSystemPreferences.checkLockFile0ErrorCode(FileSystemPreferences.java:926)
       at java.util.prefs.FileSystemPreferences.lockFile(FileSystemPreferences.java:915)
       at java.util.prefs.FileSystemPreferences.sync(FileSystemPreferences.java:723)
       at java.util.prefs.FileSystemPreferences.flush(FileSystemPreferences.java:814)
       at java.util.prefs.FileSystemPreferences.syncWorld(FileSystemPreferences.java:475)
       at java.util.prefs.FileSystemPreferences.access$1200(FileSystemPreferences.java:33)
       at java.util.prefs.FileSystemPreferences$10.run(FileSystemPreferences.java:449)
       at java.util.TimerThread.mainLoop(Timer.java:432)
       at java.util.TimerThread.run(Timer.java:382)

이런 에러가 종종 생기는데 이유가 먼가요?


이 에러는 JDK 1.4의 XML Configuration 기능 사용시 발생 가능합니다.
다음과 같은 방법으로 해결됩니다.

$JAVA_HOME 디렉토리와 java를 사용하는 user(vep, msgsvr, jaaad 등)들이 그룹이 같아야 합니다.

$JAVA_HOME/.systemPrefs 디렉토리에 group에게 모든 권한을 준다.
$JAVA_HOME/jre/.systemPrefs 디렉토리에 group에게 모든 권한을 준다.

그리고 아래의 디렉토리에 있는 파일들을 다 삭제한다.

$JAVA_HOME/.systemPrefs
$JAVA_HOME/jre/.systemPrefs
$HOME/.java

이렇게 하면 해결 됩니다.

:
Posted by codetemplate
2006. 10. 30. 19:55

Oracle data를 csv로 덤프하는 방법 DB2006. 10. 30. 19:55

    1  #!/bin/ksh
    2
    3  for tableName in `cat table.lst`
    4  do
    5          echo "set echo off" > t1.sql
    6          echo "set heading off" >> t1.sql
    7          echo "set pagesize 0" >> t1.sql
    8          echo "set verify off" >> t1.sql
    9          echo "set feedback off" >> t1.sql
   10          echo "set linesize 130" >> t1.sql
   11          echo "set trimspool on" >> t1.sql
   12          echo "define tableName=$tableName" >> t1.sql
   13          echo "spool t2.sql" >> t1.sql
   14          echo "select 'set echo off' from dual;" >> t1.sql
   15          echo "select 'set heading off' from dual;" >> t1.sql
   16          echo "select 'set pagesize 0' from dual;" >> t1.sql
   17          echo "select 'set verify off' from dual;" >> t1.sql
   18          echo "select 'set feedback off' from dual;" >> t1.sql
   19          echo "select 'set linesize 130' from dual;" >> t1.sql
   20          echo "select 'set trimspool on' from dual;" >> t1.sql
   21          echo "select 'spool &tableName.csv' from dual;" >> t1.sql
   22          echo "select 'select ' from sys.dual;" >> t1.sql
   23          echo "select decode(column_id,1,column_name, '||'',''||'||column_name)" >> t1.sql
   24          echo "from   sys.dba_tab_columns" >> t1.sql
   25          echo "where  table_name = '&tableName'" >> t1.sql
   26          echo "order by column_id;" >> t1.sql
   27          echo "select 'from &tableName;'" >> t1.sql
   28          echo "from   sys.dual;" >> t1.sql
   29          echo "select 'spool off' from dual;" >> t1.sql
   30          echo "spool off" >> t1.sql
   31 
   32          sqlplus -S vep/rkaus60 < t1.sql
   33
   34          sqlplus -S vep/rkaus60 < t2.sql
   35  done

:
Posted by codetemplate
2006. 10. 30. 19:53

Mock Testing 개념 TDD2006. 10. 30. 19:53

(http://www.shinetech.com/display/www/What+Are+Mock+Objects%3F)


객체지향 프로그램에서 각 객체는 다른 객체들과 상호작용을 한다.
다음과 같은 그림으로 이를 표현할 수 있다.


Mock Object의 기본 사상은 객체를 unit test할 때 객체가 상호작용하는 collaborator들을 mock collaborator로 변경하는 것이다.


Stub과 다른 점은 아래와 같다.
Mock Objects test themselves
Mock 객체는 테스트 대상 객체에 의해 자신이 적절한 시기에 적절한 방식으로 호출되었는지 조사한다.
Stub은 일반적으로 stubbed data를 단순 반환한다.
Mock Objects are generally extremely lightweight
각 테스트에서 완전히 다른 Mock 인스턴스들이 설정되어야 하는 경우가 있다. Stub은 상대적으로 heavyweight로써 테스트에 재사용된다.
Mock 객체 사용을 위한 디자인 고려 사항은 아래와 같다.
Everything by Interfaces
Dependency Injection
객체의 collaborator는 객체에 전달 되어야 한다. 즉 객체는 자기 자신이 collaborator를 얻지 말아야 한다. 이러한 디자인 기법을 "dependency injection" 또는 "inversion or control"이라고 한다. 이 기법의 자세한 설명은 마틴 파울러의 기사(http://www.martinfowler.com/articles/injection.html)를 참고하기 바란다.

언제 Mock Object를 사용하는 것이 유용한가 ?
Mock의 가장 주요한 잇점은 collaborator를 mock으로 대체함으로써 collaborator 사용을 위해 필요할 수 있는 복잡한 상태 설정이 필요 없게 된다는 점이다.

예를 들어 XML에서 데이터를 가져와서 데이터베이스에 insert하는 비지니스 로직을 고려해 보자. 비지니스 로직을 테스트 할 때 개발자는 XML 파일, 데이터베이스 처리를 위한 복잡한 설정, 데이터베이스 테이블의 내용 조사 등의 작업을 하지 않기를 원할 것이다. 개발자가 원하는 것은 비지니스 로직이 XML 파서, 데이터베이스 계층과 올바로 상호작용하는지를 테스트 하는 것이다. 이러한 경우 개발자는  XML Parser, 데이터베이스 상호작용을 위한 인터페이스를 정의하고 Mock으로 대체함으로써 비지니스 로직만 테스트할 수 있게 된다.

주의할 점은 Mock Object는 unit test를 위한 도구이지 integration test, functional test를 위한 도구가 아니라는 점이다.

:
Posted by codetemplate
2006. 10. 30. 19:51

Eclipse에서 CVS 사용하기 2006. 10. 30. 19:51

Update

이 기능은 오랜 시간 다른 프로젝트를 수행했거나 휴가로 자리를 비워서 본인은 변경 사항을 가지고 있지 않지만 CVS Repository에 변경이 있을 가능성이 있을 때 수행하는 것이 적합하다.

이 기능을 수행하면 conflict이 없는 코드들에 대해서는 CVS가 자동으로 merge를 수행한다.

Synchronize with Repository

이 기능은 동일 소스 코드에서 2인 이상의 개발자 동시에 변경 commit을 수행하여 conflict이 발생하는 경우에 사용하는 기능이다.

간단한 예를 가지고 설명하도록 하자.

먼저 CVS에 초기에 아래와 같은 코드가 있었다고 가정하자.

   public class HelloWorld {
       public static void main(String[] args) {
           System.out.println("Hello, world!");
       }
   }

위의 코드를 개발자 A, B가 check out하였고, 개발자 B가 먼저 아래와 같이 변경한 후 commit(check in)을 했다고 가정하자.

   public class HelloWorld {
       private static final String HELLO = "Hello, world!";
   
       public static void main(String[] args) {
           System.out.println(HELLO);
       }
   }
   

마지막으로 개발자 A가 다음과 같이 변경하였다고 가정하자.

   public class HelloWorld {
       public static void main(String[] args) {
           say("Hello, world!");
       }
   
       public static void say(String msg) {
           System.out.println(msg);
       }
   }

개발자 A는 update, synchronize with repository 등을 수행하지 않고 바로 commit을 수행하려고 하면 아래 그림과 같이 충돌되는 요소로 인해 commit 오류가 발행했다는 윈도우를 만나게 된다.

Synchronize with Repository

충돌 요소를 해결하기 위해 project을 선택하고 오른쪽 마우스 버튼을 클릭하여 "Team / Synchronize with Repository ..."를 선택한다.

그러면 아래 그림과 같은 "Team Synchronizing" 윈도우가 나타난다.

Incoming changed from Repository 해결

Java Structure Compare에서 파란색 왼쪽 화살표(HELLO)는 repository에는 있지만 로컬 소스에 없는 부분을 나타낸다. 이러한 부분을 Incoming이라고 한다.
이러한 코드 블록은 단순히 repository에서 로컬로 복사만 하면 충돌을 제거할 수 있다.
아래 그림과 같이 Java Structure Compare에서 HELLO를 더블클릭한 후 파란색 사각형에 마우스를 가져가면

아래 그림과 같이 "<" 버튼이 나타난다. 이 버튼을 클릭하면 repository의 내용이 로컬 코드에 복사된다.

Conflicts 해결

빨간색 양쪽 화살표(main(String []))는 repository와 로컬 소스 간에 상충되는 부분이 있음을 나타낸다.
필요한 경우 이 화살표를 더블클릭한 후 로컬 소스에 수작업으로 수정을 가한다.

Outgoing changes to Repository 해결

검정색 오른쪽 화살표(say(String))는 로컬 소스에는 있지만 repository에는 없는 부분을 나타낸다.
이러한 로컬 소스가 repository에 추가되어야 하는 경우 로컬 소스를 수정 없이 나두면 된다.

Mark as Merged

마지막으로 충돌 문제가 해결되었으음을 설정하기 위해 아래와 같이 "Mark as Merged"를 실행한다.

Check In

아래 그림과 같이 commit을 수행하여 check in을 한다.

Creating and applying a patch

특정 사용자를 read-only로 설정할 수 있다. read-only 권한을 가진 사용자가 변경을 CVS에 적용하기 위해서 권한을 가진 사용자에게 변경 사항을 전송할 수 있도록 하기 위해 Eclipse는 patch(다수의 파일, 패키지에 대한 변경 사항을 담고 있는 파일)를 생성한다.

이러한 patch를 받은 사용자는 툴을 이용하여 patch를 review하고 변경을 적용한다.

project / Team / Create Patch를 통해 patch를 생성한다.

project / Team / Apply Patch를 통해 patch를 적용한다.

patch를 사용하는 것은 contributor가 CVS의 현재 코드 version을 가지고 작업을 했을 때 효과적이다. 만일 CVS의 version에 수정을 가한 파일에 patch를 적용하고자 한다면 CVS의 resolve하지 못하는 conflict을 만날 수도 있다. 이러한 경우 수작업으로 merge를 수행해야만 한다.

Versions and branches

CVS는 각 파일에 대한 revision history만을 저장할 수 있는 것은 아니다. CVS는 특정 시점의 Project에 대한 snapshot을 저장하기 위해 version을 제공한다. version을 생성했다면 후에 version 레이블을 이용하여 해당 시점의 project에 대한 snapshot을 얻어낼 수 있다.

CVS는 또한 각 파일에 대해 다수의 히스토리를 저장할 수 있다. 이러한 기능은 사용자가 project에 대한 branch를 생성하는 것을 허용한다. 이 말은 동시에 둘 이상의 개발 라인을 추가하는다는 것을 의미한다.

branch는 head branch에서 다음 version을 위한 개발이 진행 중일 때 이미 release된 version에 대한 유지보수(버그 수정 등)를 제공하기 위해 사용될 수 있다.

Adding a version label

project에 새로운 version 레이블을 추가하는 것은 각 파일들의 revision number를 하나의 프로젝트 레벨 레이블로 associate하는 것을 의미한다. \

개발에서 주요한 milestone(beta/official release, 대단한 변화를 가하기 전 등)이 있을 때 마다 project을 version 레이블로 태그해야 한다.

project에 version 레이블을 부여하기 위해 먼저 로컬 소스와 repository 간에 동기화가 이뤄졌는지 확인해야 한다. 또한 모든 변경이 commit되었는지 확인해야 한다.

아래와 같은 절차를 따라 version 레이블을 부여한다.

1. project을 오른쪽 마우스로 클릭 / Team / Tag as Version을 선택

2. 적합한 version 이름을 입력

Retrieving a version

아래와 같은 2가지 방법으로 version을 가져올 수 있다.

1. CVS Repository View에서 Project을 Check Out

2. Project이 이미 checked out되어 있다면 project의 context 메뉴에서 "Relace With / Another Branch or Version" 메뉴를 통해서

Creating and using a branch

branch는 version과 유사하다. 중요한 차이점은 개발자가 branch에 속한 파일들을 변경하고, 변경을 commit할 수 있다는 점이다. 물론 이러한 변경은 해당 branch를 바라보는 개발자들에게만 보여진다.

branch를 생성할 때 시작점은 워크스페이스의 현재 version이 된다. 이러한 version은 head도 될 수 있고, 이전에 태그된 version이 될 수도 있다.

아래와 같은 절차로 branch를 생성한다.

1. project context 메뉴에서 "Team / Branch"를 선택

2. branch 이름 입력(예. startList).

3. "Start working in the branch" 체크박스 선택 후 OK 클릭

Retrieving a branch

version을 가져오는 것과 동일한 방법으로 수행

:
Posted by codetemplate