will come true

이클립스(eclipse)에서 작업한 .java파일 cmd창에서 실행하기, 메인 메소드에 인자 전달하기 본문

Java

이클립스(eclipse)에서 작업한 .java파일 cmd창에서 실행하기, 메인 메소드에 인자 전달하기

haehyun 2021. 9. 30. 18:14

1. 이클립스에서 아래와 같은 소스코드를 작성해준다.

- 커맨드라인(cmd창)에서 입력을 통해 전달받은 인자 값을 사용해서 연산을 수행하는 프로그램.

- 커맨드 라인으로 부터 전달받은 인자는 public static void main(String[] args) {} 메서드의 args매개변수에 문자열 배열형태로 하나씩 전달됨.

- 패키지명 : jungsuk / 소스파일명 : Exercise5_7.java 

package jungsuk;

public class Exercise5_7 {

	public static void main(String[] args) {
		//커맨드라인으로 전달받은 인자 체크
		if(args.length != 1) {
			System.out.println("USAGE: java Exercise5_7 3120");
			System.exit(0);
		}
		
		//문자열을 숫자로 변환 (커맨드로 받은 인자는 무조건 문자열)
		int money = Integer.parseInt(args[0]);
				
		System.out.println("money="+money);
		
		int[] coinUnit = {500, 100, 50, 10};	//동전의 단위
		int[] coin = {5, 5, 5, 5};				//단위별 동전의 개수
		
		for(int i=0; i<coinUnit.length; i++) {
			int coinNum = 0;
			
			coinNum = money/coinUnit[i];		//필요한 동전개수
			if(coinNum>coin[i]) {
				coinNum = coin[i];				//동전 부족, 있는 만큼만 사용
			}
						
			coin[i] -= coinNum;					//동전개수 차감
			money -= (coinUnit[i]*coinNum);		//전체 값에서 동전단위*돈전개수 만큼 빼기

			System.out.println(coinUnit[i]+"원: "+coinNum);
		}
		
		//전체 값이 아직 남아있으면, 거스름돈이 부족해 덜 거슬러준 것
		if(money > 0) {
			System.out.println("거스름돈이 부족합니다.");
			System.exit(0);
		}
		
		System.out.println("=남은 동전의 개수=");
		
		for(int i=0; i<coinUnit.length; i++) {
			System.out.println(coinUnit[i]+"원:"+coin[i]);
		}
	}
}

 

2. 이클립스에서 해당 프로그램을 실행하면 커맨드라인 입력값이 없어서 if(args.length != 1) 조건에 걸리게 된다.

 

3. 위 프로그램을 제대로 테스트하기 위해서는 cmd창에서 실행해줘야 한다. 

시작메뉴에서 '명령 프롬프트'를 실행하거나, 실행창(Windows키+R)에서 'cmd'를 입력해서 cmd창을 켜준다.

 

4. 이클립스에서 소스코드를 실행했으면, eclipse-workspace의 bin폴더에 컴파일 결과물인 클래스파일(.class)이 생성되어 있을텐데, 파일 탐색기에서 해당 위치를 찾아간다.

D:\eclipse-workspace\{프로젝트명}\src\{패키지명} 에 위치한 소스파일(Exercise5_7.java)가 컴파일 된 결과물은 

D:\eclipse-workspace\{프로젝트명}\bin\{패키지명}클래스파일(Exercise5_7.class)로 저장된다.

(eclipse-workspace 위치는 사용자가 이클립스 실행시 설정한 경로에 따라 다름. 내 경우에는 D드라이브인 것.)

패키지명이 com.jungsuk과 같이 점(.)으로 구분되어 있을 경우 여러 폴더로 계층을 이루게됨. 컴파일 과정에서 소스코드에 적힌 package 패키지명; 구문을 읽어 패키지명에 따라 디렉터리를 자동 생성해줌.

D:\eclipse-workspace\TestProject\bin\jungsuk

 

5. 실행하고자 하는 프로그램이 속한 패키지 폴더(jungsuk) 바로 앞 bin폴더로 이동 후, 그 상태에서 경로를 복사한다.

ex) D:\eclipse-workspace\TestProject\bin

 

6. cmd창에서 해당 경로로 이동한다.

C드라이브에서 D드라이브로 이동 > D:

드라이브 내에서 디렉터리 이동    > cd D:\eclipse-workspace\TestProject\bin   ← 위에서 복사해둔 경로

 

7. 아래 명령어를 입력하여 클래스파일을 실행할 수 있으며 뒤에 값을 입력해서 프로그램에 인자값을 넘길 수 있다.

프로그램 실행 > java 패키지명.파일명 인자값

 

위 과정에서 

1. 오류: 기본 클래스을(를) 찾거나 로드할 수 없습니다.

2. Error: A JNI error has occurred, please check your installation and try again

이 두 오류가 나타날 경우 아래와 같이 해결한다. 

 

1. 오류: 기본 클래스을(를) 찾거나 로드할 수 없습니다.

1) '제어판-시스템-고급 시스템 설정-환경변수'에서 CLASSPATH 환경변수를 만들어서 지정해뒀는지 확인한다. 

클래스패스(classpath) : 컴파일러(javac.exe)나 JVM 등이 클래스의 위치를 찾는데 사용되는 경로. 지정해 주지 않을 시 현재 디렉토리(폴더 위치)가 클래스패스로 지정된다.

 

클래스패스(classpath)를 잘못 지정해뒀을 경우, JVM에서는 해당 경로만을 탐색하기 때문에 아무리 cmd창에서 cd명령어를 통해 클래스파일(.class)과 관련된 위치로 이동해도 JVM은 이동한 위치를 탐색 대상에 포함시키지 않는다. 그렇기 때문에 실행할 프로그램의 기본 클래스를 찾거나 로드할 수 없다는 오류가 표시되는 것. 

 

클래스패스를 아예 지정해두지 않았을 경우, 자동으로 현재 디렉터리가 클래스패스로 지정되지만 클래스패스를 별도로 지정해뒀을 경우 현재 디렉터리가 자동으로 지정되지 않기 때문. (별도로 지정해둔 위치만 탐색대상)

 

환경변수에서 CLASSPATH 자체를 지워주거나, 현재 디렉터리도 탐색 대상에 포함되도록 CLASSPATH를 편집해준다.

(입력되어 있는 CLASSPATH 뒤에 .; 를 추가입력 / .은 현재 디렉터리를 의미, ;은 구분자)

 

2) 또는 cmd창에서 잘못된 디렉터리로 이동한채로 명령어를 수행해서 그런걸수도 있다.

이클립스로 소스코드를 작성하고 실행했을 경우, 

소스파일(.java)는 D:\eclipse-workspace\TestProject\src\jungsuk

클래스파일(.class)는 D:\eclipse-workspace\TestProject\bin\jungsuk 에 위치한다는 걸 명심하며,

java 패키지명.파일명 명령어를 통해 프로그램을 실행할 시 위치는 패키지 폴더의 바로위 폴더여야 한다.

 

 

2. Error: A JNI error has occurred, please check your installation and try again

D:\eclipse-workspace\HelloWorld\src\hello>java HelloTest
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.UnsupportedClassVersionError: HelloTest has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(Unknown Source)
        at java.security.SecureClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.access$100(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)

 

파일이 더 최신의 java버전으로 컴파일 되었으니, java 버전을 업그레이드하라는 뜻이다. 

파일을 더 낮은 버전의 java로 컴파일 하거나, 실행하려는 java를 최신버전으로 업데이트해준다. 

Comments