그런 맛, 나도 원하는 맛.

전부를 볼 수 있는 눈은 아무것도 보고 있지 않는 눈과 다름없어요.
그런 눈으로 보면 물에 뜬 정보들만 잔뜩 읽어낼 뿐, 돌아서면 뭘 봤는지 금세 잊고 맙니다.
이것저것 집어 먹어서 대체 뭘 먹었는지도 생각나지 않는데, 숨 가쁘게 배만 부른 느낌이랄까요?
우리가 음미하고 싶은 것은 배가 부르지 않아도 '지금 이순간'을 풍부하게 해주는,
그래서 다 먹고 난 뒤에도 혀로 입맛을 다시게 되는 그런 맛입니다.

                                                               - 이주은, 우리의 삶에 바쿠스의 포도주를.
by 은봉씨 | 2011/12/02 13:13 | 트랙백 | 덧글(0)
Spring 3.0 새기능 - Restful WebService

Spring 3.0 새기능 - Restful WebService

 

웹서비스 Restful 통신 방법을 구현하는 방법은 다양합니다.

다만, 기존 Spring MVC (3.0 이상)를 이용하여 좀더 간단하게 Restful 서버/클라이언트를 구현하는 방법이 있습니다.

  • REST 서버 : Spring Controller 로 개발
  • REST 클라이언트 : JSP 웹 화면 혹은 그냥 자바 프로그램
  • 환경 구성 : Spring3.0 MVC + Spring 제공 HiddenHttpMethodFilter 설정

REST 란?

  • Representational State Transfer 의 약자
  • REST is not-standard, architecture Style
  • URI 기반으로 리소스에 접근하는 기술
  • 프로토콜은 어느 장비에서나 지원하는 HTTP 사용
    - HTTP 프로토콜의 Simple 함을 강점으로 활용
    - HTTP 의 메소드 기반으로 리소스 접근
      (GET, PUT, DELETE, POST, HEAD, OPTION)

웹서비스 구현 스펙

  • SOAP Based WebService : JAX-RPC(J2EE 1.4), JAX-WS(Java EE 5)
  • REST Based WebService : JAX-RS (Java API for RESTful Web Services)
    - Apache CXF, Jersey, RESTEasy, Restlet, Apache Wink, Spring @MVC

     Apache CXF

     JAX-RS, JAX-WS 지원
     전자정부 표준 프레임워크에서 사용

     Jersey

     Sun Glassfish 에 탑재

     RESTEasy

     JBoss 프로젝트

     Restlet

     경량 REST 프레임워크, 가볍고 직관적

     Apache Wink

     서버 모듈과 클라이언트 모듈로 구성

     Spring @MVC

     Spring3 이상에서 지원 

 

RESTful Web Service 의 Content-Type

    
    REST 는 표준화 된 Content-Type 이나 데이터 구조를 정의하지는 않으므로
    text, xml, json, void, Integer, String, JPEG, File, OutputStream 등 필요한 표준을 정의해야 합니다.
   

 

Spring @MVC 로 RESTful WebService 구현 방법 

 

    REST 통신을 위한 서비스를 구성하기 위해서는

    기본적으로 Spring 3.0 기반의 MVC 설정이 먼저 선행되어야 하며, 해당 환경 기반 하에서

    REST 의 PUT/DELETE 등의 메소드를 사용하기 위한 스프링 제공 필더를 SpringDispatcher Servlet 의 URL Mapping 에 동일하게

    지정해주면 됩니다.

 

    Spring3.0 의 Restful Web Service 를 사용하면, 결국 웹서비스 제공자는 Spring Controller 이므로,

    로그인 등의 보안 관련 인증/인가 처리는 Spring Interceptor 를 설정하거나 하여 Rest 외의 다른 비즈니스 구현 Controller 와

    동일한 아키텍처 상의 설정으로 가져갈 수 있다는 장점이 있습니다.

    물론 DispatcherServlet 을 다르게 등록하면 별도로 가져갈 수도 있죠.

 

    다만, Spring Rest 에서 특정 데이터 포맷이 결정되어 있는 것은 아니므로

    HttpReqeust 객체와 URI 에 담을 수 있는 데이터를 미리 정의하고 수신 시 변환하는 작업은 필요합니다.

    이 또한 스프링의 @PathVariable 과 Model 을 이용하면 좀 더 간단해 질 수 있겠지요.

    데이터 형태를 JSON 이나 XML 로 가져가고 싶다면,

    그건 Spring REST 에서 Spring MVC 의 다른 기법을 함께 응용 하면 충분히 구현 가능합니다.

 

 

   Spring Controller 로 서버를 개발한 예제

@Controller
public class TemplateController {

 

     @RequestMapping(value="/template/get/{id}", method=RequestMethod.GET)
     public String view(@PathVariable String id, Model model) {
          model.addAttribute("templateModel", templateService.get(id));
          return "/template/view";

     }
}

 

- RequestMapping 의 URL 과 Method 를 살펴봅니다.

  URL 에 {id} 라고 되어 있는 부분에는 GET 방식으로 요청하는 URL 에 해당 위치에 id 라는 값이 들어올거라는 겁니다.

  client 가 요청시 ~~~/template/get/eunbongc 라고 하면 id 가 eunbongc 인 정보를 get 하는 의미지요.

  그리고, controller 프로그램에서는 해당 {} 와 같은 위치의 값을 @PathVariable 로 가져옵니다.

  그 다음은 이 값을 이용해서 비즈니스 로직을 구현하면 되겠지요.

   JSP 기반의 Client 프로그램 예제

<c:forEach items="${list}" var="templateModel">
  <li><a href="/app/template/get/${templateModel.id}">${templateModel.name}</a></li>
</c:forEach>

 

- 그냥 요청하는 거죠. ~~~/template/get/값 으로 요청을 하는건데, 해당 값에 EL 표기법을 쓴거뿐이구요.

   JUnit Test Case 처럼 일반 Client 프로그램 예제

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration (locations = {"classpath:/META-INF/app-config.xml", "classpath:/META-INF/mvc-config.xml" })
public class TemplateControllerClientTest {

 

     @Test
     public void testGet() throws Exception {
          RestTemplate restTemplate = new RestTemplate();
          String result = restTemplate.getForObject("http://localhost:8080/app/template/get/eunbongc", String.class);
          System.out.println(result);
     }

 

}

 

// 위 테스트케이스 실행 결과

{"templateModel":{"name":"choi eun bong","id":"eunbongc"}

 

- RestTemplate 은 org.springframework.web.client.RestTemplate 이며,

  RestTemplate 을 이용하여 remote client 가 url 요청을 하는 겁니다. result 는 JSON 표기법으로 받는거죠.

 (물론 단순 스트링, XML 로도 받을 수 있습니다.)

 

    web.xml 에 Spring MVC 기본 설정

참고로  위 예제는, /app/- URL Pattern 에 대해 Spring Dispatcher Servlet 을 매핑하여 별도의 확장자 없이 url 기반으로

Request 가 Mapping 되었습니다.

 

  <!-- Springframework DispatcherServlet -->
  <servlet>
    <servlet-name>OOOSpringDispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/config/mvc-config.xml</param-value>
    </init-param>
  </servlet>
 
  <!-- Springframework DispatcherServlet Mapping -->
  <servlet-mapping>
    <servlet-name>OOOSpringDispatcherServlet</servlet-name>
    <url-pattern>/app/-</url-pattern>
  </servlet-mapping>

 

    web.xml 에 REST Method 사용하기 위한 Spring3.0 제공 Filter 추가

GET/POST 처럼 평범한 HTTP Method 외의 PUT, DELETE 등을 사용하고자 할 때

html form tag 에 method=PUT 과 같은 형태로 사용할 수 있는 필터입니다. 

 

  <!-- Springframework Filter for REST -->
  <filter>
    <filter-name>httpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
  </filter>

  <filter-mapping>
    <filter-name>httpMethodFilter</filter-name>
    <url-pattern>/app/-</url-pattern>
  </filter-mapping>

 

Spring @MVC 로 RESTful WebService 구현 시 고려 사항

 

   HTTP Method 의 제약

 

     - GET, POST, PUT, DELETE 만으로 구성해야 함

      - 오래 된 장비나 서버의 경우 GET,POST만 허용

 

   URI 를 통해 보여지는 정보의 보안성   

 

   Stub 코드 생성

 

     - Spring @MVC 로 WADL 생성 불가, 

       Spring @MVC 에서의 REST 클라이언트는 Spring 의 RestTemplate 을 통해 개발해야 함

     - Spring 상에서 Apache CXF 사용하여 WADL 생성 및 Stub 코드 생성은 가능하나

       CXF 라이브러리 종속성 발생

 

by 은봉씨 | 2011/10/27 17:38 | 트랙백 | 덧글(0)
제 4회 S/W아키텍트 포럼(키노트) 요약

2011.7.7 참석한 S/W아키텍트 대회 포럼의 키노트 중 인상적인 내용에 대해 요약해보았습니다.

발표자의 발표자료를 첨부했으며, 제 개인적인 관점에서 해석하였음을 참고하세요.

 

  ------------------------------
  When Should You Consider Meta-Architecture?
  Joseph W.Yoder, refactory.com
  ------------------------------

 Meta-Architecture

   - code is data, data is code.
   - meta data : class, entry, attribute, relationship + rule, change-rule

   - 특성은 다양하지만 Pattern은 일정하다.


 Meta-Architecture 성공 전략

   - Behavior 에 대해서 4가지 종류로 정의했고, 여기에 포함되지 않은 비즈니스는 없다고 자부한다.

   - Common 한 Editor 제공으로 언어와 배경이 다른 사용자의 활용성을 극대화 시켰다.

   - easy to change and release new versions.


 Meta-Architecture 가 개발 패러다임에 변화를 이끈다.

   - 개발자의 programming 으로 소스코드가 생성되는 것
     ===> user or domain expert 의 설정으로 동작하는 시스템이 생성 되는 것


 Meta-Architecturing 시 고려 사항

   - Understand the rate of what changes.
   - Cloud components / Service are configurable.
    (물리적인 인프라 구성 요소에 대한 설정 뿐 아니라 서비스에 대해서도 설정이 필요하다.)
   - Strong design skill to create.
   - meta-data를 interpreting 한다는 것은 lower performance 이므로 해결 skill이 필요하다.
   - Don't overdesign.
   - version upgrade 시 기존의 서비스가 동작해야 하는지에 대한 검증과 같은 변화 관리가 필요하다.


  ------------------------------
  Business Architect
  박준성 KAIST
  ------------------------------

 기업의 경영 전략과 IT 전략

   - CTO 출신의 교수답게
     해외 사례(IBM)를 통해 본 기업의 경영 전략과 기업의 IT 전략의 alignment 를 강조 함

   - IT 전략은 1년, 3년, 5년의 단위로 수립된다.
     1년에 대해서는 자세하게, 3년과 3년의 단위의 전략 계획은 계속해서 업데이트.    
   - IT 3년 전략에 대해서는 실행 1년 전부터 관련 Resource 확보가 필요하다!!
     후발업체의 문제는 남이 다하니까 쟈 이제부터 시작하자라고 했을 때,
     실행할 전문가가 없다는 것이다.
     선발 업체들은 미래를 준비하는 인력에 대한 리소스 확보를 중요하게 생각한다.


 EA 활동에 대한 변화 제시
   - 전사 시스템 Application Map, 복잡한 그림들.. 누가 보나? 그런거 하지 말자.
     전사적 전략 관점에서 6개월 안에 ROI가 나오는 과제/프로젝트를 기획하는 활동을 하자.

   - BA -> BPM, AA -> SOA, DA -> MDM, TA - RTI


 Enterprise Level 의 SaaS Making Process

    1) MVC

    2) Components 

    3) Web Service(비즈니스 컴포넌트 중에 필요한 것만 서비스로 노출)
    4) SOA Governance (도출한 Service 의 활용도 증가)

    5) 서비스들 정련/정제 (사용하지 않는 것 정리)
    6) Build a stable digital pool foundation

    7) 누가 만들었던지, 어디에 있던지 사용할 수 있는 Common 한 Service 가 도출된다.
    8) SaaS

    - SaaS 는 위와 같은 과정을 거쳐야 한다. (SaaS == Extreame SOA)


 Cloud

   - 결국 Cloud 라는 것은 각 분야의 최고/최신 기술을 극대화 시켜서 모아놓은 것이라고 할 수 있다.
     Personal 이 아닌 Enterprise Level 에서는 아무나 못쓴다. Extream SOA 를 위한 준비가 필요.

 
 UnCertain Business 를 겨냥하는 Solution(Software) 개발 시 성공 요인 

   - 요구사항이 fix 될 수 없다.
   - Daily Build 는 기본, 어떤 facebook app 은 하루 20번의 Build 를 수행한다. (IMVU)
   - TDD 가 포함된 Agile 방법론 적용이 필요하다.
     TDD 가 빠진 Agile 방법론은 적용할 필요가 없다.

   - 사용자의 Feedback이 중요하다!! (IE, alpha/beta/공식 버전, 3차례의 feedback&보완)


 Think Software as a business
 Adaptive Development Method
 Middle Out Architecture


 Books

   - the business of software
   - secrets of software success
   

 Business Architect

  - 업무도 분석하고, SQL도 작성하라. 최대한 구현에 가깝게 설계할 수 있어야 한다.
  - SQL 도 작성할 수 없는 모델러는 필요없다.

 

 

P.S. 첫 번째 키노트 발표자인 Joe Yoder 씨는 Big Ball of Mud 의 저자로

     Agile과 아키텍처, 패턴 등에 전문성을 가지고 있습니다.

     프로그램 수정 없이 설정만으로........ 의 기반이 되는 Meta-Data Architecture 설계 시 참조할만 합니다.

 

     두 번째 키노트 발표자인 박준성 KAIST 교수님은 직접적인 화법으로 듣던 도중 속이 다 후련하더군요.

     SaaS 가 완성되는 프로세스와 준비된 Cloud 등의 대한 해석은 아주 명쾌했습니다.

by 은봉씨 | 2011/08/01 14:22 | 일단 퉁치자 | 트랙백 | 덧글(0)
JavaEE6 & Spring3.0 - Provider<T>

스프링 프레임워크를 이용할 경우에 빈들이 모두 Singleton 형태로 관리되나,

필요할 경우 Prototype Scope를 적용하여 필요할 때 마다 새로운 빈을 Inject 받을 수 있다.

 

그러나, bean 의 Scope 를 간단히 선언만으로 해결되지 않으며, 소스가 좀 별로다.

singleton bean 에서 prototype bean 을 참조해야 할 경우가 문제되기 때문이다.

 

하지만, javax.inject.Provider 인터페이스를 이용하면 깔끔하게 해결된다.

 

    Singlton Bean 에서 Prototype Scope 의 Bean 을 Inject 하는 예제

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration (locations = {"classpath:/META-INF/config/app-config.xml"})
public class SpringBeanScopeTest {

 

   @Autowired SingletonBean singletonBeanA;
   @Autowired SingletonBean singletonBeanB;
 
   @Test
   public void testSingltonBean() {

      // 싱글톤 빈은 아무리 변수를 달리 선언해도 동일한 오브젝트다.
      assertThat(singletonBeanA, is(singletonBeanB));
   }
 
   @Test
   public void testProviderBean() { 

      PrototypeBean prototypeBeanA = singletonBeanA.getPrototypeBean();
      PrototypeBean prototypeBeanB = singletonBeanA.getPrototypeBean();

 

     // 싱글톤에서 prototype 빈을 get 했을 때 매번 다르게 가져옴을 알 수 있다.
      assertThat(prototypeBeanA, not(prototypeBeanB));
   }
}

@Service
class SingletonBean {
 

   // prototype scope 로 선언 된 빈을 Provier<T> 로 Injection 받고 있다.
   @Autowired Provider<PrototypeBean> prototypeBeanProvider;
 
   PrototypeBean getPrototypeBean() {

      // Provider 로부터 객체를 받고 있다.
      PrototypeBean prototypeBean = prototypeBeanProvider.get();
      return prototypeBean;
   }
 
}

@Service
@Scope("prototype")
class PrototypeBean {
}

 

 

개발하다 보면,

매번 생성되어야 하는 클래스일 경우 spring bean 으로 등록하지 않으면 된다.

하지만, spring bean 으로 등록 된 다른 bean 을 사용하려면 일단 bean 으로 등록되어야 하기 때문에

위처럼 prototype scope 로 빈을 등록하고, 다른 singleton bean 에서 javax.inject.Provider 인터페이스를 통해 GET 하도록 한다.

by 은봉씨 | 2011/02/16 17:10 | 일단 퉁치자 | 트랙백 | 덧글(0)
Spring 3.0 새 기능 - Task

온라인 배치 혹은 war 로 구성되는 배치에 적용 가능성이 있어 보입니다.

 

가벼운 스케줄링을 위해 유닉스 크론 잡, 혹은 오픈소스 쿼츠. 를 많이 이용하는데요.

 

아. 정말 너무나 간단하게 스케줄링 되네요.

테스트 케이스 하나로,,Spring Task 소개합니다.

 

 

  Spring Task 로 간단하게 스케줄링 처리하는 테스트 케이스 작성 예제

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration (locations = {"classpath:/META-INF/spring/app-config.xml", "classpath:/META-INF/spring/task-config.xml"})
@Transactional
public class SpringTaskTest {

 

   @Autowired TemplateTask templateTask;
 
   @Test
   public void testFixedDelayTask() throws Exception {
     Thread.sleep(30000);
   }    
 
}

 

@Service
class TemplateTask {
 
   @Scheduled (fixedDelay=3000)
   public void fixedDelayTask() {
      System.out.println("3초 후에 실행합니다.");
   }
 
   @Scheduled (fixedRate=3000)
   public void fixedRateTask() {
      System.out.println("3초 간격으로 실행합니다.");
   }
 
   @Scheduled (cron="*/2 * * * * ?")
   public void cronTask() {
     System.out.println("크론 잡 정의 타입대로 2초마다 실행합니다.");
   }

}

 

@Service
class TemplateDaoTask {
 
   @Autowired TemplateDao templateDao;
 
   @Scheduled (fixedRate=5000)
   public void templateDaoTask() {
      System.out.println("5초 간격으로 넣었다 뺍니다.");
      String id = "taskId";
      String name="taskName";
      TemplateModel templateModel = new TemplateModel(id,name);
      templateDao.addTemplate(templateModel);
      templateDao.deleteTemplate(id);
   }
}

 

  Spring Task 설정 방법

 

Spring Task 관련 설정도 간단합니다.

task-config.xml 의 내용입니다.

 <context:component-scan base-package="springframework.test" />
 
 <task:annotation-driven/>

 

첫째 줄은, 해당 패키지로 시작되는 것중 @Scheduled 가 들어가 있는 것을 scan 하라는 의미이고,

두번째 줄은 이렇게 annotation 기반으로 주기적인 작업을 수행하겠다는 것을 의미합니다.

 

  외부 XML 파일로 스케줄링 하는 방법

 

        소스에  Annotation 으로 스케줄을 선언하는 대신 외부 XML 파일을 사용할 수 있습니다.

 

        <task:scheduled-tasks>

            <task:scheduled ref = "springTaskSample" method="xmlScheduledMethod" cron="*/1 * * * * ?" />

        </task:scheduled-tasks>

 

        아오.. 간단해도 너무 간단합니다.

        springTaskSample Bean 의 xmlScheduledMethod 메소드를 1초마다 돌리겠다는 설정입니다.

 

정리해보면.

그냥 온라인 war 에 올라가 있는 프로그램인데, 주기적으로 수행되어야 하는 경우가 있다면

별도의 스케줄러 없이 war 기동 시 spring container 가 @Scheduled 로 되어 있는 것을 식별하여

정해진 룰 대로 실행시켜준다는 의미입니다.

by 은봉씨 | 2011/02/16 17:08 | 일단 퉁치자 | 트랙백 | 덧글(0)
ProGuard - 자바 역컴파일 대응을 위한 난독기 적용

자바 언어는 역컴파일러에 의해 소스를 다 열어볼 수 있어서,

소스를 분석하고 싶은 개발자에겐 유용하지만, 소스를 보호하고자 하는 입장에선 난처하죠.

 

역컴파일이 아주 안 되게 할 수는 없고,

역컴파일 해서 소스를 열어본다하더라도,

해석하기 어렵도록 소스의 변수명 혹은 메소드 명을 바꾸는 방식의 난독기가 있습니다.

 

상용으로 사용하는 경우에만 GPL 이 적용되는 오픈소스 난독기인 proguard 를 이용한 경험을 공유하겠습니다.

Maven Project 기반입니다.

 

o maven dependency 추가

 

    <!-- proguard -->
    <dependency>
        <groupId>net.sf.proguard</groupId>
        <artifactId>proguard</artifactId>
        <version>4.4</version>
    </dependency>

 

o maven plugin 추가

 

  <build>

    ...

    <plugins>
      <plugin>
        <groupId>com.pyx4me</groupId>
        <artifactId>proguard-maven-plugin</artifactId>
        <version>2.0.4</version>
      </plugin>
    </plugins>

     ...

   </build>

 

 o maven plugin management 추가 및 설정

 

   사실 이부분에서 좀 헤맷습니다. 라이브러리 포함/미포함 관련 설정이 '완벽'해야 하거든요.

   난독기를 적용하고 싶은 대상 소스가 참조하는 라이브러리에 대해서는 난독기 적용이 안되도록 설정해야하니까요.

   Out Of Memory 도 발생하고, 시행착오가 많았습니다.

 

   <build>

    ...

     <pluginManagement>

      <plugins>

        ....

 

        <plugin>
            <groupId>com.pyx4me</groupId>
            <artifactId>proguard-maven-plugin</artifactId>
            <version>2.0.4</version>
            <executions>

               <!-- install 단계에서 proguard goal 을 쓰겠다는 설정 -->
               <execution>
                   <phase>install</phase>
                   <goals><goal>proguard</goal></goals>
               </execution>
            </executions>
            <configuration>
                <skip>false</skip>
                <obfuscate>true</obfuscate>
                <addMavenDescriptor>false</addMavenDescriptor>
                <injar>${project.build.finalName}.jar</injar>
                <injarNotExistsSkip>false</injarNotExistsSkip>

                <!-- 최종 output 파일의 이름 -->
                <outjar>${project.build.finalName}-obfuscated.jar</outjar>
                <outputDirectory>${project.build.directory}</outputDirectory>
                <includedepedency>false</includedepedency>
                <libs>
                    <lib>${java.home}/lib/rt.jar</lib>
                    <lib>${java.home}/lib/jsse.jar</lib>
                </libs>

                <!-- 메모리 부족 에러를 만난다면. 아래처럼 추가해주면 됩니다. -->
                <maxMemory>512m</maxMemory>

                <!-- 자세한 설정을 한 외부 파일 경로 지정 -->
                <proguardInclude>${basedir}/proguard.conf</proguardInclude> 

                <assembly>

                    <!-- com.xxx.yyy 를 난독기 적용 대상으로 삼겠다는 설정 -->
                    <inclusions>
                        <inclusion><groupId>com.xxx</groupId><artifactId>com.xxx.yyy</artifactId></inclusion>
                    </inclusions>
                </assembly>

                <!-- 난독기 적용 대상 소스가 참조하는 라이브러리에 대해서 관련 그룹이 아닌것은 제외하겠다는 설정 -->
                <exclusions>
                    <exclusion><groupId>!com.xxx</groupId></exclusion>
                </exclusions>
            </configuration>
        </plugin>

      ...
      </plugins>
    </pluginManagement>

    ...

  </build>

 

 o Proguard 상세 설정 파일 (proguard.conf)

 

   pluginManagement 의 plugin 설정 시 configuartion option 으로 모두 지정할 수 있으나,

   별도 파일로 뽑아보았습니다.

   핵심은 맨 아랫줄입니다.

 

   -verbose
   -dontoptimize
   -dontshrink
   -keep public class * { public protected *; }

 

   로그를 보겠다.

   압축 같은 optimzie 하지 말아라

   사용하지 않는 라이브러리 없애는 거와 같은 shrink 는 하지 말아라

   public class 의 public/protected 메소드는 난독기 적용을 하지 말아라는 거죠.

 

 o 난독 적용 명령어 실행

 

   maven eclipse plugin 에 명시적으로 goal 이 보이지 않으므로 별도로 실행시켜야 합니다.

 

   Run As --> Maven Build .. -> proguard:proguard

 

   install 한 output jar 를 input 으로 받아 난독기를 적용하므로, maven install 을 먼저 실행해야 합니다.

 

 o 난독 적용 결과 확인

 

   역컴파일을 해 보면 public class 의 public/protected method 는 큰 변화가 없을겁니다.

   다만, private 변수와 메소드는 a,b,i,j 등과 같은 허접한 이름으로 바뀌어져 있음을 확인하실수 있을겁니다.

 

   참고로.. proguard_map.txt, proguad_seed.txt 와 같은 파일을 생성해주므로 자세한 로그로 활용할 수 있습니다.

 

 o 난독 적용 전 후 역컴파일 내용 비교 샷

 

  일단 커멘트는 다 사라지고요.

   변수 이름이 a,b 이렇게 바뀝니다.

   난독기를 적용했다고 하더라도 동작은 해야 하고, 말그래도 소스를 해석하기 어렵도록 하는 것 뿐입니다.

   복잡한 소스의 경우 난독기 적용 옵션을 적절히 조정하면,, 역컴파일로 따라가면서 소스 분석하는게.. 짜증나겠지요.

 

   예전에,, 모 was 업체의 소스를 역컴파일 해서 보던 중에

   클래스 이름이 a,b,c... 변수 이름이 i,j.. 로 되어 있어서 결국 분석을 포기했던 시절이 있었지요.

   소스의 depth 가 깊어졌을 경우 소스 가독성은 현격히 떨어질 수 밖에 없을 것입니다.

 

 

 o 기타

 

   - ProGuard 가 난독기만의 기능이 있는 것은 아닙니다.

     소스 최적화(Optimizer, 압축, 사용하지 않는것 걸러내는 등) 의 기능도 있습니다.

 

   - ProGuard 가 Maven 으로만 동작하는 것은 아닙니다.

     ANT 도 되고, 그냥 Java 로 실행해도 되고, 요즘에는 Android 에서 많이들 사용하는 것 같더군요.

 

   - ProGuard 의 GUI 버전도 있습니다. 사용법은 직관적입니다.

 

 o 참고 URL

 

   http://proguard.sourceforge.net/index.html

    http://pyx4me.com/pyx4me-maven-plugins/proguard-maven-plugin/


 

// 처음에는 난독기 적용 자체를 위한 환경 설정에 신경을 썼는데,

    실제로, -keep public class * { public protected *; } 와 같은 옵션을 적용하기 전에는

    모든 소스가 다 이름이 바뀌어져 있더군요. ㅎㅎㅎ

 

    구글같은데서 검색해보면.

    난독기 적용 후 ClassNotFoundException 이나 ClassForName 으로 가져올 때 에러난다는.. 질문이 많더라구요.

    세상 사람 다 비슷한가봅니다.

 

    대체 '어디에' 난독기를 적용할 수 있을까? private 영역 뿐이겠는걸..이란 생각이 되더라구요.

    더불어 소스 개발 시 public or private 에 대해 한번 더 고려해야겠지요.

by 은봉씨 | 2011/01/18 12:25 | 일단 퉁치자 | 트랙백 | 덧글(2)
maven 이 뭐냐구요? CI 만 하면 TDD 로 하는거냐구요?

흠. 이런 난감한.. ㅎㅎ

----------
혹시 ANT 는 아시나요? 예에.. 그것이랑 비슷하게 소스 컴파일하고 압축하고 하는 도구입니다..
Make 아시나요? 네.. ANT 는 C 언어 컴파일 할 때 작성하는 Makefile 과 같은 것을 Java 진영에서 즐겨 사용하는 겁니다..
----------

대충.. 저렇게 화두를 꺼내보죠. 실은, SVN, CI (Continous Integration), NEXUS, xUnit... 갈 길이 멉니다.

그전에 우리는 자바 언어로 무언가를 개발한다고 가정을 해봅시다.
(뭐, 꼭 자바 언어가 아니라도 좋습니다.)

Makefile 을 안 써도, ANT 를 안 써도, MAVEN 을 안 써도,,
.java 를 짜고, .class 로 컴파일 하고, 테스트 해본 담에 .jar 혹은 .war 와 형태로 만들어 was 에 올리겠죠.
그리고 화면을 띄워 테스트 해볼겁니다.

특별할 게 없습니다. 하지만 우리는 혼자 일하지 않죠. 아니 심지어 혼자 일 하더라도..
컴파일 하려면 [클래스 패스] 가 필요하고, [라이브러리] 를 copy 하여 쓸 경우가 있습니다.

어렵지 않죠. 라이브러리 가져와서 classpath 에 다 잡아놓고 컴파일 하면 되니까요.
이클립스는 저장만 하면 컴파일 해주잖아요. 그리고 was 에도 배포(auto publish) 해주잖아요.

그런데요.
혼자 개발한 작은 웹 시스템에 대해 다른 사람과 공유하거나, 자꾸자꾸 재사용할 일이 생긴다는거죠.
그럴 때 마다 classpath 에 잡아줘야하는 라이브러리는 늘어나고, 내가 작성한 프로그램도 다른 사람에게 줘야하고..

프로젝트를 하다보면,, apache-commons 관련 라이브러리를 얼마나 많이 카피하게 되는지 모릅니다.
시스템 별로 WEB-INF/lib 에 카피 다~~~~ 하죠. 버전 바뀌면 또 다~~~~ 찾아서 바꿔줘야 하죠.

이 때 발생하는 문제..

 - 내 피씨에선 잘~~ 도는데 (정말?) 개발 서버에만 올리면 안 되요. 개발 서버 설정이 잘 못 된거 같아요.
 - ClassNotFoundException.. jar 올렸다니까.. 뭐? 유닉스에선 대소문자를 구별한다고?
 - NoClassDefError .. jar 도 올리고 WEB-INF/lib 에도 넣었는데.. 뭐? 시스템 클래스 패스에도 있어서 쫑 난다구?
 - 어렵게 어렵게 전문가 섭외 해 와서 문제 보여주면 라이브러리 하나 path 에 안 잡혔다고 하더군요..

아.. 아주 저런 말들 들으면. 그냥 딱 지겹습니다.
이젠 저러지 말아요. 체계화 된 프로세스로 진행해봅시다.

어떤 도구를 사용하느냐는 중요하지 않지만요. 그 도구를 어떻게 적용하냐는 정말 중요한 것 같습니다.
그리고 도구를 설치했다고 해서 그게 전부는 아니라는 것이지요.

우리는 보다 근본적으로 접근할 필요가 있습니다.

즉, 시스템을 개발할 때는 '빌드'와 '릴리즈'에 대해
[정책] 을 정하고 [프로세스]를 수립하여 [도구]로서 지원해야 한다는 것이지요.

 - 컴파일을 얼마나 오류 없이 똑 같은 작업으로 반복해서 쉽게 수행할 수 있느냐
 - 컴파일 결과를 수작업이 아닌 자동으로 반복적으로 테스트 하면서 검증할 수 있느냐
 - 문제 없이 돌아가는 시스템을 언제, 어떤 단위로, 어떻게 배포할 건가
 - 요런 진행 되는 사항을 한 눈에 확인할 수 있는 모니터링 할 수 있는 방법이 있느냐


결국 기본적으로 고려하여 해결해야 할 것은 위의 4가지가 아닌가 합니다.
저것을 위해서 우리는 CI 를 하고 TDD 를 하는것이겠지요.

현재 U-City 관련하여 프로젝트를 막 시작하고 있는데요.
단순히 허드슨을 설치한다고 TDD 가 되는 건 아니라는 걸 이해시켜야 했습니다.

MAVEN 이 너무 어려워서 2주 동안 컴파일을 못하고 있는 개발자도 속출했습니다.. 두꺼운 메이븐 책을 사시더군여..ㅠㅠ

자. 천천히 정리해보겠습니다.

by 은봉씨 | 2010/09/13 18:06 | 일단 퉁치자 | 트랙백 | 덧글(0)
친절 모드로 변신하자.
얼마만이지..

강의 때만 사용하던 문서들을.. 블로깅을 통해 정리를 다시 해보려고 한다..

이 블로그도 얼마만에 방문한건지. 예전에 쓴 글을 읽어봤더니.. 까칠해보이는군.

친절 모드로 변신하셔야지. :)
by 은봉씨 | 2010/09/13 17:11 | 일단 퉁치자 | 트랙백 | 덧글(1)
평생 개꼴을 면치 못한다.
글의 기본 재료는 단어이다.

어떤 분야에서든지 성공하고 싶다면 기본을 무시하지 말아야 한다.

서당개 삼 년이면 풍월을 읊고 성당개 삼 년이면 복음을 전파한다.

그러나 기본을 익히지 못하면 서당개도 성당개도 평생 개꼴을 면치 못한다.


                                                                            - 이외수, 글쓰기의 공중부양 첫 단락 -
by 은봉씨 | 2008/04/22 18:01 | 일단 퉁치자 | 트랙백 | 덧글(0)
내가 누구게?


- "노래하냐구요? 글쎄요, 사람들이 깨닫진 못하고 있지만 전 클래식한 연습을 해왔습니다. 바그너를 좋아하죠.

- "멋있어 보이고 싶어하는 여러분의 지치고 애처롭고 움츠러든 괄호를 저에게 줘보세요."

- "그럼요, 전 수상 스포츠를 좋아해요. 사실, 전 '포인트 브레이크'의 엑스트라랍니다. 그리고 '블루 크러시'에서는 주연을 맡았죠."

- "전 그들만큼 터프해요... 몇 년 동안 전쟁에도 몇 번 참가했었다니까요." 


                                                                                                                                        - 출처: Head Rush Ajax -

---------------------------

정답은? 브라우저다.

  - 오페라라는 브라우저가 있으니까
  - 브라우저가 Tag 를 파싱해서 보여주니까
  - 브라우저로 웹 서핑 한다고 하지
  - 모질라 파이어폭스와 엠에스 아이이 브라우저와의 전쟁

---------------------------

by 은봉씨 | 2008/04/22 17:47 | 일단 퉁치자 | 트랙백 | 덧글(0)


< 이전페이지 다음페이지 >