2011. 5. 24. 18:43 IT
spring log level 변경

개발용으로 spring context를 매번 로딩하게 했더니 디버그성 로그 지나가는게 눈에 거슬렸다.

log4j.properties 파일에 다음과 같이 추가하여 레벨을 조정해주자
log4j.logger.org.springframework=WARN



posted by smplnote
2011. 5. 23. 21:52 IT
hellios 는 기존의 link 디렉토리 대신 dropins 를 제공한다.

내가 사용한 방식은 다음과 같다.

eclipse/dropins/myplugin.link

파일 내용은 아래와 같다. 주의할 점은 디렉토리 구분자가 항상 / 인것. 
path=f:/dev/myplugin

실제 플러그인이 위치하는 곳의 구조는 아래와 같다. 
(지정된 path 아래에 eclipse/plugins , eclipse/features 가 있으면 된다.)
f:/dev/myplugin/eclipse/plugins/xx.jar

posted by smplnote
2011. 5. 20. 10:33 IT
[증상] tomcat4.x 대 버전에서 특정 library를 추가할 경우 아래와 같은 메세지가 출력됨. Parse Error at line 6 column 19: Document root element "taglib", must match DOCTYPE root "null". [원인] 특정 라이브러리는 자체개발한 taglibrary를 사용하기위해 taglib 내용을 명세한 tld 파일을 jar 의 MANIFEST 경로 안에 포함하게 되는데 tomcat4.x 에서 사용하는 taglib dtd 버전과 library내에서 사용하는 taglibrary dtd 버전간 호환되지 않아 발생하는 문제임. [해결책] A) tomcat 5.x 대로 변경한다. 장점 : tomcat upgrade로 더 나은 세상을(?) 단점 : 4.x -> 5.x 변경 영향도를 고려해야 함. 또한 JDK 버전에 대한 영향도 검토도 필요. B) 라이브러리 내부의 tld 파일을 tomcat4.x 대 specification에 맞게 수정하여 다시 jar에 포함시킨다. 장점 : 기존 was 버전에 맞게 사용할 수 있다. 단점 : 신규 library의 기능이 정상적으로 동작하는지 검증할 필요가 있다. / 라이센스를 검토해야 한다. /* tomcat을 올려야 하는 당위성을 설명하는 과정이 귀찮아서 B)안으로 우선 처리함.... 그런데 벌써 두개의 라이브러리가 걸리고 있으므로 장기적으로 볼때 WAS 업그레이드가 권장사항임. */
posted by smplnote
2011. 3. 25. 14:18 IT

 

 

어제 Method & Tools Spring 2011 에서 Tomo Popovic 이 쓴
·Automated Acceptance Tests and Requirements Traceability" 란 글에서 Concordion 을 소개하는 내용이 있어서 한번 찾아보았습니다.
해당 글은 관심 있으시면 찾아보시구요..

흔히 인수 테스트 자동화 도구로 알려져 있는 것은 FIT, FITNesse 입니다.
Html, 워드, 엑셀로 작성해서 사용자와 커뮤니케이션 하는데 도움이 된다... 고 주장합니다.
(NHN에서 위의 것들을 조합해서 NTAF 를 만들기도 했죠.)

간단하게 Concordion을 소개하면, ( http://concordion.org/ ) APL 2.0 라이센스로
JUnit과 통합되어 있고, 가독성 높은 인수테스트를 작성하도록 지원하는 인수테스트 자동화 도구입니다.

왜 Fit, FitNesse가 있는데 만들었냐가 중요할텐데요.
문서의 가독성을 높이고, Fixture code(테스트용코드) 가 덜 복잡해지고,
JUnit 방식으로 실행되게 했다고 합니다. (따라서 CI 서버와 통합이 용이)
특히 wiki는 오히려 설정도 번거롭고, 버전관리가 빈약하다고 지적하고 있군요..
( 자세히는 http://concordion.org/Questions.html#comparisonWithFit )

문서가독성(script/구현독립성) 측면에서 아래 FitNess와 비교하기도 합니다.
http://concordion.org/ScriptingMakeover.html
 
Spec 문서와 동일한 개념으로 사용할 수 있다고 주장하는데...

 
개인적으로는 SI 보다는 PKG성 제품에 보다 효과가 높을 것으로 보입니다.
그리고 FitNesse 보다는 확실히 깔끔해보이네요.
 

아래는 테스트해본 화면 캡쳐입니다. (일부러 fail을 냈습니다. )

 

concordion_sample.png

 

HelloWorldTest.java

HelloWorld.html

Greeter.java

Result.java

 

cf) spec 문서인 html 파일에서 한글을 사용할 경우 다음 메타 태그를 추가할것

  1. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

이 글은 스프링노트에서 작성되었습니다.

posted by smplnote
2010. 8. 27. 13:42 IT

 

프로젝트에서 다소 한가한 시간이라서 평소 생각만 하던 grails를 만들어보기로 했다.

작은 목표는 커뮤니케이션 포탈을 만들어보는것. (게으른 내게는 큰 목표다... )

 

  1. 설치
    두가지 방법이 있다. STS 를 설치하여 IDE환경에서 작업하는 것과, 콘솔에서 작업하는 방식

    • STS 설치방식
      - Java SDK 1.5+ 설치여부를 확인. (없으면 먼저 설치.. )
      - STS를 다운로드 한다. 주1)
      - 설치후 dashboard 화면에서 extensions tab 선택후
      Grails support, Groovy Eclipse 를 체크한다. (grails 는 뭔지 모르겠다.. 같이 설치했다.)
      - 설치후 리스타팅 하면 완료
      참고 : http://www.grails.org/STS+Integration
    • 콘솔 설치

      다운로드 사이트에서 grails를 다운로드 http://www.grails.org/Download

      환경변수 셋팅

      1. java home setting Java SDK 1.5+
        set JAVA_HOME=C:\Program Files\Java\jdk1.5.0
        # 설치위치 ( unix면 \대신 / )
        set GRAILS_HOME=c:\grails-1.3.4
        set PATH=%PATH%;%GRAILS_HOME%\bin
  2.  

  3.  GRAILS 프로젝트 만들기

    • STS에서 
      File > New > Grails Project  ... Done!
    • 콘솔에서
      >grails create-app my-project    ... Done!
  4.  도메인 클래스 만들기

    • STS에서
      Grails console을 open 주2)
      >create-domain-class speaker
    • 콘솔에서
      >grails create-domain-class speaker

      1. // Speaker.groovy 편집 
        package my.project
      2. class Speaker {
          String name
          String title
          String company

            static constraints = {
           name(maxSize:20)
           title(maxSize:50)
            }
        }
    • grails domain 설정
  5. 콘트롤러 클래스 만들기
    • STS에서
      Grails console을 open
      >create-controller my.project.Speaker
    • 콘솔에서
      >grails create-controller my.project.Speaker주3)
    • grails controller 설정 
  6.  실행
    • STS에서
      프로젝트에서 context menu > run as > grails command(run-app)
    • 콘솔에서
      >grails run-app

      cf) 실행시 hostname이 한글인 경우 ehcache에서 UnknownHostException 을 발생시키는데 기동에는 문제가 없다.

  7.  scaffodling template customizing

    1. 먼저 scaffolding template 을 사이트에 적절하게 변경하는 작업을 수행하는 것이 유용하다.
      커맨드 창 또는 grails 콘솔에서
      >grails install-templates 를 실행한다.
      그러면 src/templates 에 모든 템플릿 파일들이 생성된다.
    2.  해당 파일들에 대해 default 값들을 수정하여 사용하면 유용 ( 표준 주석 등도 만들어 두면 good.. )
  8.  JSP에서 gsp의 TLD 사용하기

    1. 최상단에 <%@ taglib prefix="g" uri="/WEB-INF/tld/grails.tld" %> 추가 
  9.  grails 설정

    grails -Dserver.port=9000 run-app
    

 http://www.tipstrs.com/tip/12727/Changing-the-port-of-a-Grails-project

 

jquery : grails install-plugin jquery
http://grails.org/plugin/jquery


주1) 현재 2.3.2가 release 된 상태다. http://www.springsource.com/products/springsource-tool-suite-download
주2) 단축키 Ctrl+Shift+Alt+G 또는 메뉴에서 Navigate > open Grails command prompt

주3) 다시 실행하는 경우 덮어쓸지 물어본다.

참고 사이트
http://www.howardism.org/Technical/Groovy/Grails_Advice.html

http://grailstutorials.com/tutorial

http://greatkim91.tistory.com/

이 글은 스프링노트에서 작성되었습니다.

posted by smplnote
2010. 8. 19. 14:00 IT

 

  • 작성일, 변경일 자동 생성
    아래와 같이 도메인 클래스에 필드를 추가하면 별도의 코딩없이 grails가 알아서 생성시, 갱신시 필드를 변경해준다.
    Class MyDomainClass {
       Date dateCreated = new Date(); 
       Date lastUpdated = new Date(); 

       // if db field name not same. (DB 필드명을 다르게 가져갈 경우는 아래처럼 매핑을 작성한다.)
       static mapping = {
          dateCreated column: "WRITTEN_DATE"
          lastUpdated column: "CHANGE_DT"
       }
    }
  •  물리테이블명 매핑
    Class MyDomainClass {
       ....
       static mapping = {
          table "CM_BOARD" // MyDomainClass 는 테이블 CM_BOARD 와 연결된다.
       }
    }
  •  버전 컬럼 제거하기
    grails domain에 자동 생성되는 version field 를 사용하지 않는 경우.
    class MyDomainClass {
       static mapping = {
          version false
       }
  • SQL Type 명시하기
    varchar(256) 이상의 size를 지정하기 원하거나... 특정 타입으로 매핑하고 싶을때.
    1) mapping sqlType 사용하기
    Class MyDomainClass {
       static mapping = {
          title sqlType: "varchar(5000)"
       }
    }
    2) constraints size 사용하기
    Class MyDomainClass {
       static constraints = {
          title(size:1..5000,blank:false)  // grails가 알아서 sqlType을 변형해준다.
       }
    }

이 글은 스프링노트에서 작성되었습니다.

posted by smplnote
2010. 8. 19. 13:24 IT

 

Config.groovy

- context root 를 / 로 바꾸기 
from  http://dogfeet.tistory.com/87
grails.app.context = "/"

 

DataSource.groovy
- hostname이 한글인 경우 hibernate 설정이 실행될때 오류가 발생한다. 조치방법은 hibernate 관련 설정을 주석처리

- memory db 에서 file DB로 변경하기 
        dataSource {
            dbCreate = "update" // 그래야 삭제가 안됨
            url = "jdbc:hsqldb:file:db/devDB" // file type, dbfile path (프로젝트 위치에 생성됨)
       }

- jndiName 사용하기 
  dataSource {
        jndiName = "java:comp/env/myDataSource"
  }

 

- sql logging 시
        dataSource {
               loggingSql = true
        }

이 글은 스프링노트에서 작성되었습니다.

posted by smplnote
2010. 7. 29. 17:10 IT

 

업무중 해당 이슈를 해결하라는 요청이 들어와서 이틀간 웹서핑을 했다.

 

이슈를 요약하자면,
IE8부터는 예전과 달리 명시적으로 "새로운 세션"으로 창을  띄우지 않는 한,
모든 창과 탭이 동일한 세션을 공유할 수 있다.
따라서 이용자가 로그아웃을 하지 않고 창만 닫은 경우, 여전히 세션이 남아있어
다른 사용자가 기존의 세션 정보를 이용하여 악용할 소지가 있다.

 

클라이언트 측에서 세션을 공유하지 않도록 하는 해결 방법은 많이 알려져 있다.

  1. 사이트에서 제공하는 로그아웃 버튼을 이용하여 명시적으로 종료하여 세션을 끝낸다.
  2. 파일메뉴에서 New Session 을 선택하여 새로운 세션으로 시작한다.
  3. iexplore.exe 실행시 인자로 -noframemerging  를 추가하여 실행시킨다. (-nomerge 옵션은 Deprecated 됨)
  4.  Registry key 수정 : HKCU\Software\Microsoft\Internet Explorer\Main\FrameMerging
    0 - disable frame merging , 1 – enable (default)

 

그럼 서버측은?

찾아본 자료는 세가지 방법을 설명하고 있었다.
1. 클라이언트 웹 세션 관리기법 : 특정 프레임에 로그인시 인자값을 할당하여 해당 인자값 유무를 체크 -> 복수프레임일 경우에만 적용 가능
2. 보안세션을 파라미터로 관리 : 보안세션에 사용되는 세션 키 값을 페이지 이동시마다 파라미터로 전달 -> 단일프레임일 경우에 적용가능, 세션키 암호화 필요 , 세션관리방식 변경이 필요함
(웹 세션 키는 쿠키로, 보안세션키는 request parameter로 전달하여 관리)
3. 보안모듈을 이용하여 프로세스 추적/제어 -> 완벽한 추적은 불가능함 , 보안모듈 개발 추가비용 발생, 장애 RISK

내가 적용한 방식은 1)과 유사한데, 프레임이 필요하지는 않다.

아이디어는 IE에서 제공하는 DOM Storage에서 시작한다.
single tab의 lifetime 을 따르는 window.sessionStorage 를 활용하기로 했다.
흐름을 기술하자면 아래와 같다.

1. 로그인 시점에 sessionStorage 를 저장한다. (로그인 후)
2. 로그인 체크가 필요한 모든 페이지 내에서 sessionStorage를 체크한다.
3. 만약 sessionStorage 정보가 없는데도 서버세션이 있다면, 다른 탭이거나, 새창이라고 판단하여
세션정보를 제거하고, 최초페이지로 이동한다.
cf) 팝업의 경우에는 적용하기 어렵다....
cf) 단점은... 기존 창까지 세션아웃된다는거. (물론 피할 수도 있겠지만, 귀찮아서 패스.. )

  1. // 로그인 시 저장하기
  2. if(navigator.userAgent.indexOf("MSIE 8") == 25 ){
  3. sessionStorage.login = "lepffm";
  4. }
  5.  
  6. // 로그인후 체크하기
    if(session!=null){부가기능
  7. if(navigator.userAgent.indexOf("MSIE 8") == 25 ){
  8. if(sessionStorage.login == null){
  9. document.execCommand("ClearAuthenticationCache",false);
  10. top.document.location.href = '/';
  11. }
  12. }
  13. }

 

참고사이트
http://blogs.msdn.com/b/ie/archive/2009/05/06/session-cookies-sessionstorage-and-ie8.aspx
http://msdn.microsoft.com/en-us/library/ee330728(VS.85).aspx
http://msdn.microsoft.com/en-us/library/cc197062(v=VS.85).aspx
http://byung.egloos.com/4970548

 

이 글은 스프링노트에서 작성되었습니다.

posted by smplnote
2010. 7. 21. 13:16 IT

 

웹페이지 속도측정 작업의 교훈

속도측정에 쓰이는 비슷비슷한 툴은 많다
하지만 적절한 툴을 찾기는 어렵다.
브라우저에 플러그인 된 경우 사용하기 편리한 점은 있으나 가장 보편적인 브라우저(IE)를 지원해야 제대로 활용이 가능하다.
각 정보의 의미를 정확하게 이해해야 한다.
특정 회수 이상 수행하여 평균값을 사용하고 목표를 정하여 멈출 시점을 정하자 
주요지표 
총시간
서버시간
렌더링시간
요청수
데이터양
문제점 진단 
- 서버냐 리소스냐
- 정말 느린가 (as-is) 비교
- 무엇으 개선할 것인가 : 302 expire gzip text? 개선 대상 선정

이 글은 스프링노트에서 작성되었습니다.

posted by smplnote
2010. 7. 20. 17:59 IT

 

고객이 웹사이트가 느리다고 불평하는 바람에
웹화면 성능 측정을 하면서 알게된 것.

 

실제 서버 시간은 그리 많지 않은데 왠 이미지는 그리도 많이 붙여놓았는지..
무수히 많은 304 메세지들.

304는 "Not Modified" 즉 변경사항이 없으므로 웹서버에서 다시 다운 받을 필요없다는 서버의 메세지다. 이경우 서버로부터의 실제 data 다운로드는 일어나지 않는다.

하지만 자주 변경되지 않는 데이터를 가지고
애초에 서버에게 물어보는 행위 자체가 불필요한거 아닌가...
그래서 서버에 물어보지 않도록  Expire 정보를 명시하기로 했다.
여러 게시글에서 추천하는 사항이다.

 

어디서 설정하나.. 한참을 헤멨지만.
수정할 파일 : %web_app_home%/config/obj.conf

  1. <Object ppath="/a/b/c/img/*">
  2. PathCheck fn="set-cache-control" control="max-age=86400"
  3. </Object>

 물론 전체를 잡아도 될거지만 내경우에는 img, css, js, htm 등만 대상으로 했다.

서버 stop 후 다시 start ...

max-age를 왜 하루로 잡았냐구? 지금은 테스트 기간이라서 자주 바뀔 소지가 있다.

 

이제 좀더 빠른 속도를 체감할 수 있다.

 

참고자료
http://blogs.sun.com/walter/entry/how_to_add_expires_header

 http://www.mnot.net/cache_docs/

http://whiteship.me/2465

 

이 글은 스프링노트에서 작성되었습니다.

posted by smplnote