기본 콘텐츠로 건너뛰기

[ JAVA ] Google Guava 코드에서 @Nonnull, @Nullable, ... 의미

  Collection 관리 등의 이유로 인해서 Google 의 Guava 라이브러리를 참조해서 사용하고 있다. 여러 가지 상황들에 대한 코드 검토 중에 눈에 띄는 코드가 있어서 정리해 둔다.    @Nullable, @Nonnull 등등의 코드는 액면상으로 보면 뭔가 액션을 취하는 Annotation 코드다. 테스트를 위해서 클래스를 생성하고 해당 코드를 작성하면 "javax.annotation.Nonnull", "javax.annotation.Nullable" 이 필요하지만 찾을 수가 없는 상태다. 무엇이 문제일까?    상기에서 설명한 Annotation에 대해서 검색을 해 보면 자바 메모리 모델 (Java Memory Model) 과 FindBugs 로 유명한 Bill Pugh 교수팀에서 "JSR 305 - 소프트웨어 결함 탐지" 를 위한 Annotation 시작한 것으로 나온다. 그리고 이를 Google 의 Guava 에서 "google findbug jsr305" 팩키지로 배포 및 소스에서 사용하고 있는 것을 볼 수 있다.    실제 해당 Annotation을 코드에서 사용하기 위해서는 아래와 같이 해당 팩키지를 Maven Dependency로 설정해 주어야 사용할 수 있다. ... <dependency> <groupId>com.google.code.findbugs</groupId> <artifactId>jsr305</artifactId> <version>1.3.9</version> </dependency> ...   FindBugs 프로젝트에서 이미 Method Parameter 와 Return Type 들에 대해 @Nullable, @NonNull, @CheckForNull 등을 사용했으나 이제는 표준화를 위해서 JSR Spec 쪽에 적용을 하고 있는

[ WINDOWS ] Windows 10 TP 에서 Bing Site 가 자동으로 열리는 경우 대응 방법

  어제 저녁에 다른 일을 하고 있는데 뜬금없이 Chrome 에서 Bing 사이트가 열렸다. TP 버전 발표 이후에 잘 쓰고 있었는데 처음으로 겪은 좀 황당한 상황이다. 아~ 쫌 뭔가 생뚱맞은 짓 좀 하지 않았으면 좋겠다. 업데이트 후에 오히려 장애가 생기는 문제나, 알게 모르게 Keylogger를 심어 놓기도 하고 (이 부분은 TP 버전의 특성을 감안하더라도), 이제는 Bing 사이트 자동 오픈까지… 점점 더 그나마 별로 없던 애정도 식어가는 듯…   여기 저기 검색을 하다보니 윈도우 8 부터인 것 같은데 Network Connection (Internet) 이 살아있는지를 검증하기 위해서 “msftncsi.com” 에 접속을 시도한다고 한다. 그런데 이 사이트가 막혀있는 경우에 항상 Connection Fail 이 발생하기 때문에 이런 경우에는 기본 설정된 페이지로 접속을 시도하여 상태를 검증한다고 한다. 기본 설정된 페이지는 아래와 같다. http://go.microsoft.com/fwlink/?LinkID=219472&clcid=0x409  ( 이 URL은  http://www.bing.com  으로 이동 )   이런 처리를 해제하기 위해서는 Registry 를 변경해 주면 쉽게 해결할 수 있다. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NlaSvc\Parameters\Internet\EnableActiveProbing   위의 키 값을 1 에서 0 으로 변경 해 주면 된다.

[ WINDOWS] Windows 10 TP 의 Keylogger 에 대한 대응???

  Windows 10 TP (Technical Preview) 가 발표된 후에 얼마 후에 외국의 블로그를 통해서 사용자의 정보등 여러 가지 정보를 MS 로 전송하는 문제를 제기 (“Keylogger Issue”) 한 것을 본 적이 있다. TP 버전이고 사용계약에 명시된 것이라고 해도 실제 데이터가 전송되는 것이 그닥 기분이 좋지는 않다. 더욱이 우리나라처럼 전 국민정보가 공개 정보가 된 상태라서 더 기분이 좋지 않을 수 밖에는 없다.   다른 블로그들의 정보를 검색해 보니 대략 아래와 같은 두 가지 유형의 방법이 있는 것 같다. 작업 스케줄러에 설정되어 있는 작업을 비 활성화하는 방식 Windows 10 설치 시에 관련된 서비를 삭제하고 작업 파일의 접근을 제한하는 방법   위의 처리 방식이 실제 전송을 해제하는지 다른 문제는 없는지에 대한 것은 정보가 없기 때문에 해법이라고 할 수 있는지도 모르겠다. ㅠㅠ 작업 스케줄러 비활성화 방식   아래와 같이 작업 스케줄러를 실행한다. 윈도우키 + R 을 누르고 taskschd.msc 을 입력하거나 윈도우 관리도구에서 작업 스케줄러 실행   작업 스케줄러의 왼쪽 메뉴에서 Windows > Application Experience 로 이동하여 "AitAgent" 작업을 Disable 로 설정   작업 스케줄러의 왼쪽 메뉴에서 Windows > NetTrace 로 이동하여 "GatherNetworkInfo" 작업을 Disable 로 설정   현재 파악된 것은 위의 두 가지 작업이지만 더 존재하는지는 현재 알 수가 없다. 설치 시점에 처리하기   이 방식은 기존 Windows 설치 시에 "Administrator" 계정을 살려서 설치를 진행해 본 경험이 있다면 쉽게 이해할 수 있는 방법이지만 처음 접하는 것이라면 어려울 수도 있다.   1. 설치 과정 중에서 "사용자 계정 생성&q

[ TOMCAT ] 하나의 웹 어플리케이션을 여러 개의 인스턴스로 구동해 보기 (테스트용)

  이전 게시글에서 Tomcat 수동 배포에 대해서 검토를 해 보았으니 이번에는 하나의 웹 어플리케이션을 하나의 Tomcat Engine 으로 Instance 만 여러 개를 만들어 구동하는 방법에 대해서 알아 보도록 한다. Tomcat Multiple Instance 개념   하나의 Tomcat 으로 여러 개의 인스턴스를 만들어서 사용하기 위해서는 약간의 개념(?)을 이해해야 한다. 제일 먼저 Tomcat 의 구조를 이행해야 하므로 간단하게 알아보도록 하자.   위의 그림은 Tomcat 의 기본 폴더 구조를 나타내는 것이다. 각 폴더의 의미는 다음과 같다. lib - Tomcat Engine 이 사용하는 외부 라이브러리 (*.jar) 관리 폴더 bin - Tomcat 실행/종료와 관계되는 스크립트 관리 폴더 conf - Tomcat 에 올라갈 웹 어플리케이션에 대한 설정 파일 관리 폴더 logs - Tomcat 의 로그 관리 폴더 temp - Tomcat Engine 에서 사용하는 임시 파일 폴더 webapps - 웹 어플리케이션이 배포되는 어플리케이션 관리 폴더 work - JSP 파일이 Servlet 으로 컴파일된 클래스 (*.class) 관리 폴더   폴더들이 상당히 많이 존재하지만 정작 Tomcat 만을 위해서 존재하는 폴더는 "lib" 와 "bin" 폴더 뿐이다. 따라서 웹 어플리케이션의 서비스를 운영하는데 사용되는 폴더들은 나머지 "conf", "logs", "temp", "webapps", "work" 폴더가 된다.    여기서 헷갈리지 않아야 하는 것은 어플리케이션이 하나의 인스턴스이고 인스턴스가 생성되어 실행이 되려면 하나의 JVM 에서 처리가 되어야 한다. 따라서 Multiple Instance 라고 하는 것은 결국 여러 개의 JVM을 운영하겠다는 것이고 여기에 각

[ JAVA ] JVM Shutdown 상황에서도 로그를 출력해 보자.

  현재 진행 중인 프로젝트는 Java Agent 를 이용해서 JVM 상에 구동되는 Application의 성능을 측정하기 위한 Custom Profiler를 구성하는 것이기에 Logging 정보가 상당히 중요하고, JVM Shutdown 되는 시점을 Hooking 하여 Agent 의 서비스들이 제대로 종료하는지를 검증하여야 한다.   그런데 JVM Shutdown Hooking 을 하게 되면 그 시점에 java.util.logging.LogManager 를 사용하고 있다면 Logger 들이 모두 Clear 되어 버리기 때문에 완전히 종료되는 시점까지 Logging 을 처리할 수 없다. *** 지금부터 언급하는 상황들은 java.util.logging.LogManager를 사용하는 경우에 해당하는 것이므로 다른 logging 처리를 하는 경우에는 해당되지 않는다. 다만 처리되는 상황이 궁금한 경우는 참고가 될 수도 있다. 왜? Logger 가 모두 Clear 되는 것일까?   가장 먼저 문제가 되는 LogManager를 역 추적해 보도록 하자. 우선 어플리케이션에서 JVM Shutdown 을 Hooking 하는 방법은 아래와 같다. // JVM Shutdown Hook Thread를 설정한다. Thread shutdownThread = new Thread(new Runnable() { @Override public void run() { try { LOGGER.info("JVM Shutdown called"); shutdown(); LOGGER.info("JVM Shutdown complete"); } catch (Exception e) { LOGGER.log(Level.SEVERE, "JVM Shutdown completed with errors", e);

[ TOMCAT ] 웹 어플리케이션 수동 배포 해 보기. (간략)

  개발하는 동안에 보통 Eclipse에 Servers 에 Tomcat 을 등록하고 Maven 을 이용해서 배포를 하고 사용하게 된다. 그러나 상황에 따라서는 Eclipse 를 이요하지 않고 Tomcat 에 직접 배포를 해서 테스트를 해야하는 상황이 발생하게 된다. 이 글을 작성하게 된 것도 Eclipse에서 Tomcat 를 실행하면 아무 문제 없는데 테스트 서버에 배포가 되어 실행이 되면 Tomcat 실행 중에 오류가 발생하는 것 때문에 임시로 간략하게 테스트 한 것을 정리해 놓도록 한다.   Tomcat 은 설치 버전이 아니라 Zip 배포 버전을 사용하였고, 위치는 D:\Tomcat7 이며, 웹 어플리케이션은 test-apps (프로젝트 명)라고 가정하고 테스트를 진행하도록 한다. (단, 하기의 내용은 실제 각 개발자의 환경에 따라서 다를 수 있으므로 반드시 맞는 방법이라고 할 수는 없다) 배포 대상 생성 및 복사   Eclipse에서 빌드를 하여 War 파일과 배포 폴더를 생성한다. 보통은 Eclipse에서 Maven 을 이용하여 빌드를 하게 되므로 빌드 후에 해당 프로젝트의 Target 폴더를 확인하면 War 파일과 배포 폴더가 생성된 것을 확인할 수 있다. 배포는 War 파일이 아니라 배포 폴더 (test-apps) 를 이용하도록 한다.   배포 폴더를 복사하여 Tomcat 폴더의 "webapps" 밑에 넣도록 한다. ( 보통은 WebContent / Library / Classes 들을 배포하지만, Maven 빌드릉 통해서 해당 항목들이 모두 배포 폴더와 War에 포함되어 있으므로 폴더채로 복사를 하면 된다) Context 설정 (server.xml 파일)   Tomcat 폴더 밑의 conf 폴더에 server.xml  파일이 존재한다. 이 파일에 Tomcat 이 구동되었을 때 사용할 어플리케이션 Context 를 설정해 주어야 한다. server.xml  파일을 열고 "<Host>...<

[ 일반 ] Chrome 에서 Manual Proxy Server 설정하는 방법

   현재 진행 중인 프로젝트 (APM Prototype - Custom Profiler) 에서 부하 테스트를 하기 위해 JMeter를 사용하려고 설정을 하고 있다. 그런데 JMeter에서 시나리오를 생성해서 설정하는 것은 상당히 어렵다. 그래서 제공되는 것이 Http Recording Controller 이다.    간략하게 처리 방법을 정리하면 Thread Group 에 Recording Controller 를 추가하고 WorkBench 에 Http(s) Test Script Recorder 를 추가해 놓고 로컬 Proxy Server 를 통해서 사용자가 브라우저를 통해서 접근하는 모든 Request 를 잡아내어 저장하는 방식이다. (이 부분에 대해서는 테스트 종료 후에 JMeter 사용법을 정리해서 올릴 예정이므로 여기서는 생략하도록 한다)   그런데 문제는 주로 사용하는 브라우저가 Chrome 인데 Chrome 의 설정을 통해서 Proxy Server 설정을 하게 되면 아래의 그림과 같이  Internet Options 창의 Lan 설정창이 열리게 되어 변경하면 외부 연결에 대해서 Proxy Server 가 설정된다는 점이다.   JMeter에서는 Firefox 를 사용하도록 권고 하고 있다. Firefox 에서는 Option > Advanced > Network 설정을 통해서 시스템 전역과는 상관없이 Manual 로 Proxy Server 설정이 가능하기 때문이라고 설명하고 있다.   그렇다고 여러 브라우저를 설치해서 사용하는 것이 싫어서 Chrome 을 이용해서 Manual Proxy Server 를 설정하는 방법을 검색해 본 결과 Chrome 인스턴스에서 설정을 통해서 처리하는 방법은 없고 실행 옵션을 줘서 설정이 가능하기는 하다. "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --proxy-server="서버IP:POR

[ JAVA ] @interface? Annotation??

  Annotation 이란 사전적인 의미대로 주석을 작성하는 것이고, 프로그램적으로 사용할 수 있도록 몇 가지 규칙을 적용한 것이다. 제일 흔한 활용 방식은 부가적인 정보를 제공하기 위한 것이다.   예를 들어 웹 어플리케이션에서 Controller 에 대한 설정을 하려면 해당 규칙 (Spring Framework 등을 사용한다면 그에 맞도록) 을 xml 설정 파일에 정의를 하고 프레임워크가 구동되면 그 정보를 로드해서 운영되는 것이다. 그러나 Annotation 방식을 사용하게 되면 xml 설정 파일에는 컴포넌트 스캔 정보와 같은 단순한 정보를 설정하고 나머지 부가 정보들은 해당 클래스에 Annotation으로 설정을 해 놓으면 같은 동작을 하게 된다. 좀 더 관리 포인트가 줄어들고 해당 클래스의 Annotation을 보면 어떤 역할을 담당하는지를 알 수 있기 때문에 많이 활용된다.   실제 구성된 코드에서 보면 "@" 가 붙은 것들을 볼 수 있다. "@" 는 Annotation을 의미하는 것이고, 가장 많이 볼 수 있는 것이 "@Override", "@SupressWarnings", "@Deprecated", "@Controller", "@RequestMapping", ... 등이다.   Annotation은 다음과 같이 정의를 해서 직접 만들어서 사용할 수도 있다.   @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Simple { public String defaultVal() default "OK"; public String val(); }   위의 코드는 단순한 기능을 제공하는 Annotation을 정의한 것으로 Annotation 의 값을 "val" 이라는 항목

[ JAVA ] Decompile 된 코드에서 this.val$xxx 는 어떻게 해석해야 할까?

  좋은 방법도 아니고 하지 않는 것이 좋기는 하지만 제대로 된 정보를 구할 수 없는 경우에 어쩔 수 없이 외부 jar 파일에서 원하는 기능과 유사한 기능을 구현한  코드를 검토해 봐야할 수 밖에는 없는 경우가 존재한다.  이럴 때는 Decompiler를 사용하여 원본에 근사치의 코드를 얻을 수 있다. Eclipse 에 Decompiler 를  설정하는 부분은 이전 게시글 에 서 설명을 했었다.    이 때 Decompile 된 코드를 검토하다 보면 허걱스런 코드들이 존재하는 것을 볼 수 있다. 여러 가지 상황들이 있지만 많이 만나게 되는 "this.val$xxx" 코드가  한 가지 예라고 볼 수 있다. 이런 경우는 어떻게 해석을 해야할까?   자바 스펙 ( http://docs.oracle.com/javase/specs/jls/se5.0/html/lexical.html#3.8) 에 의하면 '$' 는 변수명으로 사용할 수 있는 문자이지만  다음과 같은 추가 설명이 존재한다. The $ character should be used only in mechanically generated source code or, rarely, to access preexisting names on legacy systems.   위의 문장을 따르면 기계적으로 생성된 소스 코드 또는 극히 일부 기존 시스템의 이미 존재하는 이름을 참조하기 위해서만 사용하여야 한다는 제한적인 의미가 된다. 왜? 이런 제한이 있어야 하는 것일까? (정확한 것이라고 할 수는 없지만 아래와 같이 이해할수 있을것 같다) 내부적인 클래스가 존재하는 것과 같이 인식 되는 경우 - 익명 클래스등과 같은 내부에 Inner Class가 존재하는 경우에 외부 클래스와 내부 클래스를 식별하기 위한 방식으로 outerclass$innerclass 로 사용 된다. 이와 같은 이유로 인해서 메서드의 내부에 익명 클래스가 사용되는 경우도 역시 마찬가지로 적용된다. 난

[ 일반 ] 정규식 (Regular Expression)에 대한 간단 정리

유독 머리에 제 자리를 잡지 못하는 것들 중에 하나인 정규 표현식 (Reqular Expression) 을 또 써야할 상황이 발생해서 다시 한번 정리를 해 놓는다. (언젠가 또 멍청하게 까먹고 다시 정리한다고 하겠지만.. 쩝) 확장자 검증하기 (샘플) 우선  사용하려고 하는 실제 사례에 대한 의미를 확인해 보도록 하자.  실제 적용하여야 하는 부분은 특정한 문자열 (URL, File Path 등...) 에서 이미지 확장자를 제거하는 부분이다. 쉽게 사용할 수 있는 정규식은 다음과 같이 적용이 가능하다. ( [ ^ \s ] + ( \. ( ? i ) ( jpg | png | gif | bmp ) ) $ ) 위의 정규식을 이해하기 위해서 하나씩 끌어내 보면 다음과 같이 해석할 수 있다. ( # 그룹 1의 시작 [ ^ \s ] + # 공백을 제외한 하나 또는 그 이상의 문자열이 존재하여야 한다는 조건 ( # 그룹 2의 시작 \. # '.' 문자 ( ? i ) # 이후의 문자들에 대해서 대/소문자를 무시 ( # 그룹 3의 시작 jpg # 'jpg' 문자 포함 | # 또는 png # 'png' 문자 포함 | # 또는 gif # 'gif' 문자 포함 | # 또는 bmp # 'bmp' 문자 포함 ) # 그룹 3의 종료 ) # 그룹 2의 종료 $ # 문자열 종료 ) # 그룹 1의 종료 위의 내