달력

8

« 2019/8 »

  •  
  •  
  •  
  •  
  • 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

스프링 프레임크를 사용하기 시작한지는, 만 5년 정도 된것 같다. 아니 정확하게 이야기하면 알기 시작한지 5년이다. 그 동안 몇개의 프로젝트에는 적극적으로 사용해왔고, 사용하려고 했었다.

솔루션을 위한 내부의 기반 프레임워크를 개발하기에도, 그 자체만으로도 스프링은 너무 훌륭하기 때문에, Application의 공통 부분을 위한 기능들만을 최적화하고, 정의하는 것 만으로도 노력대비 좋은 결과들을 낼수 있었다. 다 로드존슨 아저씨가 많은 시간을 들여서 갈고 닦고, 발전시킨 노력의 결과들이다.

시간이 흐를수록 큰 조직에서는 코드와 PC와 씨름하기 보다는 수 많은 회의와 씨름을 하는 일이 많아진다. 더군다나 같이 협업하는 사람들이 많아지면, 본인이 원치 않아도 관리자의 길에서 뛰고 있는 모습을 보게된다. 딱 지금의 나의 모습니다.

공부하지 않고, 적절하게 판단하고 선택하고 방향에 대해서 이야기 할 수 있을까?
많은 고민을 하지만, 역시 시간이 절대적으로 부족하다.

요즘은 코드를 보기가 힘들정도로, 공부할 여유가 별로없다.
하지만, 사둔 책이 아깝다는 이유이든, 공부의 재미를 알았다는 이유이든 개발자로 살아가는 한은
꾸준히 배워야한다.

스프링 3.1은 또 다른 변호들을 이야기 할지는 모르겠다. 이전에 책을 보면서 정리한 내용인데 일단 올려놓는다.

[Spring Framework 3.0 - MVC]

·         스프링은 DespatcherServlet 7개의 Strategy를 기반한 MVC 프레임워크를 제공한다.

·         이중 DespatcherServlet는 가장 기본적이면서도 SpringMVC의 필수적인 기본 Servlet 역할과 스프링의 특징중의 하나인 Light-weight 컨테이너의 역할을 수행한다.

 

1.     @RequestMapping 핸들러 매핑

o    @MVC는 메소드 레벨에서 컨트롤러를 작성할 수 있다.

o    Annotation은 타입(클래스, 인터페이스)레벨뿐 아니라 메소드 레벨에도 적용 가능함.

o    @MVC 핸들러 매핑을 위해서는 DefaultAnnotationHandlerMapping이 필요하다.

o    DefaultAnnotationHandlerMapping은 기본 핸들러 이므로 다른 Handler Mapping bean이 명시적으로 등록이 되지 않았다면, 기본으로 사용이 가능하다.

o    만약, 다른 핸들러 매핑 빈이 등록이 되었다면, DefaultAnnotationHandlerMapping
명시적으로 등록을 해주어야 사용이 가능하다.

2.     Class/Method 결합 Mapping 정보

o    DefaultAnnotationHandlerMapping

·         @RequestMapping 애노테이션을 활용해서 타입레벨과 메소드 레벨 지원하며
타입레벨을 기본으로 삼고, 메소드 레벨의 어노테이션 정보는 타입레벨의 매핑을 세분화 하는데 사용한다.

o    @RequestMapping Annotation

·         Spring[] value(): URL 패턴

1.     String 배열 타입으로 URL 패턴을 지정해서 사용

2.     URL 패턴은 ANT 스타일과 와일드카드를 사용이 가능하다.

·         @RequestMapping("/hellow")

·         @RequestMapping("/admin/**/user")

·         @RequestMapping("/hellow", "/hi")

3.     "{ }"를 사용할때는, "{ }"의 위치에 해당하는 내용을 컨트롤러 Method에서 파라메터로 전달받을 수 있다. "{ }"에 들어가는 변수를 "path variable"이라고 부른다.

·         @RequestMapping("/user/{userid}")

·         RequestMethoe{} method(): HTTP Request Method

1.     Request Method GET, HEAD, POST, PUT, DELET, OPTIONS, TRACE 7개의 HTTP 메소드가 정의되어 있다

2.     HTTP 메소드를 추가하면 요청 메소드에 따라 다른 메소드를 매핑해 줄 수 있다.

·         @RequestMapping(value="/user/add", method=RequestMethod.GET)

3.     정의된 메소드 이외의 사용시 "HTTP 405 - Method Not Allowed"를 받음.

4.     타입레벨에서 URL을 주고 HTTP 요청 메소드를 지정할 경우 URL 생략가능.

·         @RequestMapping(method=RequestMethod.GET)

·         String[] params(): Request Parameter

1.     이것은 요청 Parameter와 그 값을 비교해서 매핑해 주는 것이다.

2.     같은 URL을 사용하지만, Parameter값에 따라 다른 작업을 할 때 사용한다.

·         @RequestMapping(value="/user/edit", params="type=admin")

3.     특정 Parameter 값이 존재하지 않아야 한다는 조건을 둘 경우 사용

·         @RequestMapping(value="/user/edit", params="!type")

·         String[] header(): HTTP 헤더

1.     Header 정보에 따라 매핑이 가능하다.

·         @RequestMapping(value="/view", headers = "content-type="text/*")

 

o    Type level 매핑과 Method level 매핑의 결합

·   타입(클래스오 인터페이스)레벨에 붙는 @RequestMapping은 타입내의 모든 매핑용 메소드의 공통 조건을 지정할대 사용한다.

·   메소드 레벨의 매핑은 클래스 레벨의 매핑을 상속한다.

      1. 컨트롤러가 각각 /user/add, /user/edit, /user/delete URL에 매핑

@RequestMapping("/user")

public class UserController{

@RequestMapping("/add") public String add(){ }

@RequestMapping("/edit") public String edit(){ }

@RequestMapping("/delete") public String delete(){ }

}

2.     타입 레벨의 URL패턴에 * **를 사용하여 매핑 가능

·         /user/*

·         /user/**  

·         타입레벨에서 공통의 매핑을 정의하고, 메소드 별로 세분화 해서 사용

 

o    Method 레벨 단독 매핑

·   공통 매핑 조건이 없을 경우, 조건을 주지 않고 메소드 레벨에 정의해서 사용.

·   이렇게 정의하지 않는다면, 클래스 자체가 매핑이 되지 않는다.

·   만약, @Controller 애노테이션을 붙여서 자동 빈 스캔을 사용할 경우는, 클래스 레벨의 @RequestMapping을 생략할 수 있다.

o    Type 레밸 단독 매핑

·   클래스 레벨의 URL 패턴이 /*로 끝나는 경우, apthem 레벨의 URL 패턴으로 메소드 이름을 사용할 수 있음.

·   아래는 /user/add /user/edit 로 각각 매핑

@RequestMapping("/user/*")

Public class UserController {

@RequestMapping public String add( ) { }

@RequestMapping public String edit( ) { }

}

 

 

 

 

 

Posted by 행복상자
[정말 나의 게으름으로 글 하나가 또 묻혀져 있었다.]
[지난 번의 1번글을 비슷한 시기에 쓰고, 연달아 정리하려고 했는데]
[또 다시, 뒤 늦게 글을 올리게 되었다. 미안하고 죄송하고, 부끄럽다.] 


 트위터의 API를 사용하기 위해서 필요한 내용들을 간략하게 정리해 봤다. 세부 내용들과 참고해야할 항목들도 정리했는데, 이전 기억을 살리기 보다는 FQA를 이용해서 접근하였다. 따라서 필요한 내용들은 Twitter의 개발자 가이드와 웹 사이트를 이용해서 확인 가능하다.
 
간략하게 정리하였지만, 기본적인 API들에 대한 지원은 Twitter에서 라기보다는 이를 이용한 Wraper 클래스들은 우리의 선배 또는 휼륭한 다른 개발자 들이 이미 개발하여 놓았다. 이를 잘 활용하는 것은 또 다른 문제이고, 다른 영역이라 생각하지만, 자신에 맞는 언어와 라이브러리를 잘 찾아 쓰는 것은 시행착오와 시간을 줄여주는 활동이다.

웹사이트에는 Web site를 위해서 Twitter에서 제공되는 기능들도 설명되어져 있다. (나의 관심사와는 좀 거리가 있어서, 생략...)



[Twitter API 이용하기]
 
  1. Developer document를 읽어봐야 한다.
    • Developer Guide 어떤 Framework 가지고 개발하더라고 반드시 읽어야 기본 문서이다.
  1. Twitter Libraries
    • Twitter 사용해서 List 가져오거나 Oauth 위한 라이브러리들은 아래에 정리되어 있다. 아래 링크를 참조해서 사용하고 있는 또는 필요로 하는 라이브러리를 사용하면 된다. (현재는 13 언어에서 지원하고 있다.)
  1. Twitter Character 140자로 정해져 있다.
  1. REST API 버전 정보는 현재 version 1 되어 있다.
  1. Twitter API 사용하기
    • Open Api 사용할 앱을 등록한다. (아래의 링크에서 등록)
      • Application Name Unique 해야 된다.
      • 작년(2010) OAuth 방식으로 바뀐 이후에, ID/Password 방식이 아니라, 인증키를 얻어야 사용이 가능하다.
  1. Twitter API 사용 제한
    • 인증 방식에 따라 다양하게 사용량이 정의되어 있다.
      • Unauthenticated call: 150 requests/hour
      • OAuth call: 350 requests/hour
    • 유휴하지 않은 OAuth 정보를 포함하게 되면,
      • 인증 받은 메소드: 에러 response 반환한다. (with HTTP 401 error)
      • 인증 받은 메소드: 다음과 같은 헤더 정보를 포함된 Response 받게 된다. 인증 받지 않았기 때문에, API 호출 제한은 Unauthenticated call 따른다.
        • X-Warning: Invalid OAuth credentials detected
      • HTTP GET commend 요청한 메소드들은 사용량의 제약을 받으나, POST commend 제약이 없다.(아래 문서 참조)

 

  • API 사용 제한량 알기
    • REST API 사용 제약에 도달하면, HTTP 400 Response code 받게 된다.
    • Search 또는 Streaming API 사용량이 한계치에 도달할 경우는 HTTP 420 response code 반환한다.

 

  • Search API 사용량 제한
    • REST API 제한이 없다. (그러나, 제약을 위해서 모든 요청은 IP 단위로 관리된다.)
    • 사용량이 한계치 도달 , HTTP 420 response code 받는다.


'공부하는 것 > Twitter API & Twitter4j' 카테고리의 다른 글

Twitter REST API (2)  (0) 2011.10.24
Twitter REST API (1)  (0) 2011.09.14
Posted by 행복상자
아주 오래전, 사실은 몇 년전(3~4년전?)인것 같다. 
Twitter를 처음 사용하면서, Twitter의 Open API와 정책들을 살펴보다가, Twitter4J라는 Twitter API를 자바에서 쉽게 사용할 수 있는 라이브러리를 접했었다.
그 당시 몇개의 Library를 검토하다가, 일본인이 만들었더 Twitter4J가 여러가지로 사용하기도 쉽고 적합하다고 판단했었는데, 최근에 개인적으로 다시 살펴볼 일이 있어서, 다시 코드를 분석하게 되었는데, 내가 이전에 기억하던 코드와 전혀 다른 코드들로 구성되어 있었다.

클라스와 메스드들은 모두 Interface로 정의하고, 이를 구현하도록 Class 들이 Re-factoring 되어져 있었다.
코드들도 깔끔하게 정리되어 있고, 정비되어져 있었고, 예제들도 모두 셈플 소스코드를 포함해서 기능별로 나주어져 있었다. (지난 몇년동안 개발자가 많은 노력과 수고를 했던것을 볼수 있었다. 고맙네...) 

아마도, 추측컨데 Twitter4J가 지원하는 플랫폼들이 다양화되면서, 인터페이스와 구현 클래스로 재 구성을 한것으로 보인다. 프레임워크의 패키지 구성을 보면, Google App Engine와 Android 단말을 지원하기 위해서 자바 Package등으로 나누어져 있다.

이를 분석하기 위해서는 먼저 Twitter의 REST API 정책을 다시 한번 살펴 볼 필요가 있다. 지난 2년동안 여러가지 정책이 바뀌고 새로운 기능들이 추가 되었을 것으로 보인다.
전체를 다 살펴보기는 힘들것이고, 개발자 가이드 먼저 살펴 봐야 겠다.


 

'공부하는 것 > Twitter API & Twitter4j' 카테고리의 다른 글

Twitter REST API (2)  (0) 2011.10.24
Twitter REST API (1)  (0) 2011.09.14
Posted by 행복상자
2011.09.10 09:28

GRails 대한 나의 생각... 공부하는 것/GRails2011.09.10 09:28

내가 RubyOnRails를 처음 알게된 것도 괘 오래전 이었던 것 같다.
2008년 이후로, ROR을 비롯해서, RedRails와 JRuby, Groovy를 개인적인 흥미로 인해서 설치해 보고 사용해 보기도 했지만, 그렇게 오래가지는 않았던 것 같다.

 왜냐하면, 내가 주로 하고 있는 업무는 JAVA 기반의 서비스이다보니, JAVA Virtual Machine위에서 동작해야 하고, 이를 보다 효율적인 측면에서 활용하기 싶었기 때문에, ROR을 직접 이용하기 보다는 다르지만 같은 환경에서 이용해 보고 싶었기 때문이다.

ROR의 쉽고 빠른 개발을 내가 하고 있는 프로젝트에 적용을 한다면, 생산성의 향상과 직관적인 관리를 통해서 보다 효과적이고 효율적으로 프로젝트를 진행할 수 있다고 생각했기 때문이다. (사실은 개발 시간을 줄여서 개발자들이 편해질까하는 순수한 의도와 흥미도 있었다.)
그러나, 개인적인 프로젝트라면 모를까, 팀 프로젝트와 실 운영을 위한 프로젝트 적용에는 많은 어려움들이 수반되고, 안정화와 검증되지 않은 부분에 대한 책임등을 고려할 때, 적용이 쉽지 않았기 때문에 프로젝트에서는 사용하지 못했었다.

GRails를 처음 접하게 된것은 2009년 상반기 였던것 같은데, ROR과 JRuby와 비교하면 굉장히 앞선 무엇이 있다라고 생각하지 않고, 또하나의 메이져는 아니지만, "흥미로운 프로젝트가 또 하나 나왔구나"라는 생각뿐, 큰 감흥은 없었던 프로젝트 였다.

그러가다, SpringSource에서 개발하고 있는 Eclipse기반의 개발툴인 Spring Tool Suite을 사용하다 보니, 
Grails와 Groovy를 쉽게 플러그인으로 설치할 수 있도록 되어 있어서, 설치해서 사용해 보게 되었는데, ROR과 같이 자동으로 Scaffolding해주고, Springframework를 사용할 수 있도록 해주고, groovy 대신에 java를 사용할 수 있다는 것이 마음에 들었다.
 

그리고, 기본 내장되어 있는 in-memory DB인 Hbase와 Tomcat를 통해서 Grails 프로젝트 생성과 동시에, Deploy해서 테스트 할 수 있는 환경이 바로 제공된다는 것이 무척 마음에 들었었다.

단, 새로운 파일들의 생성과 빌드를 위해서 HDD의 I/O가 많아서 불필요한 시간이 든다는 점과, Plug-in간의 
Dependency에 대한 문제가 있어서 인지, 일부 플러그인은 정상적으로 업데이트가 안되곤 했다.
특히, STS를 이용할 경우는 여러가지 편리한 점이 많지만, STS에 대한 Dependency로 인한 Plug-in의 업데이트가 정상적으로 진행되지 않았기 때문에, 문제점 해결에 많은 시간을 보내곤 했다.

그러다가, STS 2.7 버전이 나오면서, 기존에 2.5와 2.6버전에서 가지고 있던 Dependency 문제를 어는 정도 해결해 주었는데, 이직도 Plugin에 대한 Dependency문제가 있다. 특히, Hibernate와 Tomcat은 기본 프로그인으로 설치시 포함되어 있지만, Google App Engine SDK 설치를 위해시, 이들 플로그인들이 정상적으로 제거되지 않는 문제들을 가지고 있고, STS를 종료하고, 수동으로 삭제해주어야 한다.
 

사실, 이는 Grails의 문제가 아니라, STS와 윈도우즈7간의 권한의 취득에 대한 것이므로, 직접적인 책임은 없으나, 제대로된 IDE의 지원은 절실하다.

GRails는 STS의 지원 없이도 사용이 가능하지만, IDE를 이용하는 것은 생산성을 위해서 이기 때문에, 이를 이용하는 것이 사용하지 않는 것보다 이득이 크다.
Ggrils를 통한 개발에서 STS를 이용하지 않는 다는 것은 굉장히 불편한 길을 찾아서 걷는다라는 기분이 든다. 자바 개발에서 사용하던 라이브러리들도 그대로 이용이 가능하므로, 자바로 개발하던 개발자에게는 추가로 개발을 위해서 들여야 하는 학습 시간을 많이 필요로 하지 않기 때문에 이전에 Eclipse를 사용하던 개발자라면, STS를 설치하지 않고, Plug-in 만 설치해서 개발이 가능하다.
하지만, 나는 개인적으로 Eclipse를 설치하는 것보다는 STS를 설치하는 것이 낫다고 생각한다.

올 10월 정도에는 GRails 2.0이 새로 나온다.
여러가지 다양한 Featuer들의 변화가 였보이는데, 어제인가 보니 Grails 2.0 M2버전이 Release 가 되었던 것 같다.
 



 
Posted by 행복상자
Spring Tool Suite는 Eclipse기반의 Java 개발 환경 툴로, Spring Framework로 유명한 Spring Source사에서 제작 배포를 하고 있다. STS를 사용하는 이유는 자동화된 환경을 통해서 필수적인 부가 Plug-in의 설치가 쉽고, Grails와 스프링 프레임워크의 구성이 쉽기 때문이다.

최근까지도 Eclipse 3.6 기반의 STS 2.5.2를 설치한 이후로 자동 업그레이트롤 통해서 STS 2.7.1을 사용했는데, Eclipse 3.7기반의 STS 2.7.1을 설치하고, Grails 1.3.7을 설치하기로 하였다.
사실, STS 2.5.0은 Plug-In의 업그레이드 기능에 문제가 있어서, Grails Plug-in들과 번들의 설치가 안되는 이슈가 있었는데, 2.5.2 버전에서는 이러한 문제가 해결되어서 업그레이드를 하거나 다시 설치할 필요성을 느끼지 못했었다.  

간략히 설치 방법과 순서에 대해서 설명을 하면, 
http://www.springsource.com/ 로 웹브라우저를 통해서 이동을 하며 화면 하단에 아래 이미지와 같은 화면이 보일 것이다. 여기서 SpringSoruce Tool Suite를 클릭해 주거나,
직접 브라우저에서 http://www.springsource.com/downloads/sts 로 이동해서 다운을 받아도 된다.

■ Spring Tool Suite 다운로드


이번에 설치할 버전은 Eclipse 3.7 기반으로 구성되어져 있고, STS 2.7.1 버전이다.
다운로드 사이트로 이동하면, 아래와 같은 화면이 나오는데, 운영 환경에 맞추어서 설치를 하면 되다.
(화면에는 표시되지 않았는데, 하단에 다른 버전들오 이동할수 있는 링크가 있다.)
 

■ STS 설치
다운로드해서 압축을 풀고, 원하는 경로에 옮겨높고 JAVA SDK의 경로(PATH)를 설정하면 설치는 마무리된다. (다 알고 있다고 생각하기에 별도 설명은 하지 않는다.)

■ STS 실행
STS를 실행하기 위해서는 "설치경로/springsource/sts-2.7.1.RELEASE/sts.exe"를 실행해주면 된다.

■ Groovy와 Grails 설치
실행후 나타나는 dashboard를 하단을 보면 두개의 tab이 있다. 하나는 dashboard 텝이고 하나는 Extensions이라는 템이다. Extensions 탭은 개발에 필요한 Plug-in 들을 쉽게 설치하도록 도와 준다.

여기서는 Grails, Grails Support 그리고 Groovy Elipse를 설치할 예정이다.
아래와 같이 선택하고 하단 오른쪽에 있는 "Install" 버튼을 눌러서 설치츨 진행하면 된다.


설치한 플러그인들에 대한 설치에 대한 진행 화면이 아래와 같이 나오면, "Next"버튼을 눌러 설치를 진행하면 된다.


설치가 완료되면, STS를 재 시작을 해주어야 한다.

재 시작이 되면, Grails프로젝트를 시작할 수 있을 것이다.




Posted by 행복상자
2009.10.20 06:36

Byte and Bit에 대해서... 공부하는 것2009.10.20 06:36

최근에 지인과 같이 아야기 하다가, 이 기종시스템의 포팅에 대한 이야기가 나왔는데, 그 때 그 친구가 Byte에 대한 정확한 의미를 알지 못하면, 낭패를 볼수 있다는 말을 하였다.
나는 내 기억을 근거로 단지 1 Byte면 8 bit가 아니냐? 그런데 왜 어렵지? 라고 반문하였다.
그 친구는 1 Byte의 단위가 시스템마다 전혀 다른 의미로 사용 될 수도 있다는 것이었는데, 예전의 오래전 기억을 더듬으면서, 그런것도 같고 아닌것도 같고 확신은 하지 못했다. 그리고 나서 나에게 메일로 이에 대해 바로 알수 있도록 위키의 링크를 보내 주었다.

이에 대해서 간략하게 설명하면 다음과 같다.
한국 위키디피아 사이트에서 Byte로 검색을 하거나 "http://ko.wikipedia.org/wiki/바이트"로 링크를 찾아가면, 바이트에 정의에 대해서 다음과 같이 설명하고 있다.

일정한 개수의 비트로 이루어진 연속된 비트열. ‘일정한 개수’가 항상 정해진 건 아니지만, 최근에는 사실상 1바이트를 8비트로 간주하는 경우가 흔하다.

위에서와 같이 연속된 bit열를 Byte의 단위로 사용하는데, CDC 6000계열의 메인프레임은 6bit를 1 Byte로 사용하고 있으면, CDC의 경우 12bit를 1Byte로 부르기로 했다는 것이다.
최근에는 대부분 8bit를 1 Byte로 이용하고 있지만, 6bit, 7bit, 12bit가 1 Byte로 이용되고 있다.

여기까지는 한국 위키디피아에 정리되어 있는 내용을 정리한 것이고, 영문 위키디피아 사이트에서 정의된 것을 찾아보면 좀더 이해하는데 도움이 된다.
영문 사이트도 마찮가지로 "Byte"로 검색을 하거나, 다음의 "http://en.wikipedia.org/wiki/Byte" 의 링크를 이용해서 찾아가면 된다.

"byte"는 1956년에 Dr. Werner Buchholz에 의해서 사용되었고, 이는 IBM의 IBM scratch computer를 디자인하는 동안 사용되었다. 이때는 4bit를 1byte로 설계되었다고 한다. 전형전인 I/O장비는 6bit를 1byte로 사용하다가, 나중에 System/360에 8bit를 1byte를 사용하기 시작하면서, 규격이 정해지고 표준화 되었다.

사실상, byte는 computer에서 한번에 읽어 올수 있는 가장 작은 단위로 사용되었고, 그런 의미에서 bite가 제대로된 표현이며, bite는 "한입에 베어 물다"라는 의미를 담고 있다. 
byte의 단어의 변화는 초기에 과학자들이 규격을 정할때,  bit와 bite와의 혼돈을 피해서 사용시에 실수를 줄이려는 의도가 담겨져 있다. 그래서 bite 대신에 오늘날 byte를 사용하는 것이다.

한가지 더, 요즘은 저장장치가 테러바이트 단위로 나온다. 그 이상의 단위는 거의 생각해 보지 않았었는데, 이번 기회에 알아보았는데, 아래와 같은 단위로 정의되어져 있다. 메가에서 기가로 단위로 바뀔때도 엄청난 도약이라고 생각했었는데, 이제 테라를 거쳐 페타의 시대로 갈 것이라고 하니 기술과 정보의 양은 정말 놀랍도록 발전한다. 아마도 페타의 시대로 가려면 과거를 기준 삼아 약 5년이 걸릴것 같다. (이는 순전히 나의 예상임)

Prefixes for bit and byte multiples
Decimal
ValueSI
1000 k kilo
10002 M mega
10003 G giga
10004 T tera
10005 P peta
10006 E exa
10007 Z zetta
10008 Y yotta
Binary
ValueIECJEDEC
1024 Ki kibi K kilo
10242 Mi mebi M mega
10243 Gi gibi G giga
10244 Ti tebi
10245 Pi pebi
10246 Ei exbi
10247 Zi zebi
10248 Yi yobi

(위 표는 wikipedia에서 발췌했음.)

간단하게 bit와 byte에 대해서 알아보았다.

Posted by 행복상자
2009.10.04 10:55

GRails 공부 자료들... 공부하는 것2009.10.04 10:55

오늘 추석 연휴의 첫날, 새벅같이 일어났으면 좋으련만, 휴일이라는 핑계로 7시 경에 일어나서 어제 찾아 보던 자료를 마져 보았다.

최근에 웹기술들은 정말 눈부시게 발전하지만, 그 중에서 가장 눈에 띄는 것은 RIA쪽과 다양한 브라우져들 그리고 자바쪽의 Spring framework이다. 
Spring framework는 자바를 이용한 웹개발에 많을 변화를 몰고 왔는데, EJB를 반드시 써야한다는 국내 대규모 웹 개발 풍토에 많은 변화를 주었다. 단지 마케팅과 정치적인 주장에서 개발 효용성을 안전성과 성공사례를 통해서 바꿔버렸다. 

하지만, 개선은 어디서나 일어나나 보다. 자신의 아이디어이든 다른 이의 아이디어이든, 좀더 쉽고 빠르고 안정성있는 개발을 원하는 것은 개발자들의 희망이자 욕심이다.

그중에서 GRails와 Groove는 스프링 프레임워크의 적자는 아니었다. 하지만 로드존슨이 Dynamic Language에 대한 애정을 매 컨퍼런스마다 비추었었는데, 결국은 정확이 기억이 나지 않지만, 지난해에 Groove를 SpringSource에 합병시키고, 자신의 제품라인 중에 하나로 만들었다.

Grails를 공부하기 위해서는, 사실 이것은 어제 오늘 내가 찾아본 사이트들인데, 이미 RubyOnRails에 대한 겅험이 있는 사람이라면, 그 기본 Feature를 잘 알고 있기 때문에, 이해하가 어렵지 않을 것이다.

Grails Site
- Grails: http://grails.org/
- Grails Documents: http://grails.org/Documentation
- Grails Quick Start; http://www.grails.org/Quick+Start
- Grails Tutorials; http://www.grails.org/Tutorials

IBM Developers Network:


IBM의 개발자 네트웍스에 올라와 있는 자료들은 모두 한번씩 읽어 볼만 하다.
내용은 많을 지도 모르겠지만, 각 예제들이 연결되어 있어서 공부하는데, 많은 도움이 될거라 생각된다.

하지만, 가장 중요한 것은 자신의 PC에 환경을 구성하고, 하나 하나 실행해 보는 것만큼 큰 도움이 되는 것은 없을 것이다. 새로운 것을 아무런 부담없이 공부할 수 있다는 것은 즐겁다. 이것도 또한 일로 연결될 수 있다면, "이보다 더 좋을 수 없다" 이다. ^^

Posted by 행복상자
기다렸던 사람들이 많았을 것 같다. 이제야, 오늘에야 Spring 3.0.0 RC1이 나왔으니까 말이다. 물론 Toby(일민)이를 비롯한 몇몇 선행적인 개발자들이 이미 열심히 공부하고 있고, 이의 전달도 열심인 것에 비하면, 최근에 나는 크게 관심을 두려고 노력하지 않았다. 개인적으로는 다른 사업부로 옮겨와서, 새로운 일을 맡아서 관심이 적어진(?) 것도 있지만, 사실은 그것 보다도, 기존에 내가 만든 Framework는 스프링 2.5.5 또는 2.5.6을 기반으로 설계되어 있다. 그리고 이것을 이용하여 여러 솔루션들이 개발되고 있는 중이어서, 자체 개발한 Framework의 Minor 체인지가 아닌 Big 체인지를 결정하기 쉽지 않기 때문이다. 만약 그것을 결정해야 한다고 해도 2년 후가 될 것이다. (상품으로 그리고 서비스를 하고 있는 시스템을 변경하기란 많은 결정해야할 문제에 직면해야 하는 용기가 필요한다. 그러나 이것은 모험이 아니다.)

현재 Springframework에서 제공하고 있는 메이져 Branch는 2가지이지만 앞으로는 3가지가 될 것이다.
Springframework 1.2 와 2.5 그리고 향후 주축이될 3.0이다.
그리고 이제는 3.0 Release Candidate 1이 나왔다. 이제는 또 열심히 공부할 시점이 된 것이다.
여러가지 변경된 API라이브러리들도 있고, 추가된 라이브러리들이 있는데, 이중에서 가장 먼저 눈에 들어왔던 것은 Jackson JSON라이브러리이다. 이른 아침에 Jackson 투터리얼을 보면서 시간 가는줄 몰랐다.
앞으로 정식 버전이 나올날이 멀지 않았지만, 언제가 될지는 잘 모르겠다. 올해 안에는 나오지 않을지...

Springframework 3.0 RC1의 변경 사항은 다음의 링크를 보면된다.

그리고, 아래는 이번에 RC1에 추가된 내용이다.

Changes in version 3.0.0.RC1 (2009-09-25)
-----------------------------------------

* upgraded to CGLIB 2.2, AspectJ 1.6.5, Groovy 1.6.3, EHCache 1.6.2, JUnit 4.7, TestNG 5.10
* introduced early support for JSR-330 "javax.inject" annotations (for autowiring)
* introduced early support for JSR-303 Bean Validation (setup and MVC integration)
* added default editors for "java.util.Currency" and "java.util.TimeZone"
* refined PathMatchingResourcePatternResolver's treatment of non-readable directories
* PathMatchingResourcePatternResolver understands VFS resources (i.e. works on JBoss 5.x)
* revised AccessControlContext access from BeanFactory
* AbstractBeanDefinitionParser can deal with null return value as well
* PropertyOverrideConfigurer's "ignoreInvalidKeys" ignores invalid property names as well
* PropertyPlaceholderConfigurer supports "${myKey:myDefaultValue}" defaulting syntax
* BeanFactory's default type conversion falls back to String constructor on target type
* BeanFactory tries to create unknown collection implementation types via default constructor
* BeanFactory supports ObjectFactory as a dependency type for @Autowired and @Value
* BeanFactory supports JSR-330 Provider interface as a dependency type for @Inject
* BeanFactory prefers local primary bean to primary bean in parent factory
* protected @Autowired method can be overridden with non-annotated method to suppress injection
* private @Autowired methods with same signature will be called individually across a hierarchy
* @PostConstruct processed top-down (base class first); @PreDestroy bottom-up (subclass first)
* ConfigurationClassPostProcessor detect @Bean methods on registered plain bean classes as well
* support for default "conversionService" bean in an ApplicationContext
* MBeanServerFactoryBean returns JDK 1.5 platform MBeanServer for agent id "" (empty String)
* changed NamedParameter/SimpleJdbcOperations parameter signatures to accept any Map value type
* refined logging in JMS SingleConnectionFactory and DefaultMessageListenerContainer
* introduced "ui.format" package as an alternative to PropertyEditors for data binding
* @RequestMapping annotation now supported for annotated interfaces (and JDK proxies) as well
* @RequestParam and co support placeholders and expressions in their defaultValue attributes
* @Value expressions supported as MVC handler method arguments as well (against request scope)
* JSR-303 support for validation of @MVC handler method arguments driven by @Valid annotations
* refined response handling for @ExceptionHandler methods
* @ResponseStatus usage in handler methods detected by RedirectView
* all @SessionAttributes get exposed to the model before handler method execution
* @Event/ResourceMapping uniquely mapped to through event/resource id, even across controllers
* MultipartRequest is available as a mixin interface on (Native)WebRequest as well
* removed outdated "cacheJspExpressions" feature from ExpressionEvaluationUtils
* introduced common ErrorHandler strategy, supported by message listener container
* Jpa/JdoTransactionManager passes resolved timeout into Jpa/JdoDialect's beginTransaction
* HibernateJpaDialect applies timeout onto native Hibernate Transaction before begin call
* Spring's Hibernate support is now compatible with Hibernate 3.5 beta 1 as well
* Spring's JPA support is now fully compatible with JPA 2.0 as in EclipseLink 2.0.0.M7
* SpringJUnit4ClassRunner is now compatible with JUnit 4.5, 4.6, and 4.7
* SpringJUnit4ClassRunner once again supports collective timeouts for repeated tests
* deprecated @NotTransactional annotation for test classes in favor of @BeforeTransaction








Posted by 행복상자
지난번에 글을 쓸때는, 예상했던 것보다 시간이 많이 필요했는데, 어느덧 이른 6시, 출근할 시간이 되어서 이야기를 다 마무리 못하고 펜을 집어 넣어야만 했다.

지난번 글에서는 자바에서 Exception Handling이 어떻게 생성되고, 호출하는 코드로 어떻게 알려주게 되는지를 간략하게 이야기 하였다. (뭐 간략하다고 했지만, 이미 알고 있는 내용들이 었을 것이다.)
그리고 RuntimeException의 유형의 예외들은 컴파일러에서 신경을 쓰지 않기 때문에, 반드시 Try-Catch로 블록을 만들어 줄 필요가 없다는 것을 이야기 했다. (이 경우는 개발자가 코드상에서 해결해 주어야 한다는 것도 같이 이야기 했다.)

마지막으로, Eclipse와 같은 IDE에서 자동으로 생성되는 예외 처리 코드에 관해서도 이야기 했는데, 자동으로 생성되는 메커니즘도 이야기 했었는데, 더불어서 사용할 때 주의해야 할 것은 자동으로 생성된 코드로 인해서 예외처리가 끝났다고 착각하지 말아야 한다는 것이다. 실제 예외에 대해서 프로그램 또는 클래스에서 예외처리에 대한 코드가 들어가야하고, 이를 로그로 저장하거나 화면에 뿌려줄때는 좀더 사용자 친화적인 내용으로 저장하고, 보여주어야 추후에 유지보수하기 쉽다.

오늘은 이전에 시간이 모자라서 하지 못했던 이야기를 하려고 한다.
일반적으로 try-catch블럭의 사용을 잘 알고 있을 것이고, 더불어서 finally의 사용 또한 잘 알고 있을 거라 생각한다. 호출해야 할 코드는 try블록에다 정의하고 만약 예외가 호풀되면, 이를 제어하기 위해서 catch 블록에서 정의한 코드가 호출되고, 그리고 다시 코드가 실행된다. (try 블록에서 예외가 발생했던 코드 라인 이후는 호출이 되지 않는다.)

만약, 여기에 finally구문을 사용할 경우가 있는데, 아시다 시피 이는 try 또는 catch블록에 정의된 내용이 실행과 상관없이 정의되어 있다면 만드시 실횅되도록 정의되어 있다.
이 경우에 try 또는 catch구문에 return 문이 있다면 어떻게 될까?
try 또는 catch 블록에 return 문이 있다면, 일단 finally구문에 정의된 소소 코드들을 실행하고 나서 다시 return문으로 돌아 온다는 점에 유의 해야 한다.

예외도 객체이기 때문에 이를 상속받아서 새로운 예외들을 만들수 있다. 때문에 예외처리시에 아래와 같이 모든 예외를 한번에 다 잡을 수도 있지만, 이는 바람직하지 않다. 이전글에서 설명한 것처럼 어떤 메소드를 호출할때 어떤 메소드가 호출될 것인지가 클래스와 메소드 정의서가 정의된 문서를 보면 확인할 수 있다.

try {
      runAnyCode();
} catch (Exception ex) {
     recoveryCode();
}

위의 코드의 경우는 예외느 다 잡을수 있을지 모르지만, 어떤식으로 예외를 관리할지는 전혀 알수 없다. (물론 때에 따라서는 상위의 예외로 부터 하위의 것을 모두 잡는 것이 유용할 수도 있다. 따라서 유의해서 사용해야 한다.) 꼭 필요한 경우가 아니라면, 예외별로 잘 정의해서 사용해야 한다. 아래는 예이다.

try {
      runAnyCode();
} catch (anyCodeException aex) {
     recoveryCode();
}

마지막으로 정말 중요한 것은, 예외 처리에서 순서가 있다는 것이다.
그렇기 때문에 다중으로 예외를 선언한 경우에 주의가 필요하다. 만약 어떤 예외를 상속 받아서 새로운 Exception 들을 만들었다면, 상속 받았던 에외들을 먼저 선언해 주어야 한다. 그렇지 않다면, 원하지 안는 결과를 얻을 수도 있다.
왜냐하면, JVM 에서는 첫번째 Catch블록에서 부터 호출된 예외를 처리한 Catch블럭을 찾아 내려오기 때문이다. 만약 가능한 예외 블록이 있다면, 비교를 멈추고 catch블록에 정의된 예외처리 코드들을 실행하게 된다.
따라서 만약에 첫번째 catch블록이 catch(Exception ex)라고 정의되어 있다면, 컴파일러는 다른 catch블록이 전혀 필요 없다고 생각할 것이다. (왜냐하면 이외의 catch 블록의 코드는 전혀 실행되지 않을 것이기 때문이다.) 
아래 코드에서 어떤 코드는 실행되지 않을 까요? 
try {
      runAnyCode();
} catch (Exception ex) {
     recoveryCode();
} catch (anyCodeException aex) {
     recoveryCodeNotRun();
}

내가 하고 싶은 이야기는 사실 마지막에 이야기 하고 싶은 내용이었다. Exception에도 순서가 있고 진행되는 방향이 있다. 하지만 이를 모르고서 코드를 작성한다면 의미없는 코드를 생성하게 되고 결국은 나중에 코드의 문제를 찾는데 많은 시간을 들여야 한다는 것이다. 가장 기본 적인 이야기지만 간과하는 부분이기도 해서 이야기 하고 싶었다.

이전에 인도 개발자들이 만들어 낸 코드들 분석하면서, 내가 경험했던 것들인데, 예외 처리를 했기 때문에 문제가 없을 거라는 막연한 믿음보다는 예외처리시에 필요한 코드상에서 처리해 부분(RuntimeException)들과 catch문을 사용할 때도 우선 순위를 생각하면서 정의할 것등을 반드시 숙지해야한다.
무엇보다도 가장 판단하기 어려눈 것은 try-catch문을 아무 생각 없이 중첩해서 사용하는 경우인데, 이 경우는 가독성도 떨어지지만, 예외 처리 코드를 분석하기 매우 어렵기 때무에 되도록이면 피해야 한다.




Posted by 행복상자
일반적으로 자바에서는 C++와 마찬하지로 try catch 구문을 사용하여 예외 처리(exception handling)을 하게 되어 있다. 하지만, 개발자들이 잘 알지 못하고 사용한다면, 양날의 검처럼 작용할 수 도 있고, 유익하지 않을 수도 있다.

작년과 올 상반기까지 회의 연구소 인력들과 같이 협업하는 프로젝트가 있어서, 설계와 구현을 이들과 일정 부분 코드를 나누어서 진행하였다.
일반적으로 인도쪽 개발자들은 인건비가 싸고, 개인적인 개발 능력이 뛰어 나다고 알려져 있는데, 근 1년 이상 협업을 하면서 느낀점은 사실은 그렇지 않을 수도 있다는 것이다. 일반적으로 인도는 Windows 애플리케이션 개발과 C/C++ 을 잘사용하는 개발자들은 많기 때문에 쉽게 구할수 있기 때문에 그 중에는 능력있는 개발자들이 많이 있을수 있다. 하지만 Java라는 언어를 알고 있는 개발자는 적고, 그 중에서 웹과 J2EE의 영역들을 이해할 수 있는 개발자는 지극히 드물다. 따라서 실력있는 개발자를 Java쪽에서는 찾기가 매우 힘들다.

이야기가 길어졌는데, 인도 개발자들이 작성한 코드를 우리쪽에서 Prevent라는 툴을 이용하여 정적분석을 시켰는데, 몇가지 Critical한 내용들이 보고되었다. 그래서 이를 인도 개발자에게 코드 리뷰를 하고 수정하도록 했는데, 정적분석 수행시 마다, 동일한 위험요인에 대해 지속적으로 검출되었다. 개발자는 매번 확인하고 수정했고 코드에는 예외처리가 다 되어 있어서, 문제가 있을 수 없다고 했는데도 툴은 지속적으로 문제점을 검출하고 있었다. 그래서 결국은 내가 그들이 작성한 코드를 분석하고 리뷰를 하였는데, 여러 면에서 놀라야만 했다.
이들은 자바 프로그래밍에 대한 초보자들이었다. 거의 C/C++ 방식의 코딩과 Excepion 처리를 통한 회피에만 집중하고 있었다. 너무나도 복잡하고 다중적인 예외처리 문을 사용하는 것에 대해서 혀를 내둘러야 했다. 일단 좋은 코드는 보기도 좋아야 하는데, 무슨일을 하고 무엇을 말하려고 하는지 알수 없을 정도록 예외 처리문을 반복적으로 사용하였다. 어떤 식으로든 예외를 처리하고 나오도록 코드는 되어 있지만, 몇가지 간과한 점들이 있었는데, 그 중에 중요한 점은 예외 처리에도 순서가 있다는 것이다.

예외 처리(exception handling)시에도 지켜주어야할 순서거 있고, 이를 잘못하면 원하는 결과를 얻을 수 없을 뿐더러, 코드가 복잡해 진다.

일반적으로 예외를 처리한다는 것은 어떤 메소드를 호출하고 실행할 때, 그 메소드가 어떤식으로 동작할지 아로 있어야 한다. 이는 메소드가 결과값을 반환할 뿐만 아니라, 어떠한 경우에 예외를 호출할지를 정확히 알고 있어야 한다. 

예를 들어 "java.lang.ClassLoader"라는 클래스를 사용하려고 한다면, 이 API는 아래와 같이 정의된다.

loadClass

public Class <? > loadClass(String  name)
                   throws ClassNotFoundException 
지정된바이너리명을 가지는 클래스를 로드합니다. 이 메소드는,loadClass(String, boolean) 메소드와 같은 방법으로 클래스를 검색합니다. Java 가상 머신이 이 메소드를 호출해, 클래스 참조를 해결합니다. 이 메소드를 호출하는 것은,loadClass(name, false) 를 호출하는 것에 상당합니다.

파라미터:
name - 클래스의바이너리명
반환값:
결과적으로 얻을 수 있는 Class 객체
예외:
ClassNotFoundException - 클래스가 발견되지 않았던 경우

위처럼 정의되는 API는 실행해서 결과값을 정상적으로 반환하고, 만약 실행 중에 문제가 될 경우, 이를 어떤식으로 호출하는 메소드에 알려 줄지를 정의하고 있는 경우이다. 위의 예제는 ClassLoder 클래스를 실행시 클래스가 발견되지 않는 경우에 "ClassNotFoundException"이 호출된다.
따라서 위와 같은 명세를 정확히 개발자가 알고 있어야 메소드 호출시에 어떻게 동작할지를 예측하고 코드를 작성할 수 있다.

try-catch 구문을 사용하는 것은 호출할 메소드에서 예외를 발생시킬수 있다는 것을 알고, 이를 컴파일러에 알려주는 역할을 하는 것이다. 그리고 이때 호출되는 exception도 객체로 정의되어 사용되어 진다.
그렇다면, Exception 객체는 어디에서 정의 되는 것일까? 이 객체는 개발자가 사용하고자 하는 메소드에서 정의되게 되는데, 메소드에서 "throws"구문을 찾으면 된다. 이렇게 정의된 예외는 예외가 정의된 메소드를 를 호출하는 곳으로 던져지게 된다.

자바 개발자들이 많이 사용하는 Eclipse와 같은 IDE에서는 어떤 메소드를 호출할 때 자동으로 try-catch문으로 호출하는 메소드를 감싸주는 기능을 자주 사용하게 된다. 이는 내부적으로 호출되는 메소드 내부에 "throw"구문이 호출된다는 것을 IDE툴이 알고 있기 때문이다.

한가지 더 나아가서, 자동으로 생성하는 예외코드는 보통 아래의 예외 같은 형태로 IDE상에 추가된다.
java.io.File file = new java.io.File("c:\\test.txt");
try{
    file.getCanonicalFile();
catch (IOException e) {
    e.printStackTrace();
}

한가지 주위해야 하는 것은 위와 같이 "e.pringStackTrace()"를 툴에서 자동으로 생성해 주었다고, 예외 처리가 모두 끝나는 것이 아니다. 
1. 위에서 처리해야할 예외에 대한 후 작업이 있다면 코드를 생성해 주어야 한다.
   ==> 이것은 대부분의 개발자들이 잘하고 있다.
2. 위의 예외를 Log에 남길지를 결정해야 한다. 
   ==> 이 부분은 개발자와 개발팀 내부의 결정에 따라서 정리하면 된다.
3. 위와 같은  형태가 아니라, 개발자가 나중에 알수 있는 형태의 메시지 형태로 재 정의 해서
    메시지를 뿌려 주어야 한다.
   ==> 결국은 개발자가 어떤 상황에서 에러가 발생했는지를 알수 있어야 하고, 이를 로그로
        남겨야 후처리에 도움이 될 것이다.
위와 같이 간략하게 3가지로 정리하였지만, 대부분(?)의 개발자들이 IDE툴에서 제공하는 원형 그대로의 메시지를 사용한다. Log를 남길때도 "e.printStackTrace()"의 원형 그대로 남기는데, 어떤 경우에 예외가 호출되었는지에 대한 정보를 남겨주어야 제대로 된 예외처리라 할 수 있다.

컴파일러에서는 RuntimeException과 특수한 유형을 제외한 Exception을 관리하게 되는데, RuntimeException을 확장한 예외 클래스는 그냥 모두 통과된다. (자동으로 무시된다는 의미)
이는 대부분의 RuntmeException들은 실행 중에 어떤 조건에 문제가 생기는 경우보다는 코드의 논리에 예측 및 예방할수 없는방시으로 문제가 생기는 경우에 발생하기 때문이다.
예를 들면, 배열에서 인덱스의 범위를 벗어났는지에 대해서는 배열의 길이(Size 또는 Length)를 이용해서 확인하고 방지할 수 있다.

예외 처리에 대해서, 이야기 했는데 아직 내가 하고 싶은 이야기에는 도달하지 못했다. 이는 다음에 계속 이어서 말하려 한다.

Posted by 행복상자