※ 참고
OS : CentOS Linux release 7.4.1708 (Core)
JAVA : openjdk version "1.8.0_151"
리눅스에서 Java를 사용해서 프로그램 하나를 작성했다.
컴파일은 문제 없이 되었고, 더욱 편하게 컴파일 하기 위해 Makefile을 작성했다.
그리고 이 프로그램은 백그라운드에서 돌아야하기 때문에 commons-daemon 이라는 라이브러리를 사용해서 데몬으로 만들었다.
[그림] 내가 생성한 프로젝트 폴더 구조
- 프로젝트 컴파일 및 실행과정
# make 명령어를 주면 /src 폴더에 있는 .java 파일들을 컴파일해서 나온 .class 파일들을 /bin 폴더 안에 넣는다.
# jar -uvf ... 명령어를 주면 .class 파일들을 .jar 파일로 압축한다. (이후 -uvf 명령어로 .jar 파일을 업데이트한다)
# ./TestProject.bin start 명령어를 주면 스크립트 파일이 프로젝트를 실행한다.
이 상황에서 데몬 실행중에 'ClassNotFoundException' 이라는 에러가 발생했다.
- 에러 발생 상황
# make clean을 실행하고(/bin 폴더의 *.class, /out 폴더의 daemon.* 삭제됨)
# cd bin
# rm TestProject.jar
# cd ..
# jar -cvf bin/TestProject.jar bin/*.class
# ./TestProject.bin start
...
...ClassNotFoundException
...
제대로 생성하지 않았다?
다음의 경우에는 에러가 발생하지 않았다.
- 실행이 잘됨
# make clean을 실행하고(/bin 폴더의 *.class, /out 폴더의 daemon.* 삭제됨)
# cd bin
# rm TestProject.jar
# jar -cvf TestProject.jar *.class
# cd ..
# ./TestProject.bin start
...
실행 잘됨
...
차이점은? jar 생성할 때 현재 디렉토리가 어딘지에 따른 차이...
혹시 상대 경로로 실행해서 그런건가?
- 절대경로로 바꿔봄
...
# jar -cvf /root/test/bin/TestProject.jar /root/test/bin/*.class
# ./TestProject.bin start
...
...ClassNotFoundException
...
에러 발생
jar를 -cvf 옵션을 줘서 만드는게 아니라 -uvf 옵션을 줘서 업데이트를 한다면? 역시나 같은 문제 발생.
만약 실행이 잘된 상황에서 소스코드에 Print문을 수정한 후, 소스코드 컴파일, jar 업데이트, 스크립트 실행 순으로 했을 때 결과 값은
수정 전의 프로젝트가 실행이 된다.
결론, jar 파일을 생성이나 업데이트할 땐, Class 파일이 존재하는 폴더에서 해야한다는 것
1. jar -uvf TestProject.jar bin/*.class (X)
2. jar -uvf ../TestProject.jar *.class (O)
3. jar -uvf TestProject.jar *.class(O)
뭐 때문에 이런거지? 버그인가?