Translate

2016년 6월 25일 토요일

[JAVA] SVN 소스와 배포버전 소스가 일치하지 않는경우 소스 쉽게 맞추기 (소스 현행화 방법)





요즘에 젠킨스같은 CI 툴을 이용하면서 SVN에 커밋되어있는 소스와
실제 운영서버에 배포되어있는 소스가 동일한것이 당연하게 되었는데..



예전에는 종종 누군가 개발한 것을 운영서버에 배포하고 SVN에 커밋하지 않아서 SVN의 소스와 운영서버에 배포되어있는 소스가 불일치 하는 경우가 종종 있었다.
(개발한 당사자의 소스가 가장 최신버전의 소스가 되어버리는 상황인데 당사자가 퇴사하거나 해당 PC를 포멧해 버린다면 답이 없다;;)




위와같은 상황에서 할 수 있는 것은 서버에 올라가 있는 class 파일을 디컴파일 하여 java 소스와 일일히 비교해 보는건데 여간 고역이 아닐 수 없다.
그나마 비교해야 하는 파일이 몇개 정도라면 그냥 하면 되지만
소스가 불일치 하는 파일이 어떤건지 모르는 상황이라면 모든 소스를 일일히 비교해 보는 수 밖에 없다.



class파일을 디컴파일 하여 java 소스와 비교할 때 힘든점은 같은 소스라도 내용이 바뀔 수 있기 때문에 힘든게 아닐까 싶다.
java compiler가 java를 컴파일 시 소스 최적화를 하는데 이 때문에 소스가 미묘하게 바뀌거나 상황에 따라 완전 다른소스처럼 바뀌어 버린다.




최근에 인수인계를 해주고 떠난 이전 작업자가 소스를 SVN에 제대로 커밋하지 않는 바람에 프로젝트의 모든 소스를 디컴파일하여 소스를 맞추는 작업을 하게 되었다.
어떻게 작업을 할까 하다가 기막힌 방법이 떠올라 예상보다 적은 공수로 작업을 할 수가 있었다.


방법은 간단한데 아래와 같이 작업을 했다.

1004lucifer

1. (운영서버에)배포된 class를 모두 디컴파일 한다.
2. SVN의 소스를 내려받아 프로젝트 셋팅 후 빌드한다. (배포버전과 java 버전을 맞추는게 좋다.)
3. 빌드 후 생성된 class 파일을 디컴파일 한다.
4. 1번에서 디컴파일한 소스와 3번에서 디컴파일한 소스를 비교한다.





예를 들면 아래와 같다.
1004lucifer
샘플소스( 링크 , 다운로드 )

기존의 소스에서 아래 하이라이트 된 부분을 수정했다.
public synchronized Queueable dequeue(final int index) {
  if (index < 1 || index > this.size) {
    // throw new NoSuchElementException();
    return null;
  }

  final Queueable result = this.elements[index];
  setElement(index, this.elements[this.size]);
  this.elements[this.size] = null;
  this.size--;
  if (this.size != 0 && index <= this.size) {
    int compareToParent = 0;
    if (index > 1) {
      if (compareToParent == 0) {
        compareToParent = compare(this.elements[index], this.elements[index / 2]);
      } else {
        for (int i = 0; i < this.size; i++) {
          compareToParent++;
        }
        return result;
      }
    }
    if (index > 1 && compareToParent < 0) {
      percolateUpMinHeap(index);
    } else {
      percolateDownMinHeap(index);
    }
  }

  return result;
}



위의 방법으로 두개의 디컴파일된 소스를 비교해보면 이렇게 나온다.
(왼쪽의 모습이 위의 수정된 소스이다. 컴파일 시 소스최적화가 되어 다른 소스처럼 보여지게 된다.)
1004lucifer



작업의 공수를 낮춰주는 부분은 배포버전의 소스와 현재 SVN 소스의 어느부분이 다른지 한눈에 볼 수가 있다는 점이다.
(원본소스와 컴파일된 소스가 완전 다른 소스같이 보여지긴 하나 해당 부분만 꼼꼼히 보면 된다는 장점이 생겼다.)



위와같이 작업하여 운영서버에 배포된 class파일에서 현재 SVN 소스에 반영해야 할 파일들을 쉽게 추릴 수 있었고 어느 부분만 작업을 하면 되는지 알 수가 있어서 예상했던 공수를 많이 줄일 수 있었다.
서버에 반영된 소스가 SVN에 커밋되지 않은 상황이라는게 일어나서는 안되는 일이지만 만일 발생한 경우라면 위와같은 방법으로 소스현행화를 적응 공수를 들이며 작업이 가능 할 것이다.





PS.
나의 경우에는 IntelliJ의 디컴파일 기능을 이용했는데 따로 디컴파일 작업 없이 class를 실시간 디컴파일해서 보여준다. eclipse 역시 비슷한 플러그인이 있지 않을까 싶다.아래와 같이 기존의 class를 classes_origin 이라는 디렉토리로 넣어서 빌드된 class와 파일비교를 해서 확인했다.





CVS, GIT 등등 다른 버전관리 프로그램 또한 마찬가지고 버전관리를 사용하고 있지 않다고해도 위의 방법은 마찬가지로 유효하다.


2016년 6월 16일 목요일

[APK Studio] 프로그램 구동 시 libicui18n.so.52 에러 해결방법




OS: Ubuntu 15.10 gnome (x64)





증상


APK Studio 프로그램을 설치 후 구동하려 할 시 아래와 같이 에러메시지가 발생했다.
1004lucifer

lucifer@lucifer-Vostro-V13:/devTools/apkstudio-d49d3de$ ./apkstudio.sh
/devTools/apkstudio-d49d3de/./apkstudio: error while loading shared libraries: libicui18n.so.52: cannot open shared object file: No such file or directory
lucifer@lucifer-Vostro-V13:/devTools/apkstudio-d49d3de$






해결방법

libicui18n.so.52 라이브러리가 없어서 에러가 발생했다고 하니 libicui18n.so.52 라이브러리를 설치해 주자.
1004lucifer
1. libicui18n.so.52 라이브러리를 다운받는다.
공식: http://packages.ubuntu.com/trusty/amd64/libicu52/download
(링크가 변경될 수 있을까 싶어 개인공간에 올렸다. => Direct Download Link)


2. 해당 라이브러리를 설치한다.


lucifer@lucifer-Vostro-V13:~/Downloads$ sudo dpkg -i libicu52_52.1-3ubuntu0.4_amd64.deb
[sudo] password for lucifer:
Selecting previously unselected package libicu52:amd64.
(Reading database ... 282018 files and directories currently installed.)
Preparing to unpack libicu52_52.1-3ubuntu0.4_amd64.deb ...
Unpacking libicu52:amd64 (52.1-3ubuntu0.4) ...
Setting up libicu52:amd64 (52.1-3ubuntu0.4) ...
Processing triggers for libc-bin (2.21-0ubuntu4.3) ...
lucifer@lucifer-Vostro-V13:~/Downloads$






PS.
위의 작업 후 아래와 같은 메시지가 발생하는 경우 링크로 들어가서 확인해 본다.
Cannot mix incompatible Qt library 에러 원인과 해결방법
1004lucifer

lucifer@lucifer-Vostro-V13:/devTools/apkstudio-d49d3de$ ./apkstudio.sh
Cannot mix incompatible Qt library (version 0x50402) with this library (version 0x50201)
Aborted (core dumped)

lucifer@lucifer-Vostro-V13:/devTools/apkstudio-d49d3de$


* 중요
위의 링크로 들어가서 작업을 해도 되지만 작업을 해 놓은 수정된 APK Studio 파일을 다운로드할 수 있게 올려놓았다. (다운받기)





참고: https://github.com/vaibhavpandeyvpz/apkstudio/issues/35






[Ubuntu] Cannot mix incompatible Qt library 에러 원인과 해결방법




OS: Ubuntu 15.10 gnome (x64)




증상

APK Studio 프로그램을 받아서 실행하려 하니 아래와 같이 오류메시지가 발생했다.
1004lucifer

lucifer@lucifer-Vostro-V13:/devTools/apkstudio-d49d3de$ ./apkstudio.sh
Cannot mix incompatible Qt library (version 0x50402) with this library (version 0x50201)
Aborted (core dumped)
lucifer@lucifer-Vostro-V13:/devTools/apkstudio-d49d3de$






원인

구글 검색을 해보니 QT 관련 라이브러리를 해당 프로그램으로 복사하라고 되어있었다.
아마 프로그램에 들어있는 QT 라이브러리들의 버전이 동일하지 않거나 잘못 된 것으로 예상이 된다.





해결과정

1. 실행하려는 프로그램에 libQt5*.so.5 라는 이름을 가진 파일들이 몇개 있었다.

lucifer@lucifer-Vostro-V13:/devTools/apkstudio-d49d3de$ tree
.
├── apkstudio
├── apkstudio.png
├── apkstudio.sh
├── libQt5Core.so.5
├── libQt5Gui.so
├── libQt5Gui.so.5
├── libQt5Widgets.so
├── libQt5Widgets.so.5
├── platforms
│   └── libqxcb.so
├── uninstall
├── uninstall.dat
└── Uninstall.desktop

1 directory, 15 files
lucifer@lucifer-Vostro-V13:/devTools/apkstudio-d49d3de$



2. 일단 QT를 다운로드받아 설치 했다.
    (설치과정을 모르겠으면 댓글 달아주세요. 추가로 설명 달겠습니다.)
1004lucifer
다운로드 링크
최신버전: https://www.qt.io/download-open-source/
모든버전: http://download.qt.io/archive/qt/


3. 설치된 QT 디렉토리에서 프로그램에서 사용하는 파일을 찾아 프로그램으로 복사를 해줬다.
lucifer@lucifer-Vostro-V13:/$ cp /devTools/Qt5.6.1/5.6/gcc_64/lib/libQt5Core.so /devTools/apkstudio-d49d3de/libQt5Core.so.5
lucifer@lucifer-Vostro-V13:/$ cp /devTools/Qt5.6.1/5.6/gcc_64/lib/libQt5Core.so /devTools/apkstudio-d49d3de/libQt5Gui.so.5
lucifer@lucifer-Vostro-V13:/$ cp /devTools/Qt5.6.1/5.6/gcc_64/lib/libQt5Core.so /devTools/apkstudio-d49d3de/ libQt5Widgets.so.5
1004lucifer

4. 프로그램을 다시 실행시키니 아래와 같이 다시 에러 메시지가 나오며 구동되지 않았다.
lucifer@lucifer-Vostro-V13:/devTools/apkstudio-d49d3de$ ./apkstudio.sh
/devTools/apkstudio-d49d3de/./apkstudio: error while loading shared libraries: libicui18n.so.56: cannot open shared object file: No such file or directory
lucifer@lucifer-Vostro-V13:/devTools/apkstudio-d49d3de$


5. libicui18n.so.56 이 없어서 구동이 안된다고 하는데..
   지금 작업을 하기전에 libicui18n.so.52 를 이미 설치했었다.
   QT 버전에 따라 필요한 라이브러리 버전이 다르다고 느껴졌다.
   libicui18n.so.52 를 사용하는 QT를 설치한 후 Library를 복사했다.
   (버전에 맞는 QT를 찾느라 QT를 버전별로 5번 정도 설치한것 같은데..
    이럴줄 알았으면 차라리 libicui18n.so.56 라는걸 찾아서 설치하거나 소스를 받아 컴파일 하는게 빠르겠다.)
lucifer@lucifer-Vostro-V13:/devTools/apkstudio-d49d3de$ cp /devTools/Qt5.3.0/5.3/gcc_64/lib/libQt5Core.so ./libQt5Core.so.5
lucifer@lucifer-Vostro-V13:/devTools/apkstudio-d49d3de$ cp /devTools/Qt5.3.0/5.3/gcc_64/lib/libQt5Gui.so ./libQt5Gui.so.5
lucifer@lucifer-Vostro-V13:/devTools/apkstudio-d49d3de$ cp /devTools/Qt5.3.0/5.3/gcc_64/lib/libQt5Widgets.so ./libQt5Widgets.so.5


6. 제대로 맞는 버전으로 Library를 복사해주니 정상적으로 실행되는 것을 확인했다.





요약
* 소스를 다운받아서 컴파일 할 수 있다면 소스를 받아 컴파일 하는게 좋음!!

직접 컴파일 할 수 없다면..
1. 프로그램에 QT 관련 라이브러리가 있는지 확인 (libQT로 시작되는 파일)
2. QT 프로그램 설치
3. 다른 의존성 라이브러리가 필요하면 메시지가 나오지 않을 때 까지 설치
4. 프로그램 실행


2016년 6월 11일 토요일

[Gradle] Gradle을 Daemon으로 띄워서 빌드 실행속도(성능)를 높여보자.



OS: ubuntu
Gradle ver: 2.13


Gradle을 알아보면서 실행할 때마다 Daemon 을 사용하면 더 빨라진다는 내용이 나오는데 계속 보고있자니 거슬려서 Deamon을 사용하도록 설정했다.


설정방법

셋팅 방법은 아래와 같이 gradle.properties 파일을 만들고 내용을 채워넣어준다.
$ vi ~/.gradle/gradle.properties
(윈도우7의 경우에는 "C:\Users\<username>\gradle.properties" 파일을 생성해 주면 된다.)

org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.workers.max=3
org.gradle.configureondemand=true
org.gradle.jvmargs=-Xms128m -Xmx256m

1004lucifer
위의 작업을 다 한 후 gradle 을 실행하면 데몬이 구동이 되고 이후에는 gradle 이 빠르게 작동된다.



PS.
한가지 유의해야 할 점은 위와같이 Gradle Daemon을 셋팅 했음에도 속도가 느리게 느껴질 수 있다.
Gradle은 JVM에서 동작하는데  Gradle Daemon을 사용하면 매전 JVM을 실행하거나 정지하지 않아도 된다.
그렇기 때문에 Daemon 셋팅 시 첫번째는 기존과 비슷한 속도로 수행이 될테며 두번째부터 빠른 속도를 체감 할 수 있다.
Gradle Daemon은 시간이 지나면 자동으로 종료를 한다.(기본 3시간)



데몬구동 설정하기 전


lucifer@lucifer-Vostro-V13:/source/gradle/160611/test01$ gradle task
:tasks

------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------

Build tasks
-----------
assemble - Assembles the outputs of this project.
build - Assembles and tests this project.
buildDependents - Assembles and tests this project and all projects that depend on it.
buildNeeded - Assembles and tests this project and all projects it depends on.
classes - Assembles main classes.
clean - Deletes the build directory.
jar - Assembles a jar archive containing the main classes.
testClasses - Assembles test classes.

Build Setup tasks
-----------------
init - Initializes a new Gradle build. [incubating]
wrapper - Generates Gradle wrapper files. [incubating]

Documentation tasks
-------------------
javadoc - Generates Javadoc API documentation for the main source code.

Help tasks
----------
buildEnvironment - Displays all buildscript dependencies declared in root project 'test01'.
components - Displays the components produced by root project 'test01'. [incubating]
dependencies - Displays all dependencies declared in root project 'test01'.
dependencyInsight - Displays the insight into a specific dependency in root project 'test01'.
help - Displays a help message.
model - Displays the configuration model of root project 'test01'. [incubating]
projects - Displays the sub-projects of root project 'test01'.
properties - Displays the properties of root project 'test01'.
tasks - Displays the tasks runnable from root project 'test01'.

Verification tasks
------------------
check - Runs all checks.
test - Runs the unit tests.

Rules
-----
Pattern: clean<TaskName>: Cleans the output files of a task.
Pattern: build<ConfigurationName>: Assembles the artifacts of a configuration.
Pattern: upload<ConfigurationName>: Assembles and uploads the artifacts belonging to a configuration.

To see all tasks and more detail, run gradle tasks --all

To see more detail about a task, run gradle help --task <task>

BUILD SUCCESSFUL

Total time: 9.182 secs

This build could be faster, please consider using the Gradle Daemon: https://docs.gradle.org/2.13/userguide/gradle_daemon.html
lucifer@lucifer-Vostro-V13:/source/gradle/160611/test01$





데몬구동 설정 후 두번째 수행 시


lucifer@lucifer-Vostro-V13:/source/gradle/160611/test01$ gradle task
Parallel execution with configuration on demand is an incubating feature.
:tasks

------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------

Build tasks
-----------
assemble - Assembles the outputs of this project.
build - Assembles and tests this project.
buildDependents - Assembles and tests this project and all projects that depend on it.
buildNeeded - Assembles and tests this project and all projects it depends on.
classes - Assembles main classes.
clean - Deletes the build directory.
jar - Assembles a jar archive containing the main classes.
testClasses - Assembles test classes.

Build Setup tasks
-----------------
init - Initializes a new Gradle build. [incubating]
wrapper - Generates Gradle wrapper files. [incubating]

Documentation tasksIOException
-------------------
javadoc - Generates Javadoc API documentation for the main source code.

Help tasks
----------
buildEnvironment - Displays all buildscript dependencies declared in root project 'test01'.
components - Displays the components produced by root project 'test01'. [incubating]
dependencies - Displays all dependencies declared in root project 'test01'.
dependencyInsight - Displays the insight into a specific dependency in root project 'test01'.
help - Displays a help message.
model - Displays the configuration model of root project 'test01'. [incubating]
projects - Displays the sub-projects of root project 'test01'.
properties - Displays the properties of root project 'test01'.
tasks - Displays the tasks runnable from root project 'test01'.

Verification tasks
------------------
check - Runs all checks.
test - Runs the unit tests.

Rules
-----
Pattern: clean<TaskName>: Cleans the output files of a task.
Pattern: build<ConfigurationName>: Assembles the artifacts of a configuration.
Pattern: upload<ConfigurationName>: Assembles and uploads the artifacts belonging to a configuration.

To see all tasks and more detail, run gradle tasks --all

To see more detail about a task, run gradle help --task <task>

BUILD SUCCESSFUL

Total time: 2.147 secs
lucifer@lucifer-Vostro-V13:/source/gradle/160611/test01$





참조
http://knight76.tistory.com/entry/gradle-%EB%B9%8C%EB%93%9C-%EC%84%B1%EB%8A%A5-%EB%86%92%EC%9D%B4%EA%B8%B0
https://docs.gradle.org/2.13/userguide/gradle_daemon.html
https://docs.gradle.org/current/userguide/build_environment.html


[Linux] vim 에서 gradle 확장자의 syntax highlighting 되지 않는문제



OS: ubuntu 15.10 gnome
VIM ver: 7.4.712



증상

gradle 을 공부하면서 vi로 build.gradle 을 열어봤는데 groovy 형식의 syntax highlighting 이 되지 않았다.




해결 방법

아래와 같이 작업하면 groovy syntax highlighting 이 된다.
1004lucifer
1. vi로 gradle 파일을 오픈 후 :set filetype=groovy 라고 입력

 
2. 아래의 파일에 gradle 형식의 확장자를 지정해 준다. (권장)
/usr/share/vim/vim74/filetype.vim
(vim74 부분은 vim 버전에 따라 경로가 변경될 수 있다.)

" Vim support file to detect file types
"
" Maintainer:   Bram Moolenaar <Bram@vim.org>
" Last Change:  2015 Apr 06

" Listen very carefully, I will say this only once
if exists("did_load_filetypes")
  finish
endif
let did_load_filetypes = 1

" Line continuation is used here, remove 'C' from 'cpoptions'
let s:cpo_save = &cpo 
set cpo&vim

augroup filetypedetect

au BufNewFile,BufRead *.gradle setf groovy

" Ignored extensions






참조:
http://galsys.tumblr.com/post/51692458778/gradle-syntax-highlighting-in-vim
https://gist.github.com/uarun/1123563

2016년 6월 10일 금요일

[Tomcat] 톰캣이 정상적으로 기동되지 않는문제 (원인분석하기)





이따금씩 개발환경을 윈도우에서 톰캣을 띄워야 하는 경우가 있다.





톰캣을 구동시키려 startup.bat 파일을 실행하면 커맨드(cmd) 창이 나타났다가 에러메시지가 나타나고 바로 창이 닫혀버리기 때문에 뭐가 문제인지 확인도 못하고 어떻게 해야 할지 잘 모르는 경우가 있다.



이런경우 왜 톰캣이 정상적으로 구동되지 않는지 원인분석을 아래와 같은 방법으로 알아볼 수 있다.




startup.bat 파일은 내부적으로 catalina.bat 를 호출한다.
catalina.bat run 명령어를 통해 창이 따로 열리지 않은 상태에서 톰캣을 구동시킬 수 있기 때문에 창이 닫혀서 에러로그를 볼 수 없는 상황에서 벗어날 수 있다.

아래의 상황은 8009 포트가 이미 열려있기 때문에 톰캣을 정상적으로 구동할 수 없다고 나와있다.
그때의 상황은 IntelliJ IDEA 에서 톰캣을 이미 구동하고 있었기 때문에 포트가 겹쳐서 발생한 문제였다. 기존에 띄워진 톰캣을 종료시키니 정상적으로 톰캣을 띄울 수 있었다.

1004lucifer


K:\devTools\apache-tomcat-7.0.69\bin>catalina.bat run
Using CATALINA_BASE:   "K:\devTools\apache-tomcat-7.0.69"
Using CATALINA_HOME:   "K:\devTools\apache-tomcat-7.0.69"
Using CATALINA_TMPDIR: "K:\devTools\apache-tomcat-7.0.69\temp"
Using JRE_HOME:        "C:\Program Files\Java\jdk1.6.0_45"
Using CLASSPATH:       "K:\devTools\apache-tomcat-7.0.69\bin\bootstrap.jar;K:\devTools\apache-tomcat-7.0.69\bin\tomcat-juli.jar"
2016. 6. 10 오후 3:43:53 org.apache.catalina.startup.VersionLoggerListener log
정보: Server version:        Apache Tomcat/7.0.69
2016. 6. 10 오후 3:43:53 org.apache.catalina.startup.VersionLoggerListener log
정보: Server built:          Apr 11 2016 07:57:09 UTC
2016. 6. 10 오후 3:43:53 org.apache.catalina.startup.VersionLoggerListener log
정보: Server number:         7.0.69.0
2016. 6. 10 오후 3:43:53 org.apache.catalina.startup.VersionLoggerListener log
정보: OS Name:               Windows 7
2016. 6. 10 오후 3:43:53 org.apache.catalina.startup.VersionLoggerListener log
정보: OS Version:            6.1
2016. 6. 10 오후 3:43:53 org.apache.catalina.startup.VersionLoggerListener log
정보: Architecture:          amd64
2016. 6. 10 오후 3:43:53 org.apache.catalina.startup.VersionLoggerListener log
정보: Java Home:             C:\Program Files\Java\jdk1.6.0_45\jre
2016. 6. 10 오후 3:43:53 org.apache.catalina.startup.VersionLoggerListener log
정보: JVM Version:           1.6.0_45-b06
2016. 6. 10 오후 3:43:53 org.apache.catalina.startup.VersionLoggerListener log
정보: JVM Vendor:            Sun Microsystems Inc.
2016. 6. 10 오후 3:43:53 org.apache.catalina.startup.VersionLoggerListener log
정보: CATALINA_BASE:         K:\devTools\apache-tomcat-7.0.69
2016. 6. 10 오후 3:43:53 org.apache.catalina.startup.VersionLoggerListener log
정보: CATALINA_HOME:         K:\devTools\apache-tomcat-7.0.69
2016. 6. 10 오후 3:43:53 org.apache.catalina.startup.VersionLoggerListener log
정보: Command line argument: -Djdk.tls.ephemeralDHKeySize=2048
2016. 6. 10 오후 3:43:53 org.apache.catalina.startup.VersionLoggerListener log
정보: Command line argument: -Djava.util.logging.config.file=K:\devTools\apache-tomcat-7.0.69\conf\logging.properties
2016. 6. 10 오후 3:43:53 org.apache.catalina.startup.VersionLoggerListener log
정보: Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
2016. 6. 10 오후 3:43:53 org.apache.catalina.startup.VersionLoggerListener log
정보: Command line argument: -Djava.endorsed.dirs=K:\devTools\apache-tomcat-7.0.69\endorsed
2016. 6. 10 오후 3:43:53 org.apache.catalina.startup.VersionLoggerListener log
정보: Command line argument: -Dcatalina.base=K:\devTools\apache-tomcat-7.0.69
2016. 6. 10 오후 3:43:53 org.apache.catalina.startup.VersionLoggerListener log
정보: Command line argument: -Dcatalina.home=K:\devTools\apache-tomcat-7.0.69
2016. 6. 10 오후 3:43:53 org.apache.catalina.startup.VersionLoggerListener log
정보: Command line argument: -Djava.io.tmpdir=K:\devTools\apache-tomcat-7.0.69\temp
2016. 6. 10 오후 3:43:53 org.apache.catalina.core.AprLifecycleListener lifecycleEvent
정보: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: C:\Program
Files\Java\jdk1.6.0_45\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Windows\;C:\ProgramData\Oracle\Java\javapath;C:\Program Files (x86)\Intel\i
CLS Client\;C:\Program Files\Intel\iCLS Client\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program F
iles (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R
) Management Engine Components\IPT;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files\Git\cmd;C:\Program Files\Git\mingw64\bin;C:
\Program Files\Git\usr\bin;C:\Program Files\nodejs\;C:\Program Files (x86)\GtkSharp\2.12\bin;C:\sdk\android\platform-tools;K:\devTools\gradle-2.13\bin;C:\Window
s\Softcamp\SDS;C:\Windows\Softcamp\SDS\x64;C:\Windows\Softcamp\SDK;C:\Windows\Softcamp\SDK\x64;C:\Program Files\Bandizip\7z;C:\Users\HuhWook\AppData\Roaming\npm
;C:\Users\HuhWook\AppData\Local\atom\bin;.
2016. 6. 10 오후 3:43:53 org.apache.coyote.AbstractProtocol init
정보: Initializing ProtocolHandler ["http-bio-8080"]
2016. 6. 10 오후 3:43:53 org.apache.coyote.AbstractProtocol init
정보: Initializing ProtocolHandler ["ajp-bio-8009"]
2016. 6. 10 오후 3:43:53 org.apache.coyote.AbstractProtocol init
심각: Failed to initialize end point associated with ProtocolHandler ["ajp-bio-8009"]
java.net.BindException: Address already in use: JVM_Bind <null>:8009
        at org.apache.tomcat.util.net.JIoEndpoint.bind(JIoEndpoint.java:413)
        at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:650)
        at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:434)
        at org.apache.catalina.connector.Connector.initInternal(Connector.java:978)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
        at org.apache.catalina.core.StandardService.initInternal(StandardService.java:560)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
        at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:838)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:642)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:667)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:253)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:427)
Caused by: java.net.BindException: Address already in use: JVM_Bind
        at java.net.PlainSocketImpl.socketBind(Native Method)
        at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:383)
        at java.net.ServerSocket.bind(ServerSocket.java:328)
        at java.net.ServerSocket.<init>(ServerSocket.java:194)
        at java.net.ServerSocket.<init>(ServerSocket.java:150)
        at org.apache.tomcat.util.net.DefaultServerSocketFactory.createSocket(DefaultServerSocketFactory.java:49)
        at org.apache.tomcat.util.net.JIoEndpoint.bind(JIoEndpoint.java:400)
        ... 16 more
2016. 6. 10 오후 3:43:53 org.apache.catalina.core.StandardService initInternal
심각: Failed to initialize connector [Connector[AJP/1.3-8009]]
org.apache.catalina.LifecycleException: Failed to initialize component [Connector[AJP/1.3-8009]]
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:106)
        at org.apache.catalina.core.StandardService.initInternal(StandardService.java:560)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
        at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:838)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:642)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:667)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:253)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:427)
Caused by: org.apache.catalina.LifecycleException: Protocol handler initialization failed
        at org.apache.catalina.connector.Connector.initInternal(Connector.java:980)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
        ... 12 more
Caused by: java.net.BindException: Address already in use: JVM_Bind <null>:8009
        at org.apache.tomcat.util.net.JIoEndpoint.bind(JIoEndpoint.java:413)
        at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:650)
        at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:434)
        at org.apache.catalina.connector.Connector.initInternal(Connector.java:978)
        ... 13 more
Caused by: java.net.BindException: Address already in use: JVM_Bind
        at java.net.PlainSocketImpl.socketBind(Native Method)
        at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:383)
        at java.net.ServerSocket.bind(ServerSocket.java:328)
        at java.net.ServerSocket.<init>(ServerSocket.java:194)
        at java.net.ServerSocket.<init>(ServerSocket.java:150)
        at org.apache.tomcat.util.net.DefaultServerSocketFactory.createSocket(DefaultServerSocketFactory.java:49)
        at org.apache.tomcat.util.net.JIoEndpoint.bind(JIoEndpoint.java:400)
        ... 16 more
2016. 6. 10 오후 3:43:54 org.apache.catalina.startup.Catalina load
정보: Initialization processed in 787 ms
2016. 6. 10 오후 3:43:54 org.apache.catalina.core.StandardService startInternal
정보: Starting service Catalina
2016. 6. 10 오후 3:43:54 org.apache.catalina.core.StandardEngine startInternal
정보: Starting Servlet Engine: Apache Tomcat/7.0.69
2016. 6. 10 오후 3:43:54 org.apache.catalina.startup.HostConfig deployDirectory
정보: Deploying web application directory K:\devTools\apache-tomcat-7.0.69\webapps\docs
2016. 6. 10 오후 3:43:54 org.apache.tomcat.websocket.server.WsSci onStartup
정보: JSR 356 WebSocket (Java WebSocket 1.1) support is not available when running on Java 6. To suppress this message, run Tomcat on Java 7, remove the WebSock
et JARs from $CATALINA_HOME/lib or add the WebSocket JARs to the tomcat.util.scan.DefaultJarScanner.jarsToSkip property in $CATALINA_BASE/conf/catalina.properti
es. Note that the deprecated Tomcat 7 WebSocket API will be available.
2016. 6. 10 오후 3:43:54 org.apache.catalina.startup.HostConfig deployDirectory
정보: Deployment of web application directory K:\devTools\apache-tomcat-7.0.69\webapps\docs has finished in 386 ms
2016. 6. 10 오후 3:43:54 org.apache.catalina.startup.HostConfig deployDirectory
정보: Deploying web application directory K:\devTools\apache-tomcat-7.0.69\webapps\examples
2016. 6. 10 오후 3:43:54 org.apache.catalina.startup.HostConfig deployDirectory
정보: Deployment of web application directory K:\devTools\apache-tomcat-7.0.69\webapps\examples has finished in 266 ms
2016. 6. 10 오후 3:43:54 org.apache.catalina.startup.HostConfig deployDirectory
정보: Deploying web application directory K:\devTools\apache-tomcat-7.0.69\webapps\host-manager
2016. 6. 10 오후 3:43:54 org.apache.catalina.startup.HostConfig deployDirectory
정보: Deployment of web application directory K:\devTools\apache-tomcat-7.0.69\webapps\host-manager has finished in 67 ms
2016. 6. 10 오후 3:43:54 org.apache.catalina.startup.HostConfig deployDirectory
정보: Deploying web application directory K:\devTools\apache-tomcat-7.0.69\webapps\manager
2016. 6. 10 오후 3:43:54 org.apache.catalina.startup.HostConfig deployDirectory
정보: Deployment of web application directory K:\devTools\apache-tomcat-7.0.69\webapps\manager has finished in 62 ms
2016. 6. 10 오후 3:43:54 org.apache.catalina.startup.HostConfig deployDirectory
정보: Deploying web application directory K:\devTools\apache-tomcat-7.0.69\webapps\ROOT
2016. 6. 10 오후 3:43:54 org.apache.catalina.startup.HostConfig deployDirectory
정보: Deployment of web application directory K:\devTools\apache-tomcat-7.0.69\webapps\ROOT has finished in 48 ms
2016. 6. 10 오후 3:43:54 org.apache.catalina.startup.HostConfig deployDirectory
정보: Deploying web application directory K:\devTools\apache-tomcat-7.0.69\webapps\tservice
2016. 6. 10 오후 3:43:54 org.apache.catalina.startup.HostConfig deployDirectory
정보: Deployment of web application directory K:\devTools\apache-tomcat-7.0.69\webapps\tservice has finished in 57 ms
2016. 6. 10 오후 3:43:54 org.apache.coyote.AbstractProtocol start
정보: Starting ProtocolHandler ["http-bio-8080"]
2016. 6. 10 오후 3:43:55 org.apache.catalina.startup.Catalina start
정보: Server startup in 983 ms
2016. 6. 10 오후 3:43:55 org.apache.catalina.core.StandardServer await
심각: StandardServer.await: create[localhost:8005]:
java.net.BindException: Address already in use: JVM_Bind
        at java.net.PlainSocketImpl.socketBind(Native Method)
        at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:383)
        at java.net.ServerSocket.bind(ServerSocket.java:328)
        at java.net.ServerSocket.<init>(ServerSocket.java:194)
        at org.apache.catalina.core.StandardServer.await(StandardServer.java:444)
        at org.apache.catalina.startup.Catalina.await(Catalina.java:781)
        at org.apache.catalina.startup.Catalina.start(Catalina.java:727)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:294)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:428)
2016. 6. 10 오후 3:43:55 org.apache.coyote.AbstractProtocol pause
정보: Pausing ProtocolHandler ["http-bio-8080"]
2016. 6. 10 오후 3:43:55 org.apache.coyote.AbstractProtocol pause
정보: Pausing ProtocolHandler ["ajp-bio-8009"]
2016. 6. 10 오후 3:43:55 org.apache.catalina.core.StandardService stopInternal
정보: Stopping service Catalina
2016. 6. 10 오후 3:43:55 org.apache.coyote.AbstractProtocol stop
정보: Stopping ProtocolHandler ["http-bio-8080"]
2016. 6. 10 오후 3:43:55 org.apache.coyote.AbstractProtocol destroy
정보: Destroying ProtocolHandler ["http-bio-8080"]
2016. 6. 10 오후 3:43:55 org.apache.coyote.AbstractProtocol stop
정보: Stopping ProtocolHandler ["ajp-bio-8009"]
2016. 6. 10 오후 3:43:55 org.apache.coyote.AbstractProtocol destroy
정보: Destroying ProtocolHandler ["ajp-bio-8009"]

K:\devTools\apache-tomcat-7.0.69\bin>






2016년 6월 6일 월요일

[GAE] 서비스 기동 시 'Problem accessing /. Reason' 발생하는 문제





OS: ubuntu 15.10 gnome
Tool: IntelliJ IDEA 2016.1.1 (#IU-145.597)
GAE: Google App Engine 1.9.34




문제

IntelliJ 에서 Spring 셋팅 후 GAE(Google App Engine) Dev Server 로 기동 시 아래와 같은 모습이 보여졌다.





HTTP ERROR 503

Problem accessing /. Reason:
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#0': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.handler.MappedInterceptor#0': Cannot create inner bean '(inner bean)#63b1d4fa' of type [org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#63b1d4fa': Cannot resolve reference to bean 'org.springframework.format.support.FormattingConversionServiceFactoryBean#0' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.format.support.FormattingConversionServiceFactoryBean#0': Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: java.time.format.FormatStyle is a restricted class. Please see the Google  App Engine developer's guide for more details.

Caused by:

javax.servlet.UnavailableException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#0': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.handler.MappedInterceptor#0': Cannot create inner bean '(inner bean)#63b1d4fa' of type [org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#63b1d4fa': Cannot resolve reference to bean 'org.springframework.format.support.FormattingConversionServiceFactoryBean#0' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.format.support.FormattingConversionServiceFactoryBean#0': Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: java.time.format.FormatStyle is a restricted class. Please see the Google  App Engine developer's guide for more details.
 at org.mortbay.jetty.servlet.ServletHolder.makeUnavailable(ServletHolder.java:415)
 at org.mortbay.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:458)
 at org.mortbay.jetty.servlet.ServletHolder.doStart(ServletHolder.java:263)
 at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
 at org.mortbay.jetty.servlet.ServletHandler.initialize(ServletHandler.java:685)
 at org.mortbay.jetty.servlet.Context.startContext(Context.java:140)
 at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
 at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
 at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
 at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
 at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
 at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
 at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
 at org.mortbay.jetty.Server.doStart(Server.java:224)
 at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
 at com.google.appengine.tools.development.JettyContainerService.startContainer(JettyContainerService.java:273)
 at com.google.appengine.tools.development.AbstractContainerService.startup(AbstractContainerService.java:283)
 at com.google.appengine.tools.development.AutomaticInstanceHolder.startUp(AutomaticInstanceHolder.java:26)
 at com.google.appengine.tools.development.AbstractModule.startup(AbstractModule.java:87)
 at com.google.appengine.tools.development.Modules.startup(Modules.java:105)
 at com.google.appengine.tools.development.DevAppServerImpl.doStart(DevAppServerImpl.java:258)
 at com.google.appengine.tools.development.DevAppServerImpl.access$000(DevAppServerImpl.java:47)
 at com.google.appengine.tools.development.DevAppServerImpl$1.run(DevAppServerImpl.java:213)
 at com.google.appengine.tools.development.DevAppServerImpl$1.run(DevAppServerImpl.java:211)
 at java.security.AccessController.doPrivileged(Native Method)
 at com.google.appengine.tools.development.DevAppServerImpl.start(DevAppServerImpl.java:211)
 at com.google.appengine.tools.development.DevAppServerMain$StartAction.apply(DevAppServerMain.java:277)
 at com.google.appengine.tools.util.Parser$ParseResult.applyArgs(Parser.java:48)
 at com.google.appengine.tools.development.DevAppServerMain.run(DevAppServerMain.java:225)
 at com.google.appengine.tools.development.DevAppServerMain.main(DevAppServerMain.java:216)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:498)
 at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

Powered by Jetty://








해결


인터넷을 찾아보니 두가지 방법이 나왔다.
1004lucifer
1. jetty 버전 업데이트
2. JAVA JDK 버전 변경


jetty 를 내가 직접 설정하여 쓰는게 아니다보니 나는 두번째 방법을 선택했다.





PS.
Maven 에 jetty를 설정한 경우라면 jetty 버전을 변경해 보거나
GAE를 command 로 실행시킨 경우라면 JAVA_HOME 을 변경하면 해결 할 수 있을 것 같다.





참고: http://stackoverflow.com/questions/9565273/google-app-engine-service-unavailable


2016년 6월 1일 수요일

[Grunt] grunt build 할 시 "ngtemplates:dist" 부분에서 멈추는 증상



OS: Ubuntu 15.10 gnome



증상

angular-full-stack(Link) 을 사용하여 작업 후 마지막에


$ grunt build

작업을 했는데




lucifer@lucifer-Vostro-V13:/source/yeoman/Angular_CreateJS_Wedding$ grunt build
Running "clean:dist" (clean) task
>> 79 paths cleaned.

Running "wiredep:app" (wiredep) task

Running "wiredep:test" (wiredep) task

Running "useminPrepare:html" (useminPrepare) task
Configuration changed for concat, uglify, cssmin

Running "concurrent:dist" (concurrent) task
   
    Running "copy:styles" (copy) task
    Copied 1 file
   
    Done, without errors.
   
   
    Execution Time (2016-05-31 15:16:06 UTC)
    loading tasks               741ms  ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 84%
    loading grunt-contrib-copy   93ms  ▇▇▇▇ 10%
    copy:styles                  49ms  ▇▇ 6%
    Total 886ms
       
    Running "svgmin:dist" (svgmin) task
    Total saved: 0 B
   
    Done, without errors.
   
   
    Execution Time (2016-05-31 15:16:06 UTC)
    loading tasks         579ms  ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 50%
    loading grunt-svgmin  381ms  ▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 33%
    svgmin:dist           196ms  ▇▇▇▇▇▇▇ 17%
    Total 1.2s
       
    Running "imagemin:dist" (imagemin) task
    Minified 5 images (saved 5.4 kB)
   
    Done, without errors.
   
   
    Execution Time (2016-05-31 15:16:06 UTC)
    loading tasks                   785ms  ▇▇▇▇ 11%
    loading grunt-contrib-imagemin   1.1s  ▇▇▇▇▇ 15%
    imagemin:dist                    5.2s  ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 74%
    Total 7s
   
Running "postcss:server" (postcss) task
>> 1 processed stylesheet created.

Running "postcss:dist" (postcss) task
>> 1 processed stylesheet created.

Running "ngtemplates:dist" (ngtemplates) task




위와같이 마지막에
'Running "ngtemplates:dist" (ngtemplates) task'
라는 부분에서 넘어가지 않고 무한정 기다리기만 했다.





원인 및 해결방법

Grunt 옵션을 보니 디버깅(-d), 추가정보(-v) 옵션이 있어서 아래와 같이 사용을 했다.
1004lucifer
$ grunt -dv build

로그를 확인해보니 특정 HTML 파일을 minifying 하는 부분에서 더 이상 넘어가지 않았다.
소스를 다시한번 확인해보니 특정 태그의 style 속성이 잘못되어 있었다.

ex) <div style="font:normal 12px "돋움", dotum; position:absolute;">


해당 부분을 올바르게 수정해주니 정상적으로 빌드가 되는 것을 확인 할 수 있었다.