2016년 12월 16일 금요일

[uml] 관계도 정리

UML 사용시 가끔 혼동되는 경우가 있어서 정리 하였습니다.


2016년 12월 14일 수요일

[JNI] Java JNI 연동 방법

Java에서 C쪽 레거시 연동을 위해서 JNI를 사용할 때가 있습니다.
이때 연동하는 절차에 대해서 간단하게 정리해 봤습니다.

1. java 에서 호출 하기

public class Hello {
    native void helloFromC(int iValue, String sValue);
    static {
        System.loadLibrary("chello");
    }
    static public void main(String argv[]) {

        int i = 1;
        String s = "testval";
        Hello helloWorld = new Hello();
        helloWorld.helloFromC(i, s);
    }
}

native 로 C쪽에서 사용할 메소드를 선언합니다.
그리고  System.loadLibrary  로 C 소스를 로딩합니다.
마지막으로  호출해서 사용합니다.

2. java 소스 컴파일 및 C에서 사용할 소스의 헤더 생성하기

일단 javac 로 자바 파일을 컴파일 한 후에 javah 로 c에서 사용할 헤더파일을 생성합니다.

$ javac Hello.java
$ javah Hello

3. c 코드 작성하기 

#include "Hello.h"

JNIEXPORT void JNICALL Java_Hello_helloFromC
  (JNIEnv * env, jobject jobj, jint ival, jstring sval)
{
 const char *name = (*env)->GetStringUTFChars(env, sval, NULL);
     printf("Hello from C!\n");
     printf("%d ____ %s \n",ival,name);
     
     printf("Hello from C exit\n");     
}

4. c 코드 컴파일 하기

$ gcc -o libchello.so -shared chello.c -lc -fPIC

* 참조하는 라이브러리가 있는경우 아래와 같이 참조를 해서 컴파일 한다.
$ gcc -o libchello.so -shared -I/home/temp/Stat_Test -I/home/FRAMEWORK/include chello.c -lc -fPIC -L/home/FRAMEWORK/lib/ -lstctl


5. 실행한다. 

$ java Hello

실행시 다음과 같은 에러가 나는 경우가 있습니다.
이런 경우는 64bit 로 컴파일하고 32bit JDK 버젼에서 실행한 경우이다. 

$ /usr/local/j2sdk1.4.2_19/bin/java Hello
Exception in thread "main" java.lang.UnsatisfiedLinkError: /home/temp/TT/libchello.so: /home/temp/TT/libchello.so: wrong ELF class: ELFCLASS64 at java.lang.ClassLoader$NativeLibrary.load(Native Method) at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1586) at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1511) at java.lang.Runtime.loadLibrary0(Runtime.java:788) at java.lang.System.loadLibrary(System.java:834) at Hello.(Hello.java:4)

* 주의 사항 : 테스트는 패스를 숨기기위해서 일부 경로 정보를 조작한게 있습니다.
(무조건 복붙해서 돌리면 에러가 날 수도 있다는 뜻입니다.)
* 주의 사항 : 테스트는 같은 폴더에 있어서 패스 설정하는 부분이 빠져 있습니다.
* 주의 사항 : 실제 Web 서버에서 사용할때는 라이브러리가 LD_LIBRARY 패스에 들어가 있어야 합니다.

2016년 12월 12일 월요일

[Java] Logger 라이브러리 구조 및 유의 사항

 Log4J를 사용하다가 오래된 로그 지우는 기능을 사용하기 위하여 기존 Log4J를 걷어 내고 Logback으로 Logger를 변경하게 되었다.
이때 Logging 라이브러리 관련해서 이해한 내용을 정리 하였다.

로그 프레임 워크를 보면 아래와 같은 순서로 진행되게 된다. 

    1. 어플리케이션에서 사용하는 로거를 브릿지를 통해서  SLF4J 형식으로 변환한다. 
    2. SLF4J로 변환된 로그를 원하는 로깅 라이브러리로 바인딩하여 사용한다. 

이를 통해서 다양한 형식으로 로깅 방식을  SLF4J 로 통합하고 자신에게 맞는 로깅 라이브러리로 쉽게 바인딩 하여 사용 할 수 있도록  되어 있다. 

구성요소는 아래와 같이 4가지로 되어 있다. 

Application -> Bridge -> Interface -> Binding -> Logger

이 때 주의 할 점은  Bridge 에서 변환되는 로그와 Binding 에서 연동하는 로그의 타입이 같으면 안된다.
만약 같게 되는 경우 Binding -> Bridge 방향으로 다시 로그가 흘러가 무한 루프에 빠지게 된다.

예를 들면 log4j-over-slf4j 브릿지를 쓰고 slf4j-log4j 바인더를 사용하게 되는 경우
    Application -> Bridge -> Interface -> Binding ->[ Bridge -> Interface ->Binding ->] .... 
이런식으로 무한 루프에 빠져 오류가 발생하게 된다.