[Trouble Shooting] CLI를 이용하여 외부 라이브러리를 포함한 Java파일 Compile 및 실행하기(Classpath)

2019. 9. 25. 16:47개발/기타

얼마 전, 모듈 개발 중 누적 확률정규분포의 역함수로 표준 정규분포를 따르는 난수를 생성해야했는데요, 수학에 약한 저는 여기저기 정규분포 관련 클래스를 찾아보다가 apache에서 제공하는 NormalDistribution이라는 클래스와 inverinverseCumulativeProbability 함수를 이용하면 된다는 것을 알아냈습니다. 하지만..

 

Eclipse나 IntelliJ와 같은 IDE만 사용해왔던 저는  CLI를 통해 외부 라이브러리를 포함한 Java 파일 Compile 및 실행하는 법 을 몰라서 한참을 헤매게 되었고 오늘은 그 과정에서 발생했던 트러블과 해결방법에 대해 공유를 해보고자합니다.

 

우선, 외부 class를 사용하기 때문에 import 패키지명.클래스명을 선언해준 후,

import org.apache.commons.math3.distribution.NormalDistribution;

jar파일을 다운 받아 컴파일을 시도하였습니다.

> javac 클래스명.java

클래스가 어디에 있는지 모르겠다고 합니다.

 

 

열심히 구글링을 해본 결과    외부 라이브러리 jar파일을 함께 컴파일, 실행할 시에는 classpath를 명시해주어야한다 고 합니다.

 

더보기

클래스패스(Class Path)

클래스패스란 말 그대로 클래스를 찾기위한 경로입니다. 즉, JVM이 프로그램을 실행할 때, 클래스파일을 찾는데 기준이 되는 파일 경로를 말하는 것입니다. 소스 코드(.java로 끝나는 파일)를 컴파일하면 소스 코드가 “바이트 코드”(바이너리 형태의 .class 파일)로 변환됩니다. java runtime(java 또는 jre)으로 이 .class 파일에 포함된 명령을 실행하려면, 먼저 이 파일을 찾을 수 있어야 합니다. 이때 .class 파일을 찾을 때 classpath에 지정된 경로를 사용합니다. classpath는 .class 파일이 포함된 디렉토리와 파일을 콜론(혹은 세미클론)으로 구분한 목록입니다. java runtime은 이 classpath에 지정된 경로를 모두 검색해서 특정 클래스에 대한 코드가 포함된 .class 파일을 찾습니다. 찾으려는 클래스 코드가 포함된 .class 파일을 찾으면 첫 번째로 찾은 파일을 사용합니다.

classpath를 지정할 수 있는 두 가지 방법이 있습니다. 하나는 환경 변수 CLASSPATH를 사용하는 방법이고, 또 하나는 java runtime에 -classpath 플래그를 사용하는 방법입니다.

[코딩하는 오징어]

아래와 같이 -cp를 이용하여 jar파일의 경로를 지정해주고 나니 컴파일에 성공했습니다! (저는 java파일과 jar파일을 같은 폴더에 둔 채로 실행하였습니다.)

> javac -cp commons-math3-3.0.jar 클래스명.java

정상적으로 .class파일이 생성되었고 .class파일을 이용하여 실행을 했습니다. 하지만 결과는 실패..

> java -cp commons-math3-3.0.jar 클래스명

 

왜 실행은 실패했을까요?

 

 이미 compile 된 class 실행 시에는 .jar 파일의 경로 뿐만 아니라, 실행하려는 class의 파일이 존재하는 경로도 지정을 해주어야 합니다.  이 때, windows 운영체제에서는 ; (세미클론)으로, 그 외의 운영체제에서는 : (클론)으로 구분을 해줍니다.

 

compile : 외부 라이브러리 jar파일의 classpath를 명시

> javac -cp commons-math3-3.0.jar 클래스명.java

실행 : 현재 class 파일이 존재하는 경로와 .jar파일의 경로까지 명시

> java -cp .;commons-math3-3.0.jar 클래스명

성공입니다. yeah!

 


 References 

https://docs.oracle.com/javase/7/docs/technotes/tools/windows/classpath.html

http://blog.kiyeon.net/2015/06/25/command-lineeseo-java-jagseonghago-silhaenghagi/ https://stackoverflow.com/questions/6069702/java-command-line-with-external-jar