Whiteship's Note

'OSAF'에 해당되는 글 26건

  1. 2010.05.16 Toby's 스프링 3.0 스프링 웹 기술과 스프링 MVC를 읽고서...
  2. 2009.06.22 [DDD] User-Familly 구현
  3. 2008.11.19 하이버네이트 사용시 Association Fake Object라는 기술을 사용해 보세요. (2)
  4. 2008.11.11 오랜만에 다시 본 애니프레임 (8)
  5. 2008.11.10 Why OSAF 1. 테스트 코드를 익힐 수 있습니다. (4)
  6. 2008.11.05 OSAF 1.0.0-M2는 스프링 2.5.6 기반 프레임워크~
  7. 2008.11.03 OSAF를 일반 자바 프로젝트로 읽어 들이는 방법 (2)
  8. 2008.10.31 7분 완성. CRUD 개발 쑈!!!(with OSAF) (4)
  9. 2008.10.31 OSAF에 참여하고 싶은 개발자 (2)
  10. 2008.10.28 OSAF 샘플 코드 실행하기(스크린캐스팅) (4)
  11. 2008.10.25 OSAF 공개에 대한 이 생각 저 생각 (10)
  12. 2008.10.24 OSAF의 특징 (2)
  13. 2008.10.24 OSAF 빌드하기 (2)
  14. 2008.10.24 OSAF 다운받기 (2)
  15. 2008.10.23 OSAF(OpenSprout Application Framework) 1.0 M1 공개 (6)
  16. 2008.10.17 약간 어설픈.. OSAF 그리드 태그 완성
  17. 2008.10.14 OSAF 메이븐 저장소 사용하기 (13)
  18. 2008.09.25 OSAF 검색 폼 태그 파일 완성
  19. 2008.09.25 JavaScript Calendar
  20. 2008.09.22 delete 요청 처리 컨트롤러 코드 고민
  21. 2008.09.22 휴.. 폼 태그 파일 완성.
  22. 2008.08.14 OSGi 기반 프레임워크과 애플리케이션 아키텍처 진화 과정 (2)
  23. 2008.08.13 번들을 찾으려면.. http://www.springsource.com/repository/ (2)
  24. 2008.08.12 국내 최초 OSGi 기반 애플리케이션 프레임워크 OSAF 1.5 - 멀지 않았다. (2)
  25. 2008.05.03 하악하악 테스트 커버리지 (2)
  26. 2008.04.22 GenericPropertyEditor 만들려면...

Toby's 스프링 3.0 스프링 웹 기술과 스프링 MVC를 읽고서...



난 그동안 스프링 MVC를 잘 몰랐다. 다행이다. 이제는 좀 알것같다. 대충 머리속에 그려진다. 지난번 소녀시대 스프링 @MVC를 발표할 때 아주 중요한 스프링 MVC 구성요소 몇가지를 소개했었다. 물론 그것들 보다는 소녀시대 이름만 외우고 가신 분들이 많겠지만;; 이 책에서는 모든 구성요소를 다 설명해주며 그 구성요소군에 속해있는 여러 요소들의 특징과 사용법도 설명해주고 있다. 물론 지면 관계상 뷰 기술중 대부분은 생략이지만 간단한 확장 방법을 통해서 충분히 다른 것들의 사용법도 예상할 수 있었다.

가장 기가막힌 부분은 스프링 Controller(API)와 핸들러 어댑터를 확장해서 새로운 형태의 컨트롤러를 만들어 사용하는 방법이었다. 이 부분은 정말 스프링 MVC 정복기라고 부르고 싶은 부분이다. 물론 호불호가 갈릴만한 부분이기도 하다.

하지만 그런 지식과 실천은 꼭 필요하다. 왜냐면 스프링이 제공하는 웹 계층 구현방법이 너무 다양하기 때문이다. 그것을 정책으로 통일시킬 수 있겠지만 더 좋은건 그 정책을 코드에 반영하는 것이 필요하고 그것을 기반으로 코드를 작성하면 규모가 큰 프로젝트라 하더라도 코드의 일관성을 유지할 수 있을 것이다. 프레임워크 개발이 필요한 이유가 바로 이때문이 아닐까? 프레임워크를 사용하는 이유는 둘 중 하나인것 같다. 프레임워크가 강요하는 정책을 따르기로 결정했거나, 그 프레임워크를 기반으로 프로젝트 고유의 정책과 특성을 반영한 추상계층을 만들어 낼 수 있기 때문인 것 같다. 스프링은 기본적인 방법들은 제공하지만 어떤 방법을 강요하지는 않는다. 따라서 개발자마다 코딩 스타일이 많이 다를 수 있는데 그것을 해결할 수 있는 방법을 소개해준다.

또한 스프링 3.0 최신 기술 중에 컨텐츠 네고 기법을 사용한 뷰 리졸버 설명이 기가 막힌다. 전혀 간단하지 않은 동작 원리를 쉽게 풀어 설명해주어 이해하기 편했다. 이 부분은 레퍼런스나 API에서도 설명이 빈약해서 직접 소스코드를 분석해가며 쓰셨다고 하니 그저 감사할 따름이다.

마지막으로 이 책에서 정의한 프레임워크 개발에 대한 글을 (저자의 허락-'살짝쿵 스포일러를 넣어도 대
'-하에) 옮겨본다. 
"프레임워크 개발이란 이미 있는 기술을 조합해서 어떻게 쓸지 결정하고 툴이나 공통 모듈 정도를 만들어 놓는 것이 아니다. 프레임워크란 애플리케이션의 코드가 효율적인 방법으로 개발되서 사용될 수 있도록 새로운 틀(framework)을 만드는 작업이다."

ps: 이번 장을 보면서 새로운 형태의 OSAF 3.0을 개발해야겠고 다짐했다.
top


[DDD] User-Familly 구현

JEDI/DDD : 2009.06.22 18:53


User-Familly 관계부터 생각해보면, User가 일방적으로 여러 Familly를 가지고 있다고 볼 수 있습니다. 다중성(?)은 User에서 Familly쪽으로 1:대 관계입니다. (형제 자매가 같이 입사한 경우 다:다가 될 수도 있지만, 드문 경우니깐 중복 데이터 상관하지 않고 일단은 1대다로 ㄱㄱ, ) 생명주기를 생각해보면, Familly가 User에 종속되어 있습니다. 타입을 생각해보면 User는 엔티티가 거의 확실하고, Familly는 Value 타입에 가까운 듯 합니다. 하지만 편의상 id를 주고 관리하렵니다.

자 그럼 이제 필요한 도메인 클래스를 추가하고 속성들을 만든 다음 관계를 명시합니다.

class User {
...
    @OneToMany(cascade = { CascadeType.ALL })
    Set<Familly> famillies;
...

}

여기서 준 @OneToMany로 다중성이 어떤지 나타나고, Familly의 생명주기가 User에 종속적이라는 것이 드러납니다.

다음은 UserController(UC)로 갑니다. FamillyController를 만들 필요 없이, Familly와 연관되는 부분과 관련하여 그 요청을 UC가 처리하게 합니다. 화면상으로는 User의 수정화면에서 Familly 그리드가 보이고, 거기에 추가하는 버튼과, 수정하는 버튼이 달려있습니다.


새로 개선한 OSAF를 사용하여 만든 컨트롤러에 Familly를 그리드, 추가, 수정을 다룰 핸들러 메서드를 추가했습니다.

@Controller
@RequestMapping("/base/user/*.do")
public class UserController extends GenericController<User, UserService, UserRef, UserValidator, UserParams>{

    public UserController() {
        super(User.class);
    }

    @Autowired FamillyValidator famillyValidator;

    @RequestMapping
    public void famillygrid(@RequestParam int userid, ModelMap model, OrderPage orderPage){
        if (orderPage.getOrder() == null) orderPage.setOrder("name asc");
        model.addAttribute("list", service.findFamilliesBy(userid));
        model.addAttribute("orderPage", orderPage);
    }

    @RequestMapping(value="/base/user/famillyadd.do", method=RequestMethod.GET)
    public void famillyadd(ModelMap model){
        model.addAttribute("model", new Familly());
    }

    @RequestMapping(method=RequestMethod.POST)
    public String famillyadd(int userid, @ModelAttribute("model") Familly familly, BindingResult result,
            SessionStatus status){
        famillyValidator.validate(familly, result);
        if (result.hasErrors())
            return "/base/user/famillyadd";
        else {
            service.addFamilly(userid, familly);
            status.setComplete();
            return CommonPages.CLOSE_GRID_REFRESH;
        }
    }

    @RequestMapping(value="/base/user/famillyupdate.do", method=RequestMethod.GET)
    public void famillyupdate(int famillyid, ModelMap model){
        model.addAttribute("model", service.findFamillyById(famillyid));
    }


}

thin facade 역할을 하고 있는 service를 이용하고 있습니다.

@Service
@Transactional
public interface UserService extends GenericService<User, UserParams>{

    Set<Familly> findFamilliesBy(int userid);

    void addFamilly(int userid, Familly familly);

    Familly findFamillyById(int famillyid);

}

인터페이스에 추가해주고,,, 실제로 하는 일은 대부분이 도메인 또는 dao로 위임하는 것입니다.

@Service
@Transactional
public class UserServiceImpl extends
        GenericServiceImpl<User, UserParams, UserDao> implements
        UserService {

    public Set<Familly> findFamilliesBy(int userid) {
        return get(userid).getFamillies();
    }

    public void addFamilly(int userid, Familly familly) {
        get(userid).addFamully(familly);
    }

    public Familly findFamillyById(int famillyid) {
        return dao.fingFamillyById(famillyid);
    }

}

그럼 도메인에서 할 일은 도메인에서 처리를 하고..

    public Set<Familly> getFamillies() {
        if (famillies == null)
            famillies = new HashSet<Familly>();
        return famillies;
    }

    public void addFamully(Familly familly) {
        getFamillies().add(familly);
    }

DAO에서 할일은 DAO에서 처리합니다,

    public Familly fingFamillyById(int famillyid) {
        return (Familly) getSession().createQuery(
                "from Familly where id = " + famillyid).uniqueResult();
    }

어디서 처리하든 tx facade 역할을 하고 있는 service를 거쳐왔기 때문에, 트랜잭션 처리가 됩니다.

ps: 스프링 @MVC 혹은 OSAF의 버그(?) 발견..

    @RequestMapping(value="/base/user/famillyadd.do", method=RequestMethod.GET)
    public void famillyadd(ModelMap model){
        model.addAttribute("model", new Familly());
    }

여기서 @RequestMapping의 value를 주지 않아도(CoC로 인해 같은 결과가 나와야 함) 똑같이 동작해야 하는데, 생략할 경우, seach.do를 실행할 때(위 메서드와는 전혀 관계 없는 OSAF GenericController의 update() 메서드 시그너쳐 int id를 Integer로 바꾸라는 에러가 발생함.. @_@)


'JEDI > DDD' 카테고리의 다른 글

[DDD] User-Familly 구현  (0) 2009.06.22
[DDD] Whiteship's DDD 아키텍처 수정  (6) 2009.06.16
[DDD] Whiteship's DDD 아키텍처  (10) 2009.06.12
[DDD] DDD 입문에 좋은 글  (4) 2009.06.11
파트 3: Refactoring Toward Deeper Insight  (0) 2008.10.24
Factories  (0) 2007.12.25
Aggregates  (0) 2007.12.18
Modules  (2) 2007.12.14
Services  (2) 2007.12.13
DAO vs Repository  (4) 2007.12.04
DTO(Data Transfer Object)  (2) 2007.11.21
top

TAG 1대다, DDD, OSAF

하이버네이트 사용시 Association Fake Object라는 기술을 사용해 보세요.

Hibernate/etc : 2008.11.19 11:28


이 기술은 사부 토비님이 알려준 기술입니다.
 
Fake Object라는 이름으로 배운 기술인데 보다 적당한 이름이 생각나서 붙여봤습니다. 유즈케이스를 보여드리자면 Post -> Board 관계에서 Post를 추가하려고 할 때 Post에 Board 객체를 어디선가 setBoard로 묶어줘야 합니다.

그걸 폼을 보여주기 전에 하거나 아니면 폼을 받아서 처리할 때 하거나.. 언젠간 해야되죠. 그럴 때 보통 다음과 같은 코드를 작성하게 될 겁니다.

폼 보여줄 때 세팅할 경우를 생각해보죠.

    @RequestMapping(method=RequestMethod.GET)
    public void add(int boardId, ModelMap model){
        Post post = new Post();
        post.setBoard(boardService.getById(boardId));
        model.addAttribute(post);
    }

결국 저 문장은 서비스 타고 트랜잭션 내에서 DAO로 가서 DB로 가서 board 하나를 select하는 쿼리가 날아가게 합니다. 하지만  Association Fake Object 기술을 사용하면 그 쿼리를 보내지 않고도 아주 잘~ 연관을 맺은 상태로 객체를 저장할 수 있습니다.

Association Fake Object 라는 이름이 이미 사용 중인 용어인지는 모르겠는데, 연관 맺을 때 사용하는 가짜 객체 라는 뜻입니다.

어떻게?? 비밀입니다. 아.. 사실 비밀도 아닙니다. OSAF에서 아주 잘 활용하고 있거든요, 후후훗.
top


오랜만에 다시 본 애니프레임

모하니?/Thinking : 2008.11.11 15:50


얼마만에 살펴보는 건지 모르겠지만, 많이 발전한 것 같은 느낌입니다. OSAF를 공개하고나서 프레임워크 공개가 얼마나 쉽지 않은 일인가.. 얼마나 챙길 것이 많은지를 몸소 채험하고 있는 와중에 애니프레임을 보니까 뭔가 느낌이 새롭습니다. 깔끔한 홈페이지부터 잘 정리되어 있는 문서화가 정말 부러웠습니다. 크게 Core랑 Web이랑 Tool과 예제가 있고, 그 중에서 Core, Web을 봤더니 다시 메이븐으로 세세 하게 다시 나눠 두었습니다. 보면서 몇 가지 놀라웠던 걸 정리하겠습니다.

1. 프레임워크 외적인 요소.

깔끔한 홈피와 다량의 문서화가 부러웠습니다. 사용자와 그들의 피드백을 받고 있다는 것두요. 이것도 어쩌면 일종의 피드백을 드리는 것이오니.. 제가 지금 뭘 하고 있는거죠? ㅋㅋㅋ OSAF 홈피 가꿔도 모자랄 판에 지금 애니프레임 리뷰를 해주고 있다니 ㅠ.ㅠ 그래도 괜찮습니다. 많이 배웠거든요.

2. 하이버네이트 학습 테스트

가장 놀랜건 hibernate 모듈이었습니다. HQL을 XML에서 읽어오는 서비스였습니다. 해당 기능을 제공하는 서비스 인터페이스와 구현체 하나씩을 제공하는 모듈입니다. HQL 변경하기도 쉽고 담당자가 일괄적으로 관리하기 편하겠죠.


왼쪽에 패키지 명들을 쭉 보면.. 감탄만 나옵니다. 거기에 테스트 클래스를 작성한 걸 보면 코드 뿐만이 아니라 테스트 하고자 하는 시나리오를 적어 둔 걸 볼 수 있습니다. 남을 고려한 코드가 바로 저런게 아닌가 싶더군요. 저도 개인적으로 하이버네이트 학습을 하면서 만든 학습 테스트들이 쫙 있는데 요즘은 시간이 지나서 찾아 보려고 해도 해당 테스트가 뭘 테스트 했는지 천천히 코드를 읽어보기 전까진 알기 힘든데.. 정말 좋은 방법인 것 같습니다. 한 수 배웠습니다. 하이버네이트 RI 프로젝트를 진행할 땐 저런식으로 해야겠습니다.

3. 코드 원 저자 표시 분명해짐


제가 예전에 봤을 때는 유겐이나 로드 존슨의 이름도 없이 그들이 작성한 코드를 여러 곳에서 발견할 수 있었습니다. 그걸 보고 감정이 상해서 글을 좀 겪하게 썼었는데요. 이번에는 그런 코드가 없는 것 같습니다. 이런 원저자 표기는 시각적으로, 이성적으로, 감정적으로도 여러 긍정적인 효과를 준다고 생각합니다. OSAF아직 원 저자를 표시해 줄만한 코드가 없다보니 전부 Author Toby, Whiteship 입니다.

4. private static Log(X)


이것도 역시 지난 번에 지적했었던 문제 같은데 고쳐졌습니다. 수정하신 분인 임수연님 이신듯 한데요. 이 분이 애니프레임워크에서 hibernate를 포함하여 상당히 많은 부분에 기여(?라고 하긴 좀 그런가요.ㅎㅎ) 하신 것 같네요. OSAF도 이 부분은 일찌 감치 사부님의 지시하에 private static을 사용했었죠. 그래서 저는 한동안은 원래 private static으로 하는 거구나.. 로 알고 있었습니다.ㅋㅋ
이 부분은 http://wiki.apache.org/jakarta-commons/Logging/StaticLog 이 글 혹은 http://whiteship.me/1637 이 글을 참조해서 수정이 필요합니다.

5. 애스팩트도 사용하는 구나...


사용 예제 뿐만 아니라 프레임워크에서 제공하는 Aspect도 있습니다. 성능 모니터링에 사용할 애스팩트 같은데 좋쵸 그런거 제공해주면.. OSAF도 지난 스프링 세미나에서 발표했던 애스팩트 중에 쓸만한 것들은 포함에서 M2 때 공개해야겠습니다.

6. 작명 규칙이 뭔가 맘에 안드네

그렇다고 좋은 것만 눈에 띄진 않았습니다. 인터페이스를 표기할 때 I(영문 대문자 아이)를 붙이기로 한 것 같은데 저에게는 저런 표기가 좀 낯설어서 그런지 코드 보기가 불펴했습니다. IPropertyService = 아이프로퍼티서비스. 그럼 구현체는 그냥 PropertyService인가... 아니요. PropertyServiceImpl 입니다. 그럼 그냥 인터페이스는 PropertyService라고 하고 구현체는 뒤에 Impl을 붙이는 걸로 구분하는게 낫지 않았을까 싶은데.. 뭐 개발팀에서 정할 일이니 모르겠습니다. 기왕 스프링 기반 프로젝트면 스프링 작명 스타일을 따르는게 좋치 않을까 하는 개인적인 소망입니다. OSAF는 스프링 작명을 따르고 있습니다.

7. 예제 코드의 수많은 설정 파일

자바 1.5 미만 프로젝트를 지원하기 위해서겠지만, 설정 파일이 정말 많네요. 이건 뭐.. 어찌해야 될런지.ㅋㅋ;;; 새삼 OSAF는 설정 파일이 정말 없는거구나 하는 생각이 들더군요.


예제 코드의 applicationContext만 저정도... OSAF는 물개선샌님께서 설정 파일이 없어서 어디서 설정한 건지 알 수가 없었다는... 후훗. 애노테이션이 다 그렇쵸 뭐.ㅋㅋ 장단점이 있는 것 같습니다. 애노테이션으로 하면 설정을 한 군대에서 볼 수 없으니 답답하고, 세부 내용이 기본값 등으로 숨겨져있을 수 있어서 뭔가 명시적이지가 않은데, 설정 파일 수는 줄어 들고 소스코드랑 그와 관련된 설정이 한 군대에 있으니까 소스 코드 보면서 설정 보기도 편한데 반면.. XML은 블라블라브라ㅡㅏ브ㅏ..

8. 웹 예제.. 좀 짱인듯

웹 예제를 보니까 스프링 시큐리티, 재스퍼 리포트, Flex, Ajax, 캬오.. 너무 많은 내용이 하나의 예제에 들어가있는것이 아닌가 싶었습니다. 돌려보진 않았습니다. parent 폼을 못찾아서 지금 모든 프로젝트가 다 빨간 불이거든요.ㅋㅋ OSAF와 비교해 보면 태그 파일이 전혀 없습니다. 커스텀 태그는 몇 개 보이던데 OSAF가 제공하는 화면 컴포넌트 같은 것은 없습니다. JSP는 여전히 노가다로군요. 이 부분에 대한 프레임워크 지원은 미약했습니다. 화면 컴포넌트는 OSAF가 짱입니다.

9. 약간 아쉬운 거 '틀'

DAO 구현에 어떤 틀이 있는가? 조금 애매합니다. 그냥 일반적인 스프링을 사용한 DAO 구현처럼 보이기도 하는데, 쿼리를 보내는 부분은 애니프레임이 제공하는 쿼리 서비스를 사용해서 합니다. OSAF와는 정반대의 모습니다. GenericDAO라는 확실한 틀을 제공하고 쿼리는 자율에 맡기고 있습니다.

Service 구현에도 어떤 틀은 없네요. CRUD같은 반복적인 코드도 DAO와 마찬가지로 직접 일일히 구현해야 합니다. 예제를 보니까 DAO와는 달리 서비스 쪽은 인터페이스를 사용해서 만들고 있습니다. 흠~ 인터페이스를 쓰려면 DAO도 쓰고 안 쓰려면 Service도 쓰지 말지 왜 그렇게 했을지 좀 의아했습니다. 어쨋든 어떤 틀 같은 건 없었습니다. OSAF는 GenericService를 제공하죠. 두 종류의 GenericService를 제공하는데 하나는 Context가 있는 것(다른 것에 종속하는 것)이고, 하난 없는 것(독립적인 것)입니다.

컨트롤러 구현에는 어떤 틀이 있습니다. 위에서 본 코드 중에 하나인 AnyframeFormController 같은 것을 상속하여 컨트롤러를 만들고 있습니다. OSAF도 두 종류의 GenericController를 제공하여 컨트롤러 구현을 매우 간편하게 할 수 있도록 멋진 기능을 제공하고 있죠. 애니프레임이 제공하는 컨트롤러를 쓰더라도 상당 부분의 코드느는 스프링을 그냥 썼을 때와 비슷해 보입니다.

결론적으로.. 애니프레임의 프레임이라는 것이.. 조금 불투명해 보인다는 것입니다. OSAF 처럼 확실한 틀이 안 보입니다.

10. 발전한 모습에 정말 놀랐습니다.

몇 개월 전에 봤던 그 프레임워크가 맞나 싶을 정도로 많이 발전한 모습이고 코드 곳곳에서 노력하신 흔적을 볼 수 있었습니다. 샘날 정도로....

이것으로 상당히 긴 애니프레임 리뷰를 마치겠습니다. 몇 달 전엔 죄송했습니다. (__)/
top


Why OSAF 1. 테스트 코드를 익힐 수 있습니다.

OSAF : 2008.11.10 22:04


OSAF를 공개한지 한 달이 아직 안 됐습니다. 10월 23일에 공개했었죠. 지금까지 약 200에 가까운 다운로드를 기록하고 있지만, 전혀... 아무런... 반응이 없다는 것에는 가히 놀라울 뿐입니다. 그냥 제가 쓴 글의 댓글 몇 개 정도 뿐의 관심이 저에게 한 편으로는 아쉬움으로 또 다른 한 편으로는 오기로 다가옵니다.

완전 최첨단 프레임워크인 OSAF에 왜 이렇게 관심이 없을까. 고민을 많이 했습니다. 어렵나? 메이븐 떄문인가? 그거 없어도 되는데. 문서가 부족하긴 부족하고. 그래도 어떻게 이렇게 조용할 수가 있지. 홈피 디자인이 좀 구리긴 한데.. 그거 때문인가? ㅋ. OSAF 발음이 너무 어려운가? 별에 별 생각을 많이 했습니다. 당연히 기운도 빠집니다. OSAF를 공개한 건 어쩌면 OSAF에게 못씁짓을 한 건 아닌지 말이죠.(Max님의 '어디가서 밥은 먹고 다녀야 할텐데..' 라는 댓글이 생각납니다.)

긍정적으로 생각하기로 했습니다. 언젠가는 빛을 보겠지. 열심히 계속 가꾸다 보면 언젠간 알아주겠지. 하고 말이죠. 그래서 OSAF가 여러분에게 어떤 도움을 줄 수 있을지 생각하고 알려드리기로 했습니다. 그 중 첫 번째가 바로 테스트 코드입니다.

OSAF의 테스트 커버리지는 60%가 조금 넘습니다. (앞으로 차차 올릴 예정입니다.) 60%의 테스트 커버리지는 전부 OSAF 개발팀에서 직접 작성한 테스트 코드입니다. 어딘가에서 배껴온 코드가 절대로 아닙니다. 테스트는 초기에 JUnit과 EasyMock을 사용해서 작성 했었습니다. 물론 스프링 테스트 기능도 사용하고 있죠. 배포 직전에는 EasyMock을 Mockito로 교체하여 비슷한 테스트를 보다 깔끔하고 직관적이며 적은 수의 코드로 대체할 수 있었습니다. DBUnit을 확장하여 OSAF가 제공하는 테스트 케이스를 이용하면 DAO 테스트가 매우 간편해질 것 입니다.

이렇게 좋은데... 한 번 들여다 보고 뭐라고 해주시지 않으시겠어요? 좋다. 잘했다. 고맙다. 이런거 말구요. 이 부분의 테스트는 이해가 안 된다. 테스트가 조금 이상하다. 이 부분의 테스트는 왜 안했냐. 어려워서 그런거냐? 이 부분의 테스트는 이렇게 고치는게 좋치 않겠냐? 이런.. 반응이 제가 가장 좋아하는 반응이자 OSAF에게 거름을 주는 방법입니다.

소스 코드는 굳이 다운 받지 않아도(장기적으론 받아 두시면 좋겠지만..)

http://www.opensprout.org:9060/browse/OSAF/osaf/trunk

위 링크로 가시면 웹에서 직접 볼 수 있습니다. 소스 코드나 OSAF 와 관련하여 문제나 제안하고 싶은 것이 있다면 주저하지 마시고 이슈를 등록해 주세요.

http://www.opensprout.org/jira/secure/Dashboard.jspa


top


OSAF 1.0.0-M2는 스프링 2.5.6 기반 프레임워크~

OSAF : 2008.11.05 11:52


국내 최초 아니 어쩌면 세계 최초 스프링 2.5.6 기반 애플리케이션 프레임워크가 될지도 모릅니다. 크하하하. 최첨단 프레임워크니까 이 정도는 해줘야겠죠?

나오자마자 바로 업그레이드. 이럴 땐 메이븐이 편하긴 합니다. pom.xml에서 프로퍼티 사용해서 버전만 바꿔주면 되거든요.

    <properties>
        <slf4j.version>1.4.3</slf4j.version>
        <spring.version>2.5.6</spring.version>
        <java.version>1.5</java.version>
    </properties>

        <!-- spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
...

뭐 이런 식입니다. 어떻게 사용하는지 대충 아시겠죠?

인증샷 올립니다



top

OSAF : 2008.11.05 11:52 Trackback. : Comment.

OSAF를 일반 자바 프로젝트로 읽어 들이는 방법

OSAF : 2008.11.03 23:10


OSAF는 꼭 메이븐 프로젝트가 아니여도 사용할 수 있습니다. 아마 메이븐 때문에 OSAF를 접하시는 분들이 어렵게 느끼시는 것 같은데요. 다음에 배포할 때는 일반 자바 웹 프로젝트 예제도 같이 넣어두겠습니다.

지금은 일단 사용법만 간단하게 보여드리겠습니다.


웹 프로젝트 샘플도 이와 비슷하게 사용하시면 되겠죠?? 음냐.. 내일은 OSAF 아키타입을 보여드리겠습니당.
캬오.. 1일 1스크린캐스팅이 되겠네요. OSAF 말고도 스프링+하이버 게시판 개발 스크린캐스팅도 찍어야 되는데 말이죠. :)

top


7분 완성. CRUD 개발 쑈!!!(with OSAF)

OSAF : 2008.10.31 23:20




검색하다가 NG가 났는데, 영문 검색은 잘 됩니다. 한글 검색시 인코딩 때문에 문제가 좀 있네요. 전에도 발생했던 문제인데, 톰캣 설정(사부님왈. bodyfor어쩌구..)을 조금 수정하면 간단하게 고칠 수 있을 것 같습니다.

실제 동영상 런타임이 7분 49초인데, 설명 없이 코딩만 샥샥 하면 분명 3분 미만으로 CRUD 개발을 완성할 수 있습니다. 그렇게 만들어 놓고 세부적인 검색 조건과 파라메터 들을 추가하면서 개발 해 나간다면... 캬오... 멋지지 않아요??!!!

2008/10/24 - [Screen Casting] - OSAF 빌드하기
2008/10/28 - [OSAF] - OSAF 샘플 코드 실행하기(스크린캐스팅)

이것으로 OSAF 스크린캐스팅 시리즈 세 개가 완성됐습니다. 캬~
다음 스크린캐스팅은 OSAF 아키타입으로 웹 개발 시작하기. 입니다. 많이 기대해주세요.

ps: 요즘 다운로드 수가 바닦을 치던데.. 받으실 분들은 다 받으신 건가요. :)

top


OSAF에 참여하고 싶은 개발자

OSAF : 2008.10.31 11:39


메일 한 통이 날아왔습니다. 흠.. 한 단어의 영문 이름과 제목도 한 단어. hi.

'스팸인가...스팸이라고 하기엔 너무 단순한데..'

그래서 열어봤습니다.

캬오.. 소스포지에서 소스 코드만 보고 찾아온 것 같네요. 그래서 프로젝트 사이트 알려주고, 어떻게 참여하고 싶은지 물어보는 답멜을 보내줬습니다.

한국에 계신 분들도 참여하실 분 계시면 말씀하세요~
top


OSAF 샘플 코드 실행하기(스크린캐스팅)

OSAF : 2008.10.28 23:44



top


OSAF 공개에 대한 이 생각 저 생각

모하니?/Thinking : 2008.10.25 21:19


프로젝트 시작

사부님의 글 스프링과 하이버네이트를 이용한 RAD프레임워크 - OSAF(OpenSprout App. Framework) 공개에도 나와있지만, 이 프로젝트를 시작하게 된 시점과 여자친구에게 차인 시점이 교묘하게 일치합니다. 그리고 그 즈음에 경제가 막 악화 되면서 프로젝트가 연이어 연기 되거나 파토나는 상황이 이어졌습니다. 현재까지도 좀 그런 상태라 회사에 나와서 할 일이.. 딱히 없었습니다. 일이 없어도 워낙 하고 싶은 공부도 많고 번역할 꺼리도 많았기 때문에 심심하지는 않았는데.. 문제는 도태되는 느낌. 그리고 헤어짐에 대한 아픔. 그 두 가지는 무슨 일을 해도 해결할 수가 없었습니다. 집중할 것이 필요했습니다.

그래서 처음엔 일을 늘려나갔습니다. 번역과 스크린캐스팅을 늘려나갔습니다. 주말에도 일을 해야지 일정에 맞출 수 있을 정도로 말이죠. 그리고 취미를 만들었습니다. 사부님이 추천해준 큐브도 돌리고, 어렸을 때 배웠던 피아노가 생각나서 피아노 학원도 다니기 시작했습니다. 그런데도 기술적으로 도태되는 느낌과 시련의 아픔은 여전히 어떻게 할 수가 없었습니다. 그래서 OSAF를 시작했습니다.

내가 사용하는 이 프레임워크가 얼마나 좋은지 보여주고 싶었습니다. 그리고 그 당시는 그다지 잘 알고 있지도 않아서 더 알고 싶은 마음도 있었습니다. 대체 이 많은 태그는 어떻게 만들었으며 그리드가 어떻게 동작하는건지 말이죠. 저에겐 딱 좋다 싶었습니다. 공부도 되고, 집중도 할 수 있으니깐 말이죠.

프로젝트 진행

토비님이 거의 모든 핵심 코드를 작성했다고 봐도 무방합니다. 저는 그 코드에 살을 조금 붙이거나 공개를 위해서 수정을 했습니다. 주석을 달고, 사이트를 준비하고, 예제를 만들고, OSGi 서비스 기반으로 제공할까 하다가 실패를 해서 그냥 패키지 기반으로 전환, 그리드 태그 만들다가 DisplayTag가 적절치 않음을 발견, 그리드 태그 변환으로 인해 CRUD 형태가 기존과 달라짐, 덩덩덩. 여러 문제가 있었습니다.

하다보니, 예전에는 무심코 지나갔던 코드도 다시 들여다보게 되고, 공부할 것도 간간히 등장하더군요. 하지만, 공부할 것들이 너무 많아서 자칫 공부에 빠지면 공개를 못하겠다는 느낌이 들었습니다. 선택의 기로였죠. 공부냐 공개냐. 공부를 하자니 공개를 못하겠고, 공개를 하자니 공부를 못하겠고. 선택은 아시다시피 공개를 선택했습니다. 공부야 언제든 계속 하면 되는데, 지금 이렇게 시간 있을 때 공개 못하면 나중엔 더 힘들것 같았거든요. 그래서 공부를 좀 미루더라도 공개하기로 결정했습니다.

프로젝트 공개

공개하는 과정도 쉽지가 않았습니다. 일단 웹 사이트라도 있어야 하는데 그러려면 도메인이 있어야 하고, 서버도 있어야 되고, 그 서버에 위키, 이슈 트래커, CI 환경, 덩덩덩이 있어야 됐거든요. 근데 그런 귀찮을 일을 사부님 한테 맡길 순 없자나요. 그래서 제가 다 했습니다. 리눅스에 톰캣 깔고, 아파치랑 연동하고, 연동할 때 모르는거 물어보고, 개발 환경 제품들은 전부 Atlassian 제품들도 설치했습니다. 라이선스는 처음엔 그냥 임시 라이선스를 가지고 설치하고, 나중에 설치도 하고, 도메인 설정도 하고, 준비 중인 코드를 일단 올려서, 오픈 소스 라이선스를 신청했습니다. 근 2주 정도 뒤에 오더군요. 그걸로 라이선스를 바꿔서 이제 1년 간은 라이선스 걱정없이 사용 할 수 있게 됐습니다. 막바지에는 개발 해오던 프로젝트 구조와는 달리 멀티 프로젝트 구조의 메이븐 프로젝트로 변경해서 공개 했습니다.

프로젝트 3일 후

이제 공개 한 지 3일이 지났습니다. 일단은 후련합니다. 그리고 근 세달에 걸쳐 OSAF를 다듬고 수정하고 공개하는 시간을 지나면서 시련의 아픔도 차차 나아졌습니다. 지금도 사실 완치됐다고 느껴지지는 않지만 예전 보단 정말 많이 나아졌습니다. 그리고 두려움이 다가옵니다. 이렇게 세 달 동안 노력해서 공개한 프레임워크가 잘 살아갈 수 있을지 말이죠. 책임감이 느껴집니다. OSAF가 잘 살지 못하고 아무런 관심도 못 받고 아무도 사용하지 않고 묻혀버릴 거라면 내가 지금 괜한 일을 한 것 아닐까. OSAF라는 이름에 누를 끼치는 건 아닐까. 말이죠. 그래서 의무감이 생깁니다. 절대로 먼지가 쌓이지 않게 해야겠다. 계속 다듬어야겠다. 지금은 비록 많이 부족해도 언젠간 반짝 반짝 빛이 나도록 말이죠.

앞으로

OSAF는 최첨단 프레임워크가 될 예정입니다. 포기 했었던 OSGi 서비스 기반을 다시 시도하고, 이클립스 플러그인 개발을 해서 IDE로 코드 생성을 지원하고, 그리드 태그를 개선할 겁니다. 그리고 스프링 3.0이 출시되면 RESTful을 지원할 것이며, 스프링 Security 예제도 제공하고, 메이븐 아키타입으로 OSAF 기반 웹 애플리케이션 개발을 아주 쉽게 사용할 수 있도록 할 것입니다.

OSAF 관련 활동 말고, OpenSprout 활동으로는 스프링, 하이버 RI 프로젝트 및 OSGi 관련 프로젝트도 사부님과 구상 중입니다. 새로운 OpenSprout 멤버도 모집할 것 같습니다. 아직 구체적인 계획은 없지만, 아무래도 사람이 좀 더 있어야 하지 않을까 싶습니다.

끝으로

새싹아.. 무럭 무럭 자라거라. OpenFlower, OpenTree, OpenForest가 되는 날까지. ㄱㄱㅆ!!

top

TAG OSAF, 잡담

OSAF의 특징

OSAF : 2008.10.24 12:32


OSAF는 스프링, 하이버네이트 기반 애플리케이션 프레임워크입니다. 라는 다소 두리 뭉실한 소개로는 대체 어떤 특징이 있는지 애매 모호 하실 것 같아서 OSAF가 가지고 있는 특징을 설명하겠습니다.

1. 제네릭 활용

GenericDao는 많이 듣고, 알고, 사용하고 있으리라 생각합니다. 하지만, OSAF에는 하이버네이트 기반의 GenericDao 뿐만 아니라, GenericService, GenericController 기능을 제공합니다. 따라서 GenericDao를 사용했을 때의 장점을 그대로 살려서 Service와 Controller 계층에서도 빠르고 간편하게 CRUD 개발이 가능하다는 것입니다. 또한, GenericPropertyEditor를 제공하여 스프링의 커스텀 프로퍼티 에디터 작성을 지원하고 있습니다. 훨씬 쉽고 빠르게 커스텀 프로퍼티 에디터를 작성하실 수 있을 것으로 생각합니다.

2. 태그 파일 활용

JSP 기반 뷰 코드를 컴포넌트화 하여 태그 파일로 만들었습니다. 이로 인해 JSP를 모르는 사람도 몇 개의 태그만 익히면 빠르게 뷰를 만들 수 있습니다. 이는 곧 생산성으로 직결될 것입니다. OSAF는 add, update, grid, search 등의 기본 뷰와 레이아웃을 제공합니다. 일반적인 JSP 파일이기 때문에, 얼마든지 워하는 대로 커스터마이징이 가능합니다.

3. 스프링 2.5 기반 프레임워크

스프링 2.5의 가장 큰 변화이자 핵심은 애노테이션 활용 극대화입니다. 애노테이션으로 XML 설정을 최소화 했기 때문에, 더 이상 여러 명의 개발자가 빈 설정 파일 하나를 수정해서 커밋하다가 충돌나고 어쩌구 저쩌구 하는 복잡한 일이 벌어질 여지를 최소화 했습니다. 또한, 스프링 MVC의 경우처럼 클래스 상속 구조를 애노테이션으로 대체하여 POJO 개발이 가능하도록 개선된 부분도 있습니다. 컴포넌트 스캔과 오토 와이어링을 비롯한 많이 기능이 애노테이션을 기반으로 하고 있습니다. OSAF는 스프링 2.5가 제공하는 애노테이션 기능들을 매우 잘 활용하고 있습니다.

4. 하이버네이트 기반 프레임워크


하이버네이트를 사용하여 도메인 중심의 개발이 가능합니다. 하이버네이트 기반 DAO를 제공하며, 하이버네이트에 특화된 기능 flush(), clean() 등의 인터페이스를 사용할 수 있습니다. 또한 하이버네이트를 사용하여 DB 교체가 용이하기 때문에 테스트 DB와 실제 배포 환경 DB가 다르더라도 편하게 개발할 수 있습니다.

5. CRUD 초고속 개발

위의 모든 특징들은 바로 이 것으로 귀결 됩니다. 별다른 코드 생성기나 IDE가 없이도, 직접 C&P를 해가면서 5분 이내에 한 도메인에 대한 CRUD 개발이 가능합니다. 여기서 CRUD 개발에 필요한 파일은 전부 12개 정도로, 자바 클래스 8개. 뷰 4개 정도 입니다. 이 코드는 예제 코드를 복사하여 붙여 넣고 find/replace 기능을 사용하여 이름만 바꾸면 작업이 종료됩니다. 컴포넌트 스캔과 애노테이션 활용을 극대화 했기때문에, 빈 설정을 건드릴 필요도 없으며, 하이버네이트 기반이라 테이블을 만들 필요도 없습니다. 태그 파일을 활용했기에 뷰도 정말 간단하게 편집하여 재사용할 수 있며, 제네릭 서비스와 컨트롤러의 역할은 두 말할 필요가 없습니다.

이상이 OSAF의 가장 큰 특징 다섯 가지입니다. 세부적인 기능에 대해서는 차차 또 공개하겠습니다. 급하신 분들은 소스 코드를 다운로드 하여 직접 확인해 보시기 바랍니다. :)

ps: OSAF 말고 OpenSprout에 대해 궁금하시다면, 여기를 참조하세요.
top


OSAF 빌드하기

OSAF : 2008.10.24 10:49




프로젝트를 받으시면, dist 폴더에 jar 파일이 들어있으니까, 직접 빌드를 하시진 않아도 되지만, 그래도.. 재미삼아 한 번 해보세요.ㅋㅋ

빌드 할 때 주의함 점이 하나 있는데요. 위에서처럼, JDK 버전이 1.6이 아닌 경우에 에러가 날 수 있습니다. 그럴 떄는 pom.xml을 열어서 jdk.version 프로퍼티를 1.5로 수정해주시면 됩니다. 위 동영상에서도 똑같은 현상이 벌어졌으니 참고하시면 되겠습니다.

참고로 OSAF는 JDK 1.5 이상에서만 사용할 수 있습니다. 1.4 이하는... ( --) 몰라요..ㅋㅋㅋ
top


OSAF 다운받기

OSAF : 2008.10.24 08:41


OSAF 소스포지 링크를 클릭하면 다음과 같이 두 개의 파일이 보입니다.


위에 있는 녀석은 OSAF 의존성 라이브러리들을 osaf홈/lib 폴더에 모두 담고 있습니다. 메이븐을 사용하지 않을 때는 거기에 있는 모든 라이브러리를 클래스패스에 추가해서 사용하시면 됩니다.

메이븐을 사용하실 때에는 아래에있는 1메가 남짓의 파일을 받으시면 됩니다.

소스포지를 이용해주시면 다운로드 집계가 되기 때문에 차후에 통계 자료를 참고할 수 있습니다.

한 가지 방법이 더 있는데, 메이븐 리파지토리에 OSAF 메이븐 저장소를 등록하신 다음, 다음의 dependency 설정을 pom.xml에 추가하는 방법이 있습니다.

<dependency>
        <groupId>org.opensprout</groupId>
        <artifactId>osaf-core</artifactId>
        <version>1.0.0-m1</version>
</dependency>

이렇게만 추가하면, 필요한 모든 라이브러리까지 알아서 끌어오기 때문에 매우 편리합니다.

OSAF 저장소를 추가하는 방법도 간단합니다.

<project>
...
    <repositories>
...
        <repository>
            <id>osaf.repository</id>
            <name>OSAF Repository</name>
            <url>
                http://www.opensprout.org:8082/nexus/content/groups/public/
            </url>
        </repository>
...
    </repositories>
..
</project>

top


OSAF(OpenSprout Application Framework) 1.0 M1 공개

OSAF : 2008.10.23 17:17



(쇼팽, 연습곡 25번, 겨울바람)

사용자 삽입 이미지

토비님과 제가 주관하는 OpenSprout에서 OSAF 1.0을 드디어 공개합니다.

OSAF는 스프링, 하이버네이트 기반의 자바 애플리케이션 프레임워크입니다. 그리고 OSGi 플랫폼에 설치하여 사용할 수 있는 번들이기 때문에, 필요한 패키지만 import 할 수 있다면, 얼마든치 번들로 설치가 가능합니다.

주요 기능으로는 자바 5의 Generic 사용을 극대화 했으며, 진정한 스프링 2.5 애노테이션 활용을 볼 수 있습니다. 제공하는 기능에 비해 프레임워크의 크기는 전혀 크지 않습니다. 인터페이스 포함 클래스 갯수는 46개 정도입니다. 태그 파일, 자바스크립트, 이미지 파일까지 포함해서 1메가가 조금 넘는 크기입니다.

스프링, 하이버 학습 시 또는 자바 5이상 프로젝트에 자유롭게 사용하시기 바랍니다. 아! 주의할 것이 있는데, OSAF는 EPL 라이선스라는 것입니다. 단순한 사용에는 아무런 제약이 없지만, 저희 코드를 수정하거나 복사하여 재 배포 할 시 해당 코드도 반드시 공개해야 합니다. 이 점 주의해 주시기 바랍니다. :)

현재 버전은 OSAF 1.0.0 M1 입니다. 아직은 부족한게 많아서 마일스톤 버전으로 공개합니다. 이번 배포 버전에는 OSAF-Core 모듈과 OSAF 기반의 웹 애플리케이션 샘플을 같이 제공하고 있습니다.

http://www.opensprout.org/wiki/display/os/OpenSprout+Application+Framework

위 페이지가 OSAF 위키 페이지입니다. 저곳을 중심으로 OpenSprout 관련 위키 글을 정리할 예정입니다.

https://sourceforge.net/project/showfiles.php?group_id=158280&package_id=177263


소스 코드는 위 링크에서 다운로드 할 수 있으며, depedency 라이브러리들을 몽땅 포함하고 있는 17M 정도의 osaf-1.0.0-m1-with-dependency.zip과 라이브러리는 제외한 osaf-1.0.0-m1.jar 파일을 받을 수 있습니다.

현재는 문서도 많이 부족하고, 주석도 충분치가 않습니다. 물론 코드 완성도도 조금 떨어집니다. 그런 부분들은 앞으로 버전을 올리면서 차차 보완할 예정입니다. 그리고 스크린캐스팅을 통해서 OSAF 사용법을 자주 올릴 예정이오니, 기대해주시기 바랍니다. 그리고 개선할 부분이나 문제가 있다면 번거롭더라도 이슈를 올려주시면 감사하겠습니다.

관련 사이트는 다음과 같습니다.

OpenSprout 홉 페이지: http://www.opensprout.org/wiki/display/os/Home
OSAF 배포 소식: http://www.opensprout.org/wiki/display/os/Release
OSAF JavaDoc: http://www.opensprout.org/api/
OSAF 이슈 트래커: http://www.opensprout.org/jira/browse/OSAF
OSAF 소스 코드 뷰: http://www.opensprout.org:9060/browse/OSAF/osaf/trunk
OSAF 커버리지: http://www.opensprout.org/coverage/
top

TAG 1.0.0 M1, OSAF

약간 어설픈.. OSAF 그리드 태그 완성

모하니?/Coding : 2008.10.17 15:39


조금 어설픈 그리드 태그를 완성하고 공개합니다. 사실상 그리드 태그의 핵심 요소는 DisplayTag이고, 회사에서 사용한 OSAF 태그는 상용제품을 사용하고 있어서 공개할 수가 없었습니다. 그리드 구조도 조금 바껴서, 엑셀 기능을 제대로 활용할 수 없었습니다. ㅠ.ㅠ.. 이제 더이상 시간을 끌다가는 언제 공개할 수 있을지 몰라서, 일단 마일스톤 버전 공개를 목표로, 현 상태를 정리하여 공개하겠습니다.

<o:gridpage popupheight="400" popupwidth="700" >
<c:set var="startNumValue" value="${startNum}" />

    <d:table name="list" class="maingrid" id="maingrid">
        <d:column title="No">
            <a href="javascript:sendToUpdate(<c:out value="${maingrid.id}" />)">
                ${startNumValue}
            </a>
<c:set var="startNumValue" value="${startNumValue + 1}" />
        </d:column>
        <d:column property="name" title="이름" />
        <d:column property="loginId" title="아이디" />
        <d:column property="sex" title="성별" decorator="org.opensprout.sample.model.enumeration.SexType" />
        <d:column property="location" title="사는곳" />
        <d:column property="birthday" title="생일" />
        <d:column property="hobbies" title="취미" />
    </d:table>
</o:gridpage>

이런식으로 그리드 태그를 작성하면, 화면에서 다음과 같은 그리드를 만들어 줍니다. 약간 어설플이라고 한 이유는 많은데, 차차 개선해 나가기로 하겠습니다.


왼쪽에 [1/6]은 [첫번째 row 넘버/전체 갯수] 입니다. 따라서 두 번째 페이지에서는 [6/6]으로 보이겠죠.
중간에 있는 [1|2] 에서 굵은 글씨체가 현제 페이지고 2를 누르면 두 번째 페이지로 이동합니다.
오른쪽에 있는 건, 한 페이지당 목록의 갯수 입니다.

파이어폭스/인터넷 익스플로러/구글 크롬 에서 확인해봤을 때 모두 동일하게 보였습니다.
top


OSAF 메이븐 저장소 사용하기

Build/Maven : 2008.10.14 15:04


참조 : http://www.sonatype.com/book/reference/repository-manager.html#sect-conf-maven-nexus

기본으로 메이븐 저장소를 사용하게 되는데, 멀리 있어서 느린데다가, 라이브러리 업데이트도 느리기 때문에 최신 라이브러리를 참조할 수가 없습니다. 반면, 최신 라이브러리를 빠르게 참조할 수 있는 OSAF 메이븐 저장소를 간편하게 사용하실 수 있습니다.

일단 .m2 폴더(자기 계정 기본 폴더에 히든 폴더로 생깁니다.)에 settings.xml 파일을 열고(없으면 만들고.)

<settings>
...
 <mirrors>
...
  <mirror>
  <id>Nexus</id>
  <name>Nexus Public Mirror</name>
  <url>http://www.epril.com:8082/nexus/content/groups/public</url>
  <mirrorOf>central</mirrorOf>
  </mirror>
... 
</mirrors>
...
</settings>

이렇게 하나의 미러 사이트를 추가해주시면 됩니다. 기본 메이븐 저장소, 아파치, 코드하우스, 아틀라시안, 스프링, 스프링 DM 등 유명한 메이븐 저장소를 전부 프록시로 등록해뒀기 때문에, 저렇게 설정하시면 기본 설정에서 보다 더 많은 최신 라이브러리를 쉽고 빠르게 참조하여 사용할 수 있으실 겁니다.

간혹, 정말 간혹 다운받지 못하는 라이브러리가 있을 때는, 저한테 요청하시면 (원하는 그룹 iD와 원하는 artifactID, 버전으로..)라이브러리 설치 서비스도 해드립니다.ㅋㅋㅋ  라이브러리 설치야 워낙 간단하기 땜시~
top


OSAF 검색 폼 태그 파일 완성

모하니?/Coding : 2008.09.25 15:59


사용자 삽입 이미지

태그 파일을 활요한 JSP 코드는 다음과 같습니다.

<o:searchpage title="사원관리">
    <o:searchbuttons popupheight="400" popupwidth="700" />

    <o:searchform action="grid.do">
        <o:searchrow>
            <o:stext path="name" label="이름" size="20" maxlength="30" />
            <o:sselect path="location" label="국적" items="${ref.locations}" isCOV="yes" />
            <o:sdate path="birthday" label="생일" />
        </o:searchrow>
        <o:searchrow>
            <o:sradiobuttons path="sex" label="성별" items="${ref.sexType}" />
        </o:searchrow>
        <o:searchrow>
            <o:scheckboxes path="hobbies" label="취미" items="${ref.hobbyType}" />
        </o:searchrow>
    </o:searchform>
</o:searchpage>

뭔가 많아 보여도, <o:searchrow>를 사용해서 세 줄로 표시했을 뿐, <o:searchrow>를 빼면 별거 없습니다. 이젠 정말 폼 태그 파일 만들차례.. ㅎㄷㄷㄷ.. 어려울텐데.. ㄷㄷㄷㄷ DisplayTag로 만들어봐야지
top


JavaScript Calendar

View/JavaScript : 2008.09.25 13:52


참조: http://www.dynarch.com/projects/calendar/
사용자 삽입 이미지

저렇게 달력을 뿌려주는 자바스크립트 라이브러리입니다. Date 정보를 입력받을 때 사용하면 유용하겠죠. 여러 가지 스타일 시트도 제공해주고, 여러 포맷으로 데이터를 조작할 수도 있고, 좋습니다.

jscalander가 제공하는 예제 소스 코드를 보면 어떻게 이용할 수 있을지 대충 알 수 있습니다.
<form action="#" method="get">
<input type="text" name="date" id="f_date_b" /><button type="reset" id="f_trigger_b">...</button>
</form>

<script type="text/javascript">
    Calendar.setup({
        inputField     :    "f_date_b",      // id of the input field
        ifFormat       :    "%m/%d/%Y %I:%M %p",       // format of the input field
        showsTime      :    true,            // will display a time selector
        button         :    "f_trigger_b",   // trigger for the calendar (button ID)
        singleClick    :    false,           // double-click mode
        step           :    1                // show all years in drop-down boxes (instead of every other year as default)
    });
</script>

친절하게 주석도 있기 때문에, 금방 적용하실 수 있겠죠. 하지만, 약간의 번거로움은 감수를 하셔야 하며, 저런 컴포넌트가 여럿 필요할 때는 복사 붙여넣기 코드가 JSP 페이지 사방에 나타날 수 있을 겁니다. 그럴 땐 태그 파일을 만들어서 컴포넌트화 해 두면 매우 편합니다.

언젠가 공개할 OSAF를 사용하신다면, 간단한 태그 파일 sdata.tag로 쉽게 저런 UI 컴포넌트를 만들 수 있습니다.

<o:sdate path="birthday" label="생일" />

이렇게 한 줄이면 끝이죠. 캬오~ 태그 파일 만쉐이! OSAF 만쉐이!!
top


delete 요청 처리 컨트롤러 코드 고민

모하니?/Coding : 2008.09.22 15:47


앞선 글에서도 살펴봤지만, Cascade 옵션을 적용하려면, id 값으로 레코드를 제거하는 쿼리를 날리는게 아니라, Session의 delete(object) 메소드 호출을 해야 하는데. 기존의 컨트롤러는 삭제할 객체의 id 값을 가져오고, service.delete(id)를 호출하여 최종적으로는 id로 삭제하는 쿼리를 난리게 됩니다.

방법은 두 가지.

1. Cascade 옵셥을 사용할 녀석만 매번 OSAF가 제공할 기본 컨트롤러 코드를 다음과 같이 재정의하게 할 것인가.

//Employee.java

    @RequestMapping
    public String delete(int id) {
        service.delete(service.get(id));
        return CommonPages.CLOSE_RESEARCH;
    }

2. 아니면, 아예 OSAF 기본 컨트롤러 코드를 변경해서 기본적으로 Session.delete(Object)를 호출하게 할 것인가.

//BaseController.java

    @RequestMapping
    public String delete(int id){
        // This will not trigger additional query, because the deleting object is already exist in Session Context.
        // We'll use Session's delete(Object) method to apply cascade options.
        service.delete(service.get(id));
        return CommonPages.CLOSE_RESEARCH;
    }

두 번째 것을 선택했습니다. 이론적으로는 Session Context에 삭제할 객체가 담겨 있을테니, 추가적인 select 쿼리가 날아가지 않을 것 같아서 선택했고, 테스트를 통해 검증을 해본결과 예상이 맞았습니다. 어차피 같은 쿼리가 날아간다면, 좀더 유연하게 설정값을 가지고 Cascade를 적용할 수 있는 메소드를 사용하도록 OSAF 컨트롤러 코드를 변경했습니다.

'모하니? > Coding' 카테고리의 다른 글

약간 어설픈.. OSAF 그리드 태그 완성  (0) 2008.10.17
DisplayTag 데코레이터 사용하기  (0) 2008.09.29
OSAF 검색 폼 태그 파일 완성  (0) 2008.09.25
Principle of least astonishment  (0) 2008.09.24
How to Design a Good API & Why it Matters  (0) 2008.09.24
delete 요청 처리 컨트롤러 코드 고민  (0) 2008.09.22
@Resource 활용 팁  (6) 2008.09.08
TDDBE - xUnit 23장  (0) 2008.09.01
TDDBE - xUnit 22장  (0) 2008.09.01
TDDBE - xUnit 21장  (0) 2008.09.01
TDDBE - xUnit 20장  (0) 2008.09.01
top


휴.. 폼 태그 파일 완성.

View/JSP : 2008.09.22 11:59


<o:popuppage title="사원등록">
    <o:buttons>
        <o:savebtn />
        <o:cancelbtn />
    </o:buttons>
    
    <o:form>
        <o:ftext label="이름" path="name" size="10" maxlength="20" />
        <o:ftext label="아이디" path="loginId" size="15" maxlength="20" desc="최대 20자리까지 입력 할 수 있습니다." />
        <o:fpassword label="패스워드" path="password" size="10" maxlength="16" desc="최대 16자리까지 입력 할 수 있습니다." />
        <o:fradiobuttons label="성별" path="sex" items="${ref.sexType}" />
        <o:fcheckboxes label="취미" path="hobbies" items="${ref.hobbyType}" />
        <o:fselect label="국적" path="location" items="${ref.locations}" isCOV="yes" />
        <o:ftextarea label="메모" path="memo" rows="3" cols="50" />
    </o:form>
</o:popuppage>

이게 추가와 수정시에 사용할 JSP 페이지 코드입니다. JSP를 몰라도 금방 태그 파일 몇개만 익히면 쉽게 페이지를 찍어낼 수 있습니다. 이 페이지에서 사용하고 있는 태그 파일들은 다음과 같습니다.

사용자 삽입 이미지

흠냐~ 이 녀석들로 만들어 낸 화면입니다.
사용자 삽입 이미지

물론 CSS도 가미가 되어 있습니다. CSS는 잘 몰라서 사부님이 만들어 둔 걸 그대로 쓰고 있습니다. 저기 items 뿌리는 부분의 label 스타일을 좀 변경하고 싶은데;; 일단 스타일은 나중에 변경하기로.. ㅋㅋ

사용자 삽입 이미지

업데이트 뷰에서도 위와 동일한 태그를 사용하면 됩니다. 흠.. 버튼을 하나 추가해서 삭제버튼을 달아야겠군요.

이것으로 폼 태그 파일들은 다 준비가 됐습니다. 이제 그리드 태그 파일만 완성하면... 드디어 OSAF를 출시할 수 있게 됩니다. 캬오~~
top


OSGi 기반 프레임워크과 애플리케이션 아키텍처 진화 과정

Spring DM/exercise : 2008.08.14 18:11


대체 어떻게 모듈화 해야 할까...
어떻게 나눌 것인가..
어떻게 구성해야 번들간의 상호참조(CD)를 없앨 수 있을까..
어떻게 나눠놔야 개발을 할 때 여러 번들을 뒤적거리지 않을까..
번들헬이 발생하지 않게 하려면...

위와 같은 고민들은 OSGi와 스프링 DM을 학습하다보면, 자연스레 맞닥드리게 되는 문제들입니다.

이 질문에 대한 답은 모르겠습니다. 사실 답은 있죠. "잘". 그러려면, 많이 실험을 해봐야 합니다. 때마침 저한텐 아주 좋은 실험체가 있습니다. 임상 실험 프로젝트랄까요.ㅎㅎ 스프링 하이버기반으로 세 달에 걸쳐서 만든 시스템이 하나 있습니다. 규모가 크지도 작지도 않고 좋습니다. 도메인 모델이 한 40개 정도되는 프로젝트입니다. 비즈니스 로직도 포함하고 있어서 서로 얽히고 섥혀있지요.

이 프로젝트에서 OSAF15에 들어갈 코드를 분리해냈습니다. 그게 1단계였죠. 분리해낸지는 꽤 됐지만, 주석이랑 테스트 코드를 추가하느라 시간이 좀 지연됐습니다. 어제부로 그 작업도 끝났습니다. 1.5 단계랄까요. 정리하는 단계는 그렇게 끝났습니다.

이제는 본격적으로 2단계로 돌입해서 쪼갠 것을 적용해봐야 합니다. 그래서 검증이 되는거죠. 일단은 OSGi화 하지 않았던 기존 시스템과 동일하게 동작하는것을 목표로 적용합니다.

2단계가 잘 돌아가면, 그 뒤엔 쪼갠 것을 돌리는 상태에서 OSAF 번들만 수정해서 업데이트를 하는 겁니다. 이게 마지막인 3단계입니다.

오늘은 2단계에 막 들어선 날로, 코딩은 별로 못하고 낙서와 그림을 그리고 웹 서핑을 하면서 다른 자료를 찾는데 시간을 많이 보냈습니다. 다행히 어느 정도 성과가 있었습니다.

사용자 삽입 이미지
처음에 그린 그림입니다. OSAF15 번들 자체가 너무 커서, 그 안에 들어있는 몇 개의 패키지를 별도의 모듈로 쪼개는 걸 구상하여 그린 겁니다. OSAF, OSAF-App 이렇게 둘로 쪼개고, 일반 App 번들과 OSAF-App 번들을 WAR 번들에서 참조하는 걸 그리다가.. 문제를 발견했습니다. 그게 바로 아래에 있는 S/F SessionFactory 입니다.

저 때는 아직 문제를 발견했다기 보다.. 뭐랄까.. 냄새가 나고 있었다고 할까요.. 저 땐 단순하게 SessionFactory를 사용한다고만 생각했지 SessionFactory에서 저 번들들 안에 들어있는 모델을 참조해야 한다고.. 즉 상호참조가 발생하리라곤 미쳐 생각을 못하고 있었습니다.

사용자 삽입 이미지
(여러 색의 형광펜을 발견하고, 잘 나오나 확인을 해보는 그림이 좀 멋있어 졌습니다.ㅋㅋㅋㅋ)

두 번째 그림입니다. 첫 번째와 비슷하게 OSAF에서 이번엔 Security 부분을 떼어 내야겠다는 생각이 들었습니다. OSAF-App에는 User, Role, Audit과 같은 인증, 권한 과 관련된 기본 도메인들과 그 도메인이 사용하는 Audit이라는 클래스가 있었습니다. 그리고 User, Role에 대한 Dao, Service, Controller 까지도 들어있었죠.

문제는 Security가 저 녀석들을 사용하고 있다는 겁니다. User, UserDao를 사용합니다. 그렇게 되면 OSAF와 OSAF-App 두 번들이 CD에 빠집니다. 그래서 Security를 빼내면 될 줄 알고 저렇게 OSAF-Security를 빼내기로 결정.

실제 코드 작업을 좀 하다가 보니... 크헉!!!! osaf.service에서 osaf.security를 참조하고 있었습니다. 이러면 이거 때어낸다고 해서 해결될 문제가 아닌게 되는거라.. 다시 고민에 빠짐...

사용자 삽입 이미지
(이때부터 그림에 좀 신경을 쓰기 시작했죠.)

맨 왼쪽에 X 표를 친 부분이 바로 그 좌절하는 순간입니다.

여차저차해서 SessionFactory에 대한 실마리를 찾았고, 다시 OSAF는 좀 크지만, 한 덩어리로 가기로 했습니다.
사용자 삽입 이미지
(네모와 동그라미를 그리는 연습을 자주 해야겠습니다.)

실제 OSAF 내부에선 저런 순환 구조는 아닙니다. base쪽에 패키지를 세세하게 나눠뒀기 때문에 패키지 순환 참조는 발생하지 않습니다. CD는 하나도 없습니다.

오늘은 여기까지 구상하고 마치고 내일 다시 재도전해야겠습니다. "잘" 나누는 방법을 찾기란 이렇게 힘들고 재밌는 일이더군요. 캬캬캬.
top

TAG OSAF, OSGi

번들을 찾으려면.. http://www.springsource.com/repository/

Spring DM/etc : 2008.08.13 12:04


http://www.springsource.com/repository/ 필요한 번들을 찾으려면 왼쪽 사이트에 가셔서 검색하시면 됩니다. 다소 복잡한 dep 구조를 가지고 있는 하이버네이트도 잘 정리되어 있었습니다.

사용자 삽입 이미지

위에 링크에서 번들 파일을 바로 다운로드 할 수 있으며, Maven을 사용할 때는 아래 dependency 덩어리를 pom.xml에 추가하면 됩니다. 그리고 이 번들이 의존하는 다른 번들들의 링크까지 확인할 수 있습니다.

하단의 Required Dependencies 바를 펼치면 해당 링크로 바로 이동할 수 있죠.
사용자 삽입 이미지

이렇게 위 사이트의 도움으로 OSAF 1.5의 모든 의존성을 해결해서 ACTIVE 상태로 만들 수 있었습니다.

사용자 삽입 이미지

차근 차근 진행이 되어 갑니다. 멀지 않았습니다. 하지만, 한 발짝 물러나야 할 일이 생겼군요.

1. OSAF 1.5 모듈에서 스프링 DM이 해줄 일이 생겨서, 빈 몇 개를 서비스로 등록을 해야겠습니다. 컴포넌트 스캔 확인 좀 해야겠네요. 컴포넌트 스캔까지 되면...

2. 다음은 예제 만들어서 저 번들이 제공하는 서비스와 패키지를 제대로 쓸 수 있는지 확인하고..

3. 간단 튜토리얼 만들고...

4. OSAF 웹 사이트좀 꾸민 다음..

5. 최종 배포!!!

멀지 않았습니다. 배포한 뒤에는 좀 더 심화 작업을 진행할 생각입니다.

6. 기존 시스템 OSGi화 하기

7. 코드 제너레이터 만들기

8. 이클립스 플러긴 만들기
top


국내 최초 OSGi 기반 애플리케이션 프레임워크 OSAF 1.5 - 멀지 않았다.

모하니?/Coding : 2008.08.12 18:10


사용자 삽입 이미지

프로젝트와 프로젝트 사이에 텀이 생겨서, 요즘 다듬고 있는 OSAF 1.5 입니다. 범용성은 없고, 얼리어댑터에게만 유용한 프레임워크입니다. 초고속 애플리케이션 개발을 지원하는 OSAF의 맛보기 정도랄까요.

프로젝트를 만드는 김에 OSGi 번들로 만들생각입니다. 굳이 Spring DM 번들일 필요는 없지만, 일단 베이스는 Spring DM 번들로 시작했습니다. 보시면 이미 번들도 생성이 되었죠. 캬캬캬

설치도 해봤습니다. 맨 아래에 있습니다.

사용자 삽입 이미지

하지만... INSTALLED 상태로 짐작하실 수 있겠지만... 미싱 라이브러리가 장난 아닙니다.

사용자 삽입 이미지

그래서.. 걍 이 번들 안에 나머지 jar도 왕창 다 묶어서 배포해버릴 생각으로
bundle:bundleall을 사용했습니다.(무슨 말인지 이해 못하시겠다면, 두 번째 링크 참조) 하지만, jta 라이브러리를 손댈 때 문제가 발생하더군요.

사용자 삽입 이미지

멀지 않았습니다. 코드만 공개하려면 일찌감치 공개할 수 있었지만, 주석도 달고 테스트도 추가하면서 현재 커버리지 53%를 넘긴 상태 입니다. 핵심 코드 테스트는 오늘부로 모두 완료한 상태고, 나머진 테스트하기 귀찮은 것들이 몇 개 있는데, 그것들은 뭐 기계적으로 좀 추가해서라도 65% 정도는 넘길 생각입니다.  이 번들이 RESOLVED만 되면, 최종 관문으로 사부님한테 검사 받고, 그 관문이 통과되면 예제를 후루룩 만든담에.. 공개!!!

멀지 않았습니다.

참조
http://www.springsource.com/repository/ <-- 번들 많아요. 없는 것도 있어요.(전부 있다는 뜻이 아님.)
http://felix.apache.org/site/maven-bundle-plugin-bnd.html <-- bnd 메이븐 플러긴 공부좀 해야겠어요. 지금은 기본 설정으로 만들었지만;;)
http://notehive.com/wp/2008/07/23/osgi-hibernate-spring-dm-sample/ <-- JTA를 포함한 하이버네이트 관련 번들을 볼 수 있는 코드를 제공하는데.. svn 주소가 접속이 안 됨. 7월에 올린 글인데 벌써 코드를 지운거야?? ㅠ.ㅠ 왜..

ps: 과연 사부님이 최종 관문 통과 시켜주실까??
top

TAG OSAF, OSGi, ㅁㄴ

하악하악 테스트 커버리지



사용자 삽입 이미지

Bamboo가 만들어준 클로버 테스트 커버리지 리포트 입니다. 너무 단순해 보여서 탈이지만, 바쁘기 땜시 딱 저것만 봐도 충분합니다.

0%가 나온 날은 그날 빌드가 안 돌아가서 그렇습니다. 41%로 시작했다가 쭉쭉 떨어져서 17%를 바닥 치고 다시 50%까지 성장하고 있습니다. 투자 할만해 보이시나요? ㅋㅋ

테스트 커버리지를 올리기로 결심한 것은 박재성님의 CI 강좌 이후 뒷풀이 때 박재성님과 나눈 대화 때문이었습니다. "테스트 커버리지 70% 이상을 유지하시는데 힘드시지 않은가요?" 라는 질문을 드렸고 그 뒤에 박재성님께서 매우 좋은 답변을 해주셔서 저에게 자극이 됐던 것 같습니다.

현재 프로젝트를 진행하며 토비형님과 함께 OSAF도 만들어가고 있습니다. 실제 프로젝트를 진행하며 스프링 2.5, 하이버 3.2 기반의 OSAF 프레임워크를 만들고 있습니다. 그래서인지 정말로 필요한 코드들만 프레임워크에 들어가고 있으며 잘 만들면 ROO나 RoR의 스캐폴딩이 부럽지 않은 기능과 센스를 갖춘 프레임워크가 나올 것으로 기대하고 있으며 또 그렇게 만들려고 노력하고 있습니다. 그 정도 되려면 스프링 프레임워크 정도의 테스트 커버리지는 기본으로 갖춰줘야겠지요.

사용자 삽입 이미지

Anyway, 성장이 좀 더뎌지긴 했지만 꾸준히 올라갈 것으로 예상됩니다. 어떻게 아냐구요? 아직도 OSAF 코드 중에 테스트를 만들어야 할 대상들이 남아있기 때문이죠. 그리고 제가 만들기로 마음먹었기 때문에 커버리지는 분명히 좀 더 올라갈 것입니다.
top


GenericPropertyEditor 만들려면...

모하니?/Coding : 2008.04.22 21:04


0. PropertyEditor가 뭔지 알아야 함.
1. 왜 PropertyEditor를 쓰는지 알아야 함.
2. PropertyEditor를 자주 사용하는 코드가 있어야 함.
3. 자바의 Generic을 알아야 함.
4. Reflection 알아야 함.
5. ApplicationContext 알아야 함.
6. 스프링 기반 테스트 코드 만들 수 있어야 함.
7. BeanLifeCycle 적절히 이용할 줄 알아야 함.

자바의 Generic이 erasure 방식이라 아쉽지만, 그래도 잘 사용하면 엄청나게 많은 코드가 줄어들고, 코드가 줄어드는 만큼 개발 생산성은 팍팍팍 증가합니다.

Java 5 이상을 못 or 안 사용하고 계신 분들이더라도 괜찮습니다. 굳이 Generic을 사용하지 않고도 비슷한 추상 클래스를 만들어서 사용하시면 됩니다. 대신에 매번 캐스팅 하는 수고는 감수하셔야겠지만 말이죠.

스프링으로 테스트 클래스 만들어가며 GenericPropertyEditor를 만들어 봤습니다. 정말 재미있어서 옆 모니터에 틀어둔 스타리그도 안 보고, 여친님 문자가 왔었는지도 몰랐네요. 소스 코드는 공개하지 않습니다. 헤헷.

ROO보다 멋진 OSAF가 공개되는 날을 기다리며~
top







티스토리 툴바