2012년 4월 23일 월요일

Arquillian: So you can rule your code, Not the bugs


So you can rule your code, Not the bugs.
No more mocks. No more container lifecycle and deployment hassles.
Just real test!

Arquillian 어원



영화 "Men in Black”에 나온 외계인, 사람 형태의 로봇에 타고 있는 작은 외계인 종족이 "Arquillan”

Arquillan의 3가지 원칙
1. Tests should be portable to any supported container
2. Tests should be executable from both the IDE and the build tool
3. The platform should extend or integrate existing test frameworks

Arquillan의 Feature

1. Real Tests
Mocks can be tactical, but more often than not, they are used to make code work outside of a real environment. Arquillian let's you ditch the mocks and write real tests. That's because Arquillian brings your test to the runtime, giving you access to container resources, meaningful feedback and insight about how the code really works.

2. IDE Friendly
The learning curve for getting started with Arquillian is minimized by the fact that it integrates with what you already know. Using JUnit for your unit tests? Then you can reuse your knowledge of JUnit to do integration testing. TestNG? Arquillian let's you choose. And you can even run your Arquillian tests right alongside unit tests in your IDE.

3. Test Enrichment
Your application and tests can share the same programming model, regardless of technology stack. For example, Arquillian can inject the deployed Contexts and Dependency Injection (CDI) beans, Enterprise JavaBeans (EJB) components and other Java EE resources directly to your tests. Arquillian can also extend that programming model to provide access to container APIs and implicit objects from test frameworks such as JSFUnit and Selenium.

4. Classpath Control
Most test suites are a mess, but it's not your fault. Test frameworks carelessly use whatever classes and resources are on the classpath of the test, making isolation of the test scenario difficult and turning the test suite into a Frankenstein. Not Arquillian. Micro-deployments are much smaller than the full application, so the test archive deploys faster, which means you get a faster test-code-test development cycle.

5. Drive the Browser
Arquillian is just as relevant for client testing as it is for server-side testing. Arquillian Drone abstracts away all the tedious setup of the Selenium Server, letting you skip right to driving the browser from your test. Arquillian even unifies client and server-side testing, most apparent in our JSFUnit integration.

6. Debug the Server
Arquillian brings you server-side debugging like never before. Typically, you have to package the application, deploy it to the server, connect the debugger and interact with the UI in order to hit the breakpoint. Now you can just drop a breakpoint in the test or application code and debug the test. Bang, you hit the breakpoint inside the server from the comfort of your IDE. Prepare for an eye opening experience!

7. Container Agnostic
You name the container, Arquillian can manage it. If not, why not write an adapter? Having the choice of multiple containers allows you to switch from an embedded container in development to a standalone server for continuous integration, test on different compliant containers to ensure application portability, or even interact with several containers in the same test to validate distributed behavior.

8. Extensible Platform
There's no limit to what you can test using Arquillian. Many extensions are available. If you're looking for an integration that's not yet implemented, Arquillian provides an extensible platform into which you can integrate that next great testing tool.

9. Strong Tooling
Want to take the quick path to getting started with Arquillian? Tools like JBoss Forge can help. Just install the Arquillian plugin, set it up in your project, and get started writing tests in seconds. You'll be amazed how easy it is to get started with Arquillian and Forge - it's the next enterprise evolution.

2012년 4월 13일 금요일

사용자 행위 로그를 이용한 모바일 어플리케이션의 사용성 분석 기법

소프트웨어 어플리케이션이 사용자에게 효율적인 서비스를 제공하는데 있어 사용자 인터페이
스는 중요한 요소이다. 특히, 언제 어디서나 실행 가능한 모바일 어플리케이션의 특성상 다른 도메인의 어플리케이션 보다 소프트웨어의 품질 속성 중에서 사용성의 우선순위가 높다. 현재까지 소프트웨어 어플리케이션의 사용성 향상을 위해 기존 연구에서는 프로토타입과 스토리보드방식을 활용하여 해당 어플리케이션의 사용성에 대해 설문을 하는 방식으로 사용성을 측정하여 문제점을 식별하고 개선시켜왔다.
하지만, 이러한 방식은 특정 어플리케이션의 사용성 관련 문제점을 지속적으로 식별하고 개선하기 위해서 매번 설문을 진행해야하는 한계점이 있다. 따라서, 본 논문에서는 어플리케이션이 배포된 후에도 지속적으로 사용자의 의도를 파악하여 어플리케이션의 문제점을 식별하고 개선시켜 나가기 위해 사용자 행위 로그를 이용해 어플리케이션의 사용성을 분석하는 기법을 제안하고 있다.
제안된 기법의 실효성 검증을 위해 안드로이드폰에 탑재되어 제공되는 모바일 어플리케이션을 대상으로 본 기법을 적용하고 그 결과를 분석하였다.

문서보기

2012년 3월 14일 수요일

Integration Framework Comparison

Java code Geeks에 가장 많이 사용하는 Integration Framework 3가지 “Spring Integration”, “Mule ESB”, “Apache Camel”에 대해서 비교 분석한 Post가 올라와 있어서 간략히 정리해 보도록 하겠습니다. 원문은 아래 링크를 따라 가시기 바랍니다.

원문 보기

현재도 그렇지만 앞으로는 더욱더 회사 간 또는 어플리케이션 간에 데이터 교환이 더 빈번히 많아지고 그 필요성도 커지는 건 당연한 일입니다. 이런 일을 위해서 Enterprise Integration Patters(EIP)가 발표되었고 이를 충실히 구현한 Open source EIP Framework이 위에서 언급한 3가지 입니다.

Spring Integration

  • Spring project을 기반으로 개발되어 있어, Spring Project에 쉽게 추가.
  • Spring을 잘 안다면 쉽게 사용 가능.
  • 기본적인 Connector만 지원(File, FTP, JMS, TCP, HTTP, JDBC,WebService)
  • 기존 Spring project에 EI 기능을 추가한다면 적극 추천.

MULE ESB
  • EI 기능외에 Full ESB 기능이 포함되어 있음.
  • SAP, Tibco Rendevous, Oracle Siebel CRM, Paypal, IBM’s CICS Transactioin Gateway와 같은 특화된 Connector을 제공.
  • 특화된 Connector가 필요하다면 추천.

Apache CAMEL
  • Mule ESB 만큼 많은 Connector 제공.
  • IDE 툴은 “FuseSource”, “Talend”에서 따로 제공하나 많은 양의 Boilerpalte code을 발생시킴. 
3 가지 중 승자는 없는 것 같습니다. 개인적인 판단에 따라 사용하시길. 


원문 저자는 개인적으로 Apache Camel을 선호한다고 합니다. Spring Project는 싫고(전 Post에서 언급되지만 원저자는 Spring을 싫어 합니다), 특별한 Connector도 필요 없기 때문에.

2012년 3월 12일 월요일

Why I will use Java EE instead of Spring in new Enterprise Java Projects in 2012

Java Code Geeks에 포스팅 된 글입니다.
이 글의 필자는 JEE(J2EE가 아닙니다.)가 보다 활성화 되었으면 하는 의도에서 이 글을 작성 한 것 같습니다.
또 한 필자는 Enterprise Java Project에서 표준 기술인 JEE 보다 Spring(이는 비 표준 기술입니다.)의 역할이 크고 사람들이 열광 하는 것에 못 마땅하게 생각하고 있음을 알 수 있습니다.  그리고 언급하고 있는 이야기를 요약하면 다음과 같습니다.

  1. 과거 J2EE는 무겁고, 크고, 불편했다. 이를 해결해준 것이 Spring이다. Spring이 Enterprise Java 환경에 미친 영향은 실로 막대하다.
  2. 우리가 흔히 말하는 J2EE는 이미 죽었다. 지금은 JEE(Java Enterprise 5 이후) 시대이며 JEE는 Spring과 다른 Framework으로 부터 장점만을 훔쳐서(“STOLE”) 훌륭하게 발전 되었다.
  3. JEE는 “Standard specification”이다. 이는 Vendor Independent을 가지게 한다.
  4. 앞으로는 JEE기반의 Enterprise Java Project가 많아 질 것이다.
필자가 너무 JEE을 옹호하는 발언을 하므로 몇몇 개발자들의 원성도 사고 있군요. 하지만 중요한 사실은 JEE는 이제 Spring을 대적할 수 있을 만큼 안정적이고, 빠르고, 편리해 졌다는 것입니다.

원문보기

2012년 3월 5일 월요일

I don't know, what is GlassFish?

Why the name GlassFish?
개발자 중 한명인 Eduardo가 말한 “transparent development”(투명한 개발), 다른 개발자가 “비쳐 보인다”라고 말하므로서 개발의 투명성을 묘사하는 GlassFish라 명해졌습니다.

GlassFish는 Java EE을 지원하는 Open source Application server 입니다.
GlassFish(현재 3.1.2)는 Java EE 6의 모든 기능을 완벽히 구현하였습니다.

GlassFish vs Tomcat
GlassFish는 Java EE Container에 속해 있는 반면, Tomcat은 Servelt과 JSP만 지원하는 Servlet Container 이다.

Tomcat 상에서 구동되는 어플리케이션은 GlassFish에서도 그대로 사용이 가능.

두드러진 차이점

  • GlassFish를 이용하면 EJB, JPA, JMS 등의 이점을 확실하게 누릴 수 있다. 반면에 Tomcat의 경우 상기의 기술을 개별적으로 추가해 줘야 하는 번거로움이 있으며, 개발자는 그 기능을 일일이 확인해야 한다. 
  • GlassFish가 제공하는 클러스터링과 정교한 고가용성 기능은 어플리케이션이 엄격한 엔터프라이즈급 SLA를 충족 할 수 있도록 설계되었다. 
  • GlassFish는 관리자 콘솔과 Command Line Interface를 이용한 중앙식 관리 방식을 지원하고 있고, Callflow Monitoring 기능은 어플리케이션 개발자 또는 서버 관리자가 어플리케이션 개발자 또는 서버 관리자가 어플리케이션이 가장 많이 사용되는 영역을 파악할 수 있도록 도와줍니다. 
  • GlassFish는 Ruby/JRuby, Python/Jython, Groovy, PHP, JavaScript/Phobos, Scala 같은 다양한 스크립팅 언어를 지원합니다. 
  • GlassFish는 어플리케이션 재배포시 세션을 유지시킬 수 있어 개발자가 단기간에 Java 웹 어플리케니션을 개발할 수 있도록 도와 줍니다. 
  • GlassFish는 서버를 재시작 하지 않고 가상 서버와 HTTP Listener를 동적으로 재구성할 수 있게 해줍니다. 
  • GlassFish 하위 웹 티어는 Grizzly Framework을 통해 구현되었는데, Java로 제작된 이 프레임워크는 NIO API의 이점을 최대한 활용함으로써 높은 확장성 뿐 아니라 고도의 커스터마이징 능력까지 제공합니다.

Sun에서는 Tomcat의 NIO Connector와 GlassFish를 비교했습니다. 이 테스트에서는 컨테이너에서의 시간 소모를 최소화하기 위해 단순한 Servlet이 이용되었고, 사용자 증가와 관련해서 각 종 컨테이너가 지원할 수 있는 능력(작업/초)이 측정 되었습니다. 16,000명의 사용자가 접속했을 경우의 결과는 다음과 같습니다.

성능상 비교

GlassFishTomcat
작업/초6988.96615.3
평균 응답 시간0.2420.358
최대 응답 시간1.5193.693
90% 응답시간0.60.75

2012년 2월 29일 수요일

Twitter4j 와 Esper를 이용한 타임라인 분석 기법

최근 구독한 Article에서 Twitter4j와 Esper(Complex Event Processing analytic tool)을 이용하여 Twitter 상에서 발생한는 Data feed에서 의미있는 정보를 도출하는 아이디어가 있어 정리해봅니다.

Esper는 CEP 분석 도구로는 가장 좋은 평가를 받고 있습니다. GPL 라이센스 적용을 받고 있어서 이를 이용한 sofeware는 모두 Open source로 공개 되어야 합니다. 저에게는 이게 발목을 잡아서 사용하지 못하였습니다.

Article의 목적은

*Twitter 타임라인에 행복한 사람이 얼마나 많은지 찾아본다.

타임라인에 “Happy” 글이 얼마나 자주 올라 오는지 알아봅니다. 복잡할건 하나도 없습니다. Esper가 다 해줍니다.

CEP을 이해하기 위해서는 Window라는 개념을 알아야 합니다. 간단하게 설명해 보기로 하겠습니다.

지금 밖에는 2줄기 비가 내립니다.
한 줄기는 시간 입니다.(초 단위)
다른 한줄기는 Twitter의 글들입니다.

1. 나는 지금 밖이 보고 싶어서 벽에 다가 창문을 뚫으려고 합니다.
2. 창문 높이는 2초 쯤 되고, 넓이는 2줄기 비를 볼 수 있을 정도를 뚫습니다.
3. 뚫린 창문으로 내리는 비를 지켜 봅니다.
4. 창문으로 보이는 Twitter 글 중에 “Happy” 라는 단어가 2번 이상 보입니다.
5. 사람들이 행복하다고 판단합니다.

위의 벽에 뚫린 창문이 CEP에서 Window라고 합니다. 밖에서 내리는 수많은 Event 중에서
내가 원하는 것만 보기 위해서 뚫어둔 창문입니다.

Esper에서는 창문을 뚫고 지켜보는 행동을 SQL 문장과 비슷하게 정의해서 등록하게 됩니다. 아래처럼.

select user, sum(ctr) from com.sybase.simple.HappyMessage.win:time(10 seconds) having sum(ctr) > 2


그런데 중요한 맹점이 하나 있는데. 아래 두 문장에 모두 “happy”가 들어가지만 의미는 반대라는 겁니다. 이런 문제는 문장 의미분석이 필요한 부분이겠습니다.

-> I'm happy.
-> I'm not happy.


보다 자세한 내용은 원문 전체를 읽어보시기 바랍니다.

원문 보기

2012년 2월 23일 목요일

안드로이드 플랫폼에서 애플리케이션 간 객체 전송을 개선하기 위한 메타서비스의 설계 및 구현


최근 안드로이드 기반의 스마트 폰이 널리 사용되고 있으며, 이를 이용한 다양한 응용이 개발중이다. 그 중 한 애플리케이션에서 생성한 데이터를 다른 애플리케이션으로 전달하는 경우가 빈번하게 발생한다. 그러므로 한 애플리케이션에서 발생하는 메타데이터를 다른 애플리케이션으로 쉽게 전달하거나 공유할 수 있는 방법이 필요하다.

안드로이드에서 애플리케이션이 생성한 메타데이터는 Java 객체로 만들어진다. 안드로이드에서 기존의 데이터 전달 방법으로는 클립보드와 인텐트 그리고 컨텐트 프로바이더가 있다. 하지만 이 방법들은 모두 레코드 형태로 데이터를 전달하도록 되어 있다. 그러므로 개발자는 객체를 전달하기 위해 마샬링과 언마샬링하는 과정을 직접 구현해야 한다. 본 논문에서는 애플리케이션에서 만든 임의의 타입의 객체를 전송할 수 있는 메타서비스를 설계하고 구현하였다. 메타서비스를 이용할 경우 클립보드와 컨텐트 프로바이더에서 객체를 전송하기 위해 구현해야하는 복잡한 과정을 줄여서 버그를 줄이고 코드를 간단히 작성할 수 있도록 하여 생산성을 증진 시킬 수 있도록 하였다.


문서보기

2012년 2월 22일 수요일

Android 촬영 사진의 회전 각 알아보기

Android에서 촬영한 사진이나 앨범에서 사진을 Server Side로 전송하는 부분을 개발하다 보니 Vender 마다 차이가 있었다.

무슨 문제가 있었던 것일까?

LG Phone
세로 모드로 사진 촬영: 정상
가로 모드로 사진 촬영: 정상

Sam Sung Phone
세로 모드로 사진 촬영: 90도 회전 된 이미지가 전송
가로 모드로 사진 촬영: 정상

How can we do it?

  1. Android에서 촬영된 사진은 “Orientation” 이라는 “Tag”가 존재하는데 이 Data로 사진을 촬영할 때의 Degree을 알 수 있습니다.
  2. “1”번으로 Degree을 알아 보고 그 각도만큼 회전 시킨 이미지를 생성하면 됩니다.

아래는 1,2 번에 해당되는 Code을 Googing  찾아봤습니다.

/**
* 이미지 회전 각도를 알아옴.
* @param filepath
* @return 각도
*/
public synchronized static int getPhotoOrientationDegree(String filepath)
{
int degree = 0;
ExifInterface exif = null;
try
{
exif = new ExifInterface(filepath);
}
catch (IOException e)
{
Log.d(PhotoUtil.class.getSimpleName(), "Error: "+e.getMessage());
}
if (exif != null)
{
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);
if (orientation != -1)
{
switch(orientation)
{
case ExifInterface.ORIENTATION_ROTATE_90:
degree = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
degree = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
degree = 270;
break;
}

}
}
Log.d(PhotoUtil.class.getSimpleName(), "Photo Degree: "+degree);
return degree;
}

/**
* 이미지를 특정 각도로 회전
* @param bitmap
* @param degrees
* @return
*/
public synchronized static Bitmap getRotatedBitmap(Bitmap bitmap, int degrees)
{
if ( degrees != 0 && bitmap != null )
{
Matrix m = new Matrix();
m.setRotate(degrees, (float) bitmap.getWidth() / 2, (float) bitmap.getHeight() / 2 );
try
{
Bitmap b2 = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
if (bitmap != b2)
{
bitmap.recycle();
bitmap = b2;
}
}
catch (OutOfMemoryError e)
{
Log.d(PhotoUtil.class.getSimpleName(), "Error: "+e.getMessage());
}
}
return bitmap;
}

Issue
이런 문제도 있을수 있습니다.
요즘 스마트폰이 좋아 사진 한 장 당 크기가 2M를 넘어갑니다. 이 정도 크기를 Server Side로 전송하는데 시간이 많이 걸리고 요금도 무시 못하기기 때문에, iPhone 이든 Android 든 모든 이미지 압축을 하여 전송하게 됩니다. 그런데 이미지을 압축 하면 위의 Degree 값이 0이 됩니다.
압축 전에 원본을 돌려 놓고 압축해야 합니다.

2012년 2월 15일 수요일

20 Database Design Best Practices


100% 공감이 가는 내용이 있어 포스트 합니다.
원문 링크: http://www.javacodegeeks.com/2012/02/20-database-design-best-practices.html

대충 아래와 같은 내용입니다.

  1. 테이블과 컬럼에 잘 정의된 일관된 이름을 사용한다.
  2. 테이블 이름은 단수를 사용
  3. 테이블 이름에 공백을 사용하지 않는다.
  4. 테이블 이름에 불필요한 접미어, 접두어를 사용하지 않는다.
  5. 보안을 위해 비밀번호는 암호화를 유지, 복호화는 어플리케이션안에서 필요할 때 사용 한다.
  6. 모든 테이블에 Integer ID 필드를 사용한다. 당장은 필요 없더라도 앞으로 필요할 때가 반드시 있습니다.
  7. 인덱싱은 Integer 데이터 타입을 사용합니다. varchar 컬럼 인덱싱은 성능에 문제가 있습니다.
  8. Boolean 값은 bit 필드를 사용합니다. Integer또는 varchar을 사용하면 불필요한 공간을 더 사용하게 됩니다. 그리고 반드시 컬럼 이름은 “Is”로 시작합니다.
  9. 데이터베이스 접근을 위한 권한 인증에 신경씁니다. 모든 사용자에게 관리자 권한을 주어서는 절대 안됩니다.
  10. select 문장을 사용할 때 “*” 사용을 피해야 합니다. 반드시 컬럼명을 명시해서 사용해야만 보다 좋은 성능을 보장 받을수 있습니다.
  11. ORM(Object Relational Mapping) Framewokr을 사용하는 경우, 특히 어플리케이션에서 ORM Code 충분히 크다고 생각되는 경우, ORM Framework의 성능 이슈를 잘 파악하고 이에 대해 적절한 세부 설정을 처리해야 한다.
  12. 크고 사용하지 않거나, 좀처럼 사용하지 않는 테이블들은 서로 다른 물리적 스토리지에 나누어 사용하면 쿼리의 성능이 좋아집니다.(물리적 디스크 I/O을 고려해서 잘 사용하는 테이블을 적당히 나눠야 좋다는 이야기)
  13. 크고 민감한 중요한 데이터베이스 시스템은 장애조치 클러스터링, 재해복구 시스템, 자동 백업, 복제 등 같은 보안 서비스를 사용하는게 좋습니다.
  14. 데이터 무결성위한 제약 조건 foreign key, not null 등을 사용합니다. 어플리케이션 코드에서 이것을 무시할 수 있게 하면 안됩니다.
  15. 데이터베이스 문서화 부족은 악마와 같습니다. ER 스키마와 지침을 사용하여 데이터베이스 문서를 작성하고, 또한 주석 라인을 적극적으로 사용합니다.
  16. 큰 테이블에서 자주 사용되는 쿼리에 대해 인텍스를 사용합니다. 분석 도구를 사용하여 인덱스를 정의할 컬럼를 결정하는데 도움을 받습니다. row의 범위를 검색하는 쿼리의 경우 클러스터링 된 인덱스는 일반적으로 성능이 좋습니다. 그리고 point 쿼리의 경우 클러스터링이 안된 인덱스가 성능이 좋습니다.
  17. DB 서버와 Web 서버는 반드시 다른 머신에 설치되어야 합니다. 보안, CPU 성능, 메모리 성능 등 모든 면에서 좋습니다.
  18. 이미지나 BLOB 데이터는 자주 쿼리 되는 테이블에 정의해서는 안됩니다. 성능의 문제가 있을 수 있기 때문입니다. 이런 데이터는 테이블을 분리하고 데이터를 찾을 수 있는 포인터 정보를 자주 쿼리 되는 테이블에서 가지고 있게 해야 합니다. 
  19. 정규화(Normalizatioin)는 성능을 최적화 하기 위해서 필요에 따라 사용해야 합니다. 정규화가 잘 안되어 있으면 데이터의 과도한 중복(반복)을 초래하게 되고, 정규화가 너무 잘 되어 있으면 데이블간의 Join이 과도하게 생기게 됩니다. 이 둘은 모두 성능에 나쁜 영향을 미치게 됩니다.
  20. 데이터베이스의 모델링, 디자인에 충분한 시간을 투자 합니다. 그렇지 않으면 디자인 타임에 해결될 문제가 유지보수 시점까지 간다면 그 시간은 10배, 100배, 1000배 늘어나게 됩니다.

2012년 2월 13일 월요일

Json Java pasers / generators Benchmark




Mobile환경의 확대와 Open API 사용의 증가와 더불어 Json을 사용하는 프로젝트가 증가하고 있습니다. Json은 XML에 비해 장점을 많이 가지고 있지만 이 글에서는 장,단점을 논하지는  않겠습니다.

Json을 사용하는 프로젝트가 늘어난다는 것은 그만큼 현실성이 있기 때문일 것 입니다.
최근 Article 중에서 Json 라이브러리들의 성능을 비교한 자료가 있어 올려 봅니다.

원문 링크
http://blog.novoj.net/2012/02/05/json-java-parsers-generators-microbenchmark/

요약
테스트 대상 Libraries
  • FlexJson (2.1)
  • GSon (2.1)
  • Jackson (1.9.4)
  • JsonLib (2.4)
  • JsonMarshaller (0.21)
  • JsonSmart (2.0-beta2)
  • Protostuff JSON (1.0.4)
  • XStream (1.4.2)

성능 측정 방식
Serialization, Deserialization의 3000번 Loop을 250번 실행한 편균값을 측정하였음.

측정 결과
FlexJson
Serialization: 5.593ms / 1 PhotoAlbum, JSON file size 165KB
Deserialization: 14.663667ms / 1 PhotoAlbum

GSon
Serialization: 4.9683332ms / 1 PhotoAlbum, JSON file size 169KB
Deserialization: 9.558666ms / 1 PhotoAlbum

Jackson
Serialization: 1.286ms / 1 PhotoAlbum, JSON file size 165KB
Deserialization: 1.5566666ms / 1 PhotoAlbum

JSON-Lib
Serialization: 17.441668ms / 1 PhotoAlbum, JSON file size 168KB
Deserialization: 78.71367ms / 1 PhotoAlbum

JsonMarshaller
Serialization: 3.6623333ms / 1 PhotoAlbum, JSON file size 165KB
Deserialization: 6.372ms / 1 PhotoAlbum

Json Smart
Serialization: 3.8913333ms / 1 PhotoAlbum, JSON file size 172KB
Deserialization: -

Protostuff JSON
Serialization: 1.8266667ms / 1 PhotoAlbum, JSON file size 165KB
Deserialization: 1.2923334ms / 1 PhotoAlbum

XStream
Serialization: 76.84967ms / 1 PhotoAlbum, JSON file size 171KB
Deserialization: 26.361ms / 1 PhotoAlbum


2012년 2월 3일 금요일

Using the Tomcat 7 JDBC Connection Pool in Production

Tomcat 7에서는 기존에 사용하던 "commons-dbcp"가 다른 JDBC connection Pool로 변경 되었다고 합니다. "commons-dbcp"는 작고 traffic이 적은 어플리케이션에서는 훌륭하지만, 높은 동시 사용환경에서는 문제가 있는 것으로 알려져 있엇습니다.


기존의 "commons-dbcp"설정을 그대로 지원하기 때문에 새로운 JDBC connection Pool로 전환이 쉽다고 합니다.


이번 버전에는 추가된 기능을 보면

  1. ValidationInterval 기능이 있어 주기적(기본 30초)으로 Connection 상태를 Check 하게 됩니다.
  2. JDBC Interceptors 기능, tomcat의 특정 클래스를 직접 구현하고 " jdbcInterceptors" Property에 등록하여 사용가능.
  3. StatementFinalizer Intercepter, "createStatement", "prepareStatement", "prepareCall"에 의해서 statement가 create 될때 호출되는 Interceptor 기능
  4. 그 외 ConnectionState Interceptor, SlowQueryReport and SlowQueryReportJmx Interceptors 등.



Tomcat 7은 기존과 비교해서 발전하는건 좋은데 변화가 너무 많은게 독이 되는건 아닌지 모르겠습니다.




아래는 원문: http://www.tomcatexpert.com/blog/2012/01/24/using-tomcat-7-jdbc-connection-pool-production


One of the new features with Tomcat 7 is a replacement to the commons-dbcp connection pool. While the commons-dbcp connection pool works fine for small or low traffic applications, it is known to have problems in highly concurrent environments (think multi-core/multi-cpu).
Fortunately, this is where the JDBC Connection Pool excels. It is a completely new connection pool which has been written from the ground up, with a focus on highly concurrent environments and performance.
Given its focus on high concurrency and performance, many users are finding that the JDBC Connection Pool can be great for use in a production environment. This article will discuss the features and options which make using the JDBC Connection Pool a great choice.

The Basics

Getting started with the JDBC Connection Pool is very simple. It was purposefully designed as a drop-in replacement for commons-dbcp and as such, if you've ever used commons-dbcp you'll be immediately familiar with the configuration for the JDBC Connection Pool.
This means the most existing commons-dbcp users can switch to the JDBC Connection Pool by simply adding the following property to their configuration factory=”org.apache.tomcat.jdbc.pool.DataSourceFactory”.
What about the other commons-dbcp configuration options? You don't need to change them at all. Virtually all of the commons-dbcp configuration options are supported by the JDBC Connection Pool. Including but not limited to:testWhileIdle, testOnBorrow, testOnReturn, maxActive, minIdle, maxWait, initialSize, removeAbandoned, removeAbandonedTimeout and logAbandoned.

Connection Validation

How many users have seen this scenario before? You deploy a new application to production and it runs great all day, however the next morning you find that the application is dead. Upon examining the logs, you find that they are full of connection errors. What happened?
A common scenario at many companies is for a database to be briefly shutdown at night for maintenance (or backup). Unfortunately, when this occurs all of the connections in your application's connection pool are lost. Furthermore, because the connection was broken by the server, the connection pool does not know that the connection has been lost. As a result, the connection pool still thinks that the connection is valid, and will continue to distribute the connection to your application. Not until your application actually attempts to use the connection will it find out that the connection is bad.
Fortunately, there is an easy way to resolve this issue. You need the connection pool test each connection before it lends the connection to your application. With the JDBC Connection Pool, just like with commons-dbcp, this feature can be enabled by setting testOnBorrow to true and validationQuery to a simple test query like SELECT 1 or SELECT 1 FROM DUAL. Alternatively, the validatorClassName property can be used to indicate the full name of the class that will be used to validate connections. The class specified by validatorClassName will need to implement org.apache.tomcat.jdbc.pool.Validator, and can be used to implement any custom validation logic.
Unlike commons-dbcp, the JDBC Connection Pool provides an additional parameter called validationInterval. This parameter allows you to control how frequently a given validation query is executed. By default it is set to 30 seconds; therefore, the given validation query will only run once per connection every 30 seconds.
To illustrate the power of this feature, let's take a look at an example. You have a connection pool configured to validate connections and that pool hands out 10 connections per second to your application. Given this, the pool will execute 10 validation queries per second for a total of 300 queries over a 30 second period. However, if the validation interval is enabled and set to 30 seconds, that means only 10 queries will be run for the same 30 second time period, offering a reduction of 290 queries. Despite the fact that a typical validation query executes quickly, it is still easy to see how this can be a big savings for your application.
When deciding the value to use for the validationInterval property, the following rule can be helpful. Larger values offer better performance, while smaller values decrease the chance of a stale connection being presented to your application.
For example, a value of 60 seconds means that a validation query only needs to run once every 60 seconds for each connection. However, that also means that once a connection is validated it will not be revalidated for another 60 seconds. If a database connection were to be lost one second after it was validated then there would be a period of 59 seconds where the connection would still be considered valid by the connection pool. If a connection were to be borrowed while in this state, use of the connection would fail and the application would get a connection error.
As you can see from the example, picking a value for the validationInterval property is a trade-off and ultimately depends on what is acceptable for your application.

JDBC Interceptors

Another feature specific to the JDBC Connection Pool is the concept of a JDBC Interceptor. From the documentation, “An interceptor is a powerful way to enable, disable or modify functionality on a specific connection or its sub components”. At first glance this definition may seem a bit vague, but what this essentially means is that functionality can be added or removed from the connection pool with only a simple configuration adjustment. Even better, the code does not have to live inside the JDBC Connection Pool JAR. You can create and add custom JDBC Interceptors in the same manner as you would add an interceptor that is bundled with the connection pool.
Enabling an interceptor is easy; add the jdbcInterceptors property to your connection pool configuration and specify a semi-colon separated list containing the names of the interceptors to be used. For example,jdbcInterceptors=”ConnectionState;StatementFinalizer”.
If the interceptor that you are adding resides in the package org.apache.tomcat.jdbc.pool.interceptor specify the short name, as in the previous example. However, if you are adding an interceptor that resides in a difference package, like a custom interceptor, you would just reference the full class name of your interceptor. For example, com.mycompany.interceptors.MyCustomInterceptor.
With that in mind, let's take a look at some of the interceptors that come with the JDBC Connection Pool.

ConnectionState Interceptor

The ConnectionState interceptor is a simple interceptor which caches the properties autoCommitreadOnlytransationIsolation and catalog.
Normally when one of these properties is accessed, the connection must talk to the server and retrieve the requested value. Since this action results in communication over the network, access to these properties can be slow.
The benefit of the ConnectionState interceptor is that the values will be cached locally, allowing faster access and limiting network chatter.

StatementFinalizer Interceptor

The StatementFinalizer interceptor watches for any statement that is created by a connection with the createStatement, prepareStatement or prepareCall methods. It monitors the statements; when the connection is eventually returned to the pool, the interceptor ensures that any statements that were created are properly closed.
This interceptor comes in handy when dealing with legacy or third party applications where statement handling is problematic, but it is not possible for you to fix the code itself.

SlowQueryReport and SlowQueryReportJmx Interceptors

The SlowQueryReport and SlowQueryReportJmx interceptors monitor the amount of time that a query takes to execute, and flag any query that exceed a predefined threshold. The SlowQueryReport interceptor will log any slow queries at the WARN level, while the SlowQueryReportJmx interceptor will produce a JMX notification in addition to the WARN log statement.
I hope that the benefits to these interceptors are obvious. If you have an application in which performance is slow, you can enable this interceptor and automatically get profiling information about the SQL queries being executed by your application.

ResetAbandonedTimer Interceptor

The ResetAbandonedTimer interceptor works in conjunction with the removeAbandoned property. When the removeAbandoned property is enabled, the connection pool will attempt to reclaim connections which have been checked out of the pool for a long period of time. The rationale here is that connections checked out for an extended period of time are typically connections which have not been properly closed by a deployed application. TheremoveAbandoned setting will thus allow you to reclaim connections from badly behaving applications.
Most of the time this works just fine, however the abandoned timer can be tricked by a long running process. Let's say that you have a batch process that takes 20 minutes to execute. What happens when it is still running, but theremoveAbandoned timeout elapses? Unfortunately, the connection will still be reclaimed by the pool.
This is the benefit of the ResetAbandonedTimer interceptor. With it enabled, the abandoned timeout will be reset every time an SQL operation is executed on the connection. Thus enabling the removeAbandoned process to be more accurate, particularly for legitimate long running processes.

Summary

The JDBC Connection Pool is a fantastic addition to Tomcat 7. Not only does it provide an alternative connection pool, but one with superior performance and features. I would encourage any current users of commons-dbcp to give it a try and see how it can benefit their applications.
More information on the JDBC Connection Pool can be obtained from the Tomcat 7 documentation at the following link.



2012년 2월 1일 수요일

Android App interaction with Web

Mobile Device Framework을 구상하고 있다. iSO와 Android 양쪽에서 공통으로 지원하는 기능 들을 정리하고 있는데 그 중에 Web <-> App 간 Interaction 기능을 기술 해보기로 한다.
연동 방식은 App의 Native Code와 Web의 Javascript와 통신하는 방식이다. 때문에 WebView가 javaScript을 실행할 수 있게 설정이 되어 있어야 한다.

WebView.getSettings().setJavaScriptEnable(true);

조금 더 상세히 설명해보기로 해보자.

App에서 Web으로
App에서 “WebView”의 loadUrl을 이용해서 직접적으로 현재 Web Page 내의 JavaScript을 호출한다. App에서 Web 연동은 오직 이 방법 한 가지다.

현재 보고 있는 WebPage에 “f_addProfile()”이라는 JavaScript가 있다고 하면 아래처럼 사용한다.

WebView.loadUrl(“javascript:f_addProfile(‘전달할 인자’)”);

Web에서 App으로
Web에서 App을 호출 하는 방법은 두 가지 방법을 생각 할 수 있겠다. 하나는 정론적인 방식이고 다른 하나는 편법이다.

정론적인 방법
1. App에서 JavaScript에서 호출될 Method을 만든다.
JavaScript과 연동되는 Class는  별도로 Inner Class로 만든다.

private class WebInteractionBridge {
   private final Handler handler = new Handler();   
   public void callMe(final String arg) { // must be final
       handler.post(new Runnable() {
           public void run() {
                // 실행 로직
           }
       });
   }
}

2. WebView에 JavaScript Interface WebInteractionBridge 등록해준다. 여기선 callApp 이라는 이름으로 등록해본다.

WebView.addJavascriptInterface(new WebInteractionBridge(),"callApp");

3. WebPage의 JavaScript에서 호출 해본다. callApp은 JavaScript Interface에 등록된 이름, callMe는 Method 이름이다.

window.callApp.callMe(‘전달 인자’);

편법
WebView에 “shouldOverrideUrlLoading(WebView, String)” Method가 있는데 이는 WebPage 내의 <a href=>로 걸려 있는 Link을 클릭할 때 발생하게 되는 Callback Method다. Link URL은 Method의 String 인자로 전달 받게 됩니다.

1. Custom Link Pattern을 만들어 봅니다.
<a href="toApp://profileAlbum?userid=inter999" >
   - toApp:// → App을 호출한다는 의미
   - profileAlbum → 무엇을 하기 원한다는 의미
   -userid=inter999 → App으로 전달하려는 Data의 {Key=Value} 문자열

2. shouldOverrideUrlLoading(WebView, String)을 Override 합니다.

@Override
public boolean shouldOverrideUrlLoading(WebView view, String u) {

   if (u.startsWith("toApp://profileAlbum")) {
       String param=u.substring(u.lastIndexOf("?")+1);
       userId = param.substring(param.lastIndexOf("=")+1);
       photoUtil.doTakeProfileAlbumAction(); --> 하고자 하는 일
       return true;
   }
   return false;
}

저는 편법을 많이 사용합니다. 이유는? iSO와 Android 모두에게 동일하게 사용되는 WebPage을 만들기에 적합하기 때문입니다.

블록체인 개요 및 오픈소스 동향

블록체인(block chain) 블록체인은 공공 거래장부이며 가상 화폐로 거래할때 발생할때 발생할 수 있는 해킹을 막는 기술. 분산 데이터베이스의 한 형태로, 지속적으로 성장하는 데이터 기록 리스트로서 분산 노드의 운영자에 의한 임의 조작이 불가...