※ 본 포스팅은 생활코딩 이고잉님의 강의를 공부한 후 개인적인 학습목적으로 작성하였습니다. 생활코딩에서 더 자세하고 정확한 정보를 얻으시려는 분들은 아래 참고자료를 확인해주세요. ※
직접 컴파일하고 실행하기
이번 수업에서는 이클립스 같은 개발 도구를 이용하지 않고 직접 자바로 만든 프로그램을 컴파일하고 실행하는 방법을 살펴보겠습니다. 이 방법을 알 수 있게 되면 어떤 컴퓨터나 환경에서도 자바만 있다면 이클립스 같은 개발 도구 없이도 프로그램을 컴파일하고 실행할 수 있게 됩니다. 다만 당분간은 개발 도구가 없는 곳에서 자바를 사용할 일은 없을 것입니다. 또 직접 소스코드를 컴파일하고 실행하려면 현재 사용 중인 운영체제에 대한 많은 지식이 필요합니다. 이런 상황일수록 송부를 하려면 전략이 중요합니다. 이번 수업에서는 진행하는 내용을 따라서 같이 한번 해보되, 안 되는 부분이 나오면 과감히 실습 모드에서 구경 모드로 기민하게 전환하면 좋겠습니다. 실습을 하는 대신에 자바가 동작하는 흐름을 음미하면서 ‘아 이렇게 동작하는 거구나’, ‘아 나중에 이렇게 하면 되겠구나’라고 생각하면 더 좋겠습니다. 언젠가 미래에 여러분이 직접 실습하지 않을 수 없는 순간이 올 것입니다. 그때까지 미뤄두시면 됩니다. 이번 수업에서 다룰 중요한 내용은 다음 세 가지 입니다.
첫째, 확장자가 .java인 소스코드를 확장자가 .class인 실행 파일로 바꾸는 것입니다. 이를 컴파일(compile)이라고 합니다. 둘째, 확장자가 .class인 파일을 실행하는 것입니다. 이를 실행(Run)이라고 합니다. 셋째, 프로그램을 실행할 때 입력값을 주고, 입력값에 따라 다른 출력값을 만드는 것입니다. 이를 위해서 이전 수업에서 진행했던 예제를 사용하겠습니다.
Program.java 파일을 컴파일해서 실행 가능한 파일인 Program.class 파일을 만들어 보겠습니다. 그러고 나서 Program.class 파일을 자바로 실행해 볼 것입니다. 그 다음으로는 OKJavaGOInHome.java 파일을 컴파일해서 클래스 파일을 만들고 마찬가지로 OkJavaGOInHome.class 파일을 실행하겠습니다. 이 예제가 조금 더 어려운 이유는 Elevator 클래스는 위 예제 파일에 있지 않고, 로드한 org.opentutorials.iot.Elevator 경로에 있기 때문입니다. 즉, org.opentutorials.iot 폴더에 Elevator.java 파일이 로딩돼야 OkJavaGOInHome.java 파일을 실행할 수 있습니다. 마지막으로, OkJavaGoHomeInput 예제는 args라는 변수를 통해 사용자가 입력한 정보를 가져와서 출력하는 프로그램입니다. 즉, 프로그램을 실행할 때 어떻게 입력값을 받을 수 있는가라는 문제가 있습니다. 다시 한번 강조하지만, 우리에게 필요한 지식이 다 있어야 일을 할 수 있는 것이 아닙니다. 지금껏 우리는 양자역학을 모르고도 잘 살아왔습니다. 지금 여러분에게 필요한 것은 인식을 확장시키는 것이기 때문에 모든 것을 다 이해하려고 하지 말고 모든 실습을 다 성공하려고 하지 않기를 바랍니다. 이어지는 다음 시간에 구체적인 작업을 시작해 보겠습니다.
직접 컴파일하고 실행하고 : 실행 환경 살펴보기
윈도우 환경에서는 윈도우 탐색기를 우선 열어둡니다. 자바 소스코드를 컴파일하려면 명령어로 컴파일해야 합니다. 그래서 컴퓨터를 제어하는 명령어를 실행할 수 있는 프로그램을 실행해야 합니다. Windows R 을 클릭하면 ‘실행’이라는 프로그램이 나타납니다. ‘실행’ 프로그램에 ‘cmd’라고 입력하고 엔터를 치면 검은 화면으로 된 명령 프롬프트가 실행됩니다. 그럼 이 명령 프롬프트를 이용해 컴퓨터에 명령을 내리고 소스코드를 컴파일할 수 있게 될 것입니다. 자바 소스코드를 컴파일하고 실행하려면 javac라고 하는 것을 이용하면 됩니다. 다음과 같이 javac와 java를 실행하면 각각의 사용법이 나옵니다.
그런데, 이 프로그램들이 어디에 있는지 궁금하지 않으신가요? java와 javac 두 프로그램이 어디에 위치하는지 알려드리겠습니다. Program Files 폴더로 가면 jdk로 시작하는 폴더가 있습니다. jdk로 들어가면 바이너리를 의미하는 bin 폴더가 있고, 이 폴더 안에 “java.exe”와 “javac.exe” 파일이 있습니다.
java라고 명령을 내렸을 때 java 명령어가 현재 어디에 있든 실행되는 이유는 무엇일까요? 이것은 바로 PATH라고 부르는 환경 변수 때문입니다. 먼저 윈도우에서 환경 변수를 설정하는 방법은 다음과 같습니다. 윈도우 탐색기에서 내 PC 우 클릭 - 속성 - 고급 시스템 설정 - 고급 - 환경 변수로 이동합니다.
그럼 이런 화면이 보이게 됩니다. 여기서 <사용자명>에 대한 사용자 변수는 현재 사용자 계정에서만 사용하는 환경 변수이고, [시스템 변수]는 이 시스템을 사용하는 모든 유저들이 사용하는 환경 변수입니다. 현재 사용자 계정의 환경 변수가 시스템 환경 변수보다 우선순위가 높습니다. 여기서 PATH 변수를 더블클릭하면 Java가 설치된 것을 확인할 수 있습니다. 따라서 명령 프롬프트에서 java라고 명령을 내리고 엔터를 치면 운영체제는 현재 디렉터리에 java 프로그램이 없으면 환경 변수의 Path를 참조해서 설정된 경로 중에서 java 프로그램이 있는지 확인합니다. 현재 디렉터리와 환경 변수의 Path에 설정된 경로에 java 프로그램이 없으면 ‘파일을 찾을 수 없습니다’라는 에러를 띄웁니다. 만약 명령 프롬프트에서 java 프로그램이 실행되지 않는다면 Path 환경 변수에 java 프로그램의 경로를 추가하면 됩니다. 환경 변수에 경로를 추가하려면 [환경 변수 편집] 창에서 [편집] 버튼을 클릭하고 경로를 추가한 후 [확인] 버튼을 누르고 창을 닫으면 됩니다.
직접 컴파일하고 실행하기 : 컴파일과 실행하기
이번 수업에서는 이클립스 없이 직접 자바 소스코드를 컴파일하고 실행해 보겠습니다. 먼저 윈도우에서 소스코드를 컴파일하려면 소스코드가 위치한 디렉터리로 이동해야 합니다. 명령 프롬프트에서 소그코드가 위치한 경로로 이동하려명 cd 명령어 다음에 한 칸 띄우고 이동할 경로를 입력하면 됩니다. 하다가 안되면 전 시간에서 말씀드렸다시피 구경모드로 전환을 하십시오.
먼저 Program.java 파일을 컴파일해서 클래스 파일을 만들겠습니다. 클래스 파일을 만들 때 사용하는 명령어가 ‘javac’입니다. 터미널에서 javac를 입력하고 엔터를 치면 javac 프로그램을 사용하는 방법이 나옵니다.
javac 명령어를 입력하고 화면에 출력되는 Usage를 보면 javac를 입력하고 options와 소스 파일 경로를 입력하라고 나옵니다. oprions는 javac를 필요에 따라 다양하게 동작하게 할 때 사용하는 것입니다. 여기서는 옵션을 사용하지 않고 컴파일하기 때문에 javac 명령어 다음에 한 칸 띄우고 소스파일의 경로를 입력하면 됩니다. javac Program.java 라는 명령어를 통해서 컴파일을 진행해 줍니다. macOS나 리눅스에서는 ls 명령어로, 윈도우에서는 dir 명령어로 현재 디렉터리에 위치한 파일을 확인하면 Program.class 파일이 생성된 것을 확인할 수 있습니다. Program.class 파일이 있으면 컴파일하는 데 성공한 것입니다. 만약 에러가 발생할 경우 ‘javac -cp “.” Program.java’ 명령어를 입력해 보고 그것마저도 되지 않는다면 구경 모드로 전환하면 됩니다.
이제 앞에서 생성한 클래스 파일을 실행해 보겠습니다. 클래스 파일을 실행할 때는 java 프로그램을 사용합니다. 터미널에서 java를 입력하고 엔터를 치면 java 프로그램의 실행 방법이 나옵니다. java 프로그램을 가리켜 가상 머신(Virtual Machine)이라고 하며, 아주 많은 일을 하는 프로그램입니다. 자바에게 클래스 파일을 실행하라고 명령을 내릴 때는 java를 입력하고 한 칸 띄운 다음, 크랠스 파일에서 확장자인 .class를 제거한 파일명만 입력합니다. java Program 이렇게 말이죠. java Program이라는 명령을 입력하면 java 프로그램이 현재 디렉터리에서 Program.class 파일이 있는지 찾아보고, 만약 있다면 Program.class 파일을 실행하게 됩니다. 만약 이 부분에서 문제가 생기면 ‘java -cp “.” Program’을 실행해 봅니다. ‘java -cp “.” Program’ 명령에서 cp는 class path의 약자이며 점(.)은 현재 디렉터리를 의미합니다.
이번에는 cat 명령어로 프로그램의 내용을 확인해 보겠습니다. 윈도우에서는 cat 명령어 대신 type 명령어를 사용할 수 있습니다. 보다시피 Program이라는 클래스가 있고 그 안에 main 멘서드가 있습니다. java에게 Program.class 파일을 실행하라는 명령을 내리면 Program.class 파일에서 앞에서 지정한 클래스 파일의 이름(Program)과 같은 클래스를 찾고, 클래스 내부에서 main 메서드를 찾은 후 main 메서드 안의 코드를 순차적으로 실행하고 종료합니다. 이러한 과정은 미리 약속돼 있고 그 약속에 따라 main이라는 메서드를 만들고 Program이라는 클래스를 만들어서 이 클래스의 이름과 똑같지만 확장자가 .java인 파일을 만들면 이를 컴파일하고 실행해 원하는 프로그램이 만들어지게 됩니다. 그럼 이번 수업은 여기까지 하겠습니다.
직접 컴파일하고 실행하기 : 라이브러리 이용
이번 수업에서는 조금 더 복잡한 얘기를 해볼 겁니다. 순수하게 내가 만든 프로그램만 컴파일하고 실행할 때는 지금까지 한 것처럼 하면 되지만 내가 만든 프로그램에서 다른 사람이 만든 것을 이용하고 있다면 조금 더 복잡해집니다. 먼저 OkJavaGoInHome.java 파일을 열어보겠습니다.
OkJavaGOInHome.java 코드를 보면 Elevator myElevator = new Elevator(id);에서 사용하는 Elevator 클래스는 현재 OkJavaGoInHome.java 파일 내부에 없습니다. Elevator 클래스의 코드는 첫 번째 줄의 import org.opentutorials.iot.Elevator;를 통해 불러옵니다. 즉, org 밑의 opentutorials 밑의 iot 밑에 있는 Elevator라는 것을 import를 통해 불러온 상태입니다. 보다시피 현재 디렉터리의 org 폴더 밑의 opentutorials 폴더 밑의 iot 폴더에 Elevator.java 파일이 위차한 것을 확인할 수 있습니다. 코드 안에서 사용하는 Elevator는 이러한 iot 폴더에 있는 ELevator.java 파일을 가리킵니다. 참고로 org부터 iot 만큼을 패키지(package)라고 하며, 작은 프로그램들이 모여있는 것을 의미합니다. Elevator.java 파일을 컴파일하면 Elevator.class 파일이 생기고 Elevator.class 파일을 로딩하는 코드가 바로 import org.opentutorials.iot.Elevator;입니다. 즉, import를 통해 Elevator.class 파일을 이용할 수 있게 되는 겁니다.
‘javac OkJavaGoInHome.java’ 명령어를 사용해 소스코드를 컴파일하면 OkJavaGoInHome.class 파일이 생성됩니다. 실행 파일이 생성된 것입니다. 그런데 OkJavaGoInHome.java의 소스코드는 내부적으로 패키지 안에 있는 여러 파일들을 모두 필요로 하기 때문에 자바 컴파일러가 패키지 안에 있는 파일들도 컴파일했습니다. 그래야 사용할 수 있기 때문입니다.
이번에는 OkjavaGoInHome.java 소스 파일과 같은 디렉터리에 org 폴더가 있지 않은 상황을 만들어 보겠습니다. 이름은 상관없지만 lib라는 이름의 폴더를 생성하고, org 패키지 디렉터리를 lib 폴더로 옮기겠습니다. 그리고 이전과 동일하게 ‘javac OkJavaGoInHome.java’ 명령어를 사용해 컴파일해 보겠습니다. 그런데 보다시피 무수한 에러가 화면에 출력됩니다. 에러를 확인해 보면 org.opentutirlas.iot 패키지가 존재하지 않는다는 내용입니다. 왜냐하면 이번에 컴파일한 OkJavaGoInHome.java 파일과 같은 디렉터리에 있지 않기 때문입니다. 터미널에서 javac명령어를 입력하고 엔터를 치면 javac 프로그램의 사용법이 나오는데, 이 가운데 다음과 같은 옵션 정보를 확인할 수 있습니다.
javac 명령어의 -classpath 옵션을 사용하면 패키지 경로를 확인할 수 없는 문제를 해결할 수 있습니다. -classpath 옵션은 컴파일하려고 하는 클래스들이 어디에 있는가를 javac 프로그램에게 알려주는 역할을 합니다. 즉, OkJavaGoInHome.java 소스코드를 사용하기 위해서는 -classpath 옵션을 이용해 lib 폴더의 org 밑에 있는 패키지의 위치를 알려줄 필요가 있습니다. -classpath 옵션의 사용법은 다음과 같습니다. 윈도우에서는 ‘javac -classpath “.:lib” OkJavaGoInHome.java’, 리눅스에서는 ‘java -classpath “.lib” OkJavaGoInHome.java’ 명령으로 컴파일합니다. 그럼 자바 컴파일러가 -classpath 뒤에 적힌 경로에서 필요한 클래스 파일들을 차장보고 컴파일하면서 필요로 하는 클래스 파일까지 자동으로 컴파일하게 됩니다. 즉, 다음과 같은 명령을 하게 되면 패키지 경로를 지정해서 자바 파일을 컴파일할 수 있습니다. javac -cp “.:lib” OkJavaGoInHome.java 이렇게 말이죠. (윈도우에서는 : 대신 ;)
이것을 이해하기 위해 순차적으로 명령들을 실행해 나가보겠습니다. java OkJavaGoInHome 이라는 명령을 실행하면 위와 같은 에러 메시지가 나오게 됩니다. 여기서 Exception이라는 것은 자바에서 에러를 나타내는 표현이라고 생각하면 됩니다. 에러의 내용을 보면 Elevator 클래스를 찾지 못해 예외(Exception)가 발생한 것을 알 수 있습니다. 만약 같은 경로에 org 폴더가 있었다면 에러 없이 살행될 것입니다. 하지만 현재 자바 프로그램은 lib 폴더의 존재를 알지 못하기 때문에 클래스 파일을 찾을 수 없게 되는 것입니다. 따라서 실행할 클래스 파일의 위치를 명시적으로 알려줘야 합니다.
그런데 다음과 같이 ‘java -cp “lib” OkJavaGoInHome’ 명령을 실행하면 이번에는 main 클래스를 찾을 수 없다는 에러가 발생합니다. 자바 프로그램을 실행하면 기본적으로 현재 디렉터리에 있는 OkJavaGoInHome 클래스 파일을 찾도록 약속돼 있는데 명시적으로 lib 폴더를 지정하면 lib 폴더 하위에서만 해당 파일을 찾게 되고 현재 디렉터리에서는 찾지 않게 됩니다. 따라서 현재 디렉터리도 확인하라는 의미에서 lib 폴더 앞에 현재 디렉터리를 나타내는 점(.)을 추가해야 합니다. 즉, ‘java -cp “.:lib” OkJavaGoInHome’ 명령을 사용하면 됩니다. 윈도우에서는 콜론 대신 세미콜론을 사용해 ‘java -cp “.;lib” OkJavaGoInHome’ 명령을 사용하면 됩니다.
그럼 보다시피 현재 디렉터리에서 OkJavaGoInHome 클래스 파일을 열어서 main 메서드를 실행하다가 Elevator 코드가 있으면 lib 폴더의 org 밑에 있는 클래스 파일을 읽어서 실행하게 됩니다.이렇게 해서 지금까지 프로그램을 전부 혼자 만드는 것이 아니라 다른 사람 또는 이전에 만들어둔 프로그램을 부품으로 사용해서 만든 프로그램을 컴파일하고 실행하는 방법을 살펴봤습니다. 다른 사람들이 사용할 수 있도록 잘 정리정돈된 프로그램들을 도서관이라는 뜻에서 라이브러리(library)라고 합니다. 소프트웨어는 혼자서 모두 다 개발하지 않습니다. 다른 사람들이 만든 라이브러리를 이용해 나의 소프트웨어를 만들어 가는 것이기 떄문에 이 세상에 어떤 라이브러리가 있는지 살펴보는 것은 우리의 인생에서 견문을 넓히는 것만큼이나 중요한 일입니다.
직접 컴파일하고 실행하기 : 입력과 출력
이번 수업에서는 직접 자바 소스코드를 컴파일하고 실행할 때 입력 값을 전달해서 그 값에 따라 그 값에 따라 다르게 동작하는 프로그램을 실행하는 방법을 살펴보겠습니다. javac OkJavaGoInHomeInput.java 명령으로 소스코드를 컴파일하면 OkJavaGoInHome.java 파일도 함께 컴파일되면서OkJavaGoInHomeInput.class 파일이 만들어지고 이 클래스 파일이 사용하고 있는 다른 클래스(Elevator, Lighting, Security 등)들도 컴파일되면서 클래스 파일이 만들어집니다. 이제 java OkGoInHomeInput 명령으로 프로그램을 실행해 보겠습니다.
그럼 위와 같이 에러가 발생하고 에러 메시지를 통해 12번째 줄에서 에러가 발생했음을 볼 수 있습니다. 즉, 12번째 줄인 String id = args[0];에서 args 때문에 발생한 에러입니다. args란 프로그램을 실행할 때 입력값을 받는 역할로 사용하는 것이 ‘args’입니다. args는 main 메서드 소괄호 안에서 인자로 사용하는 변수명과 같아야 합니다. 프로그램에 전달되는 입력값은 args 변수의 대괄호 안에 0부터 시작하는 정수를 지정해 가져올 수 있습니다. 첫 번째 값은 0을 지정해, 두 번째 값은 0에서 1만큼 증가한 1을 지정해 가져올 수 있습니다. 컴퓨터에서는 숫자를 0부터 세는 관습이 있기 떄문에 0번째, 1번째, … n번째 같은 식으로 숫자를 셉니다. 그럼 어떻게 하면 ‘args’에 값을 넣을 수 있는지 설명하겠습니다. java OkJavaGoInHomeInput 명령어 뒤에 따옴표로 문자열을 묶어서 입력값을 넣고 각 입력값 사이는 띄어쓰기로 구분하면 됩니다. 예를 들어, JAVA APT 507호를 첫 번째 입력값으로 넣고 싶다면 “JAVA APT 507”과 같이 문자열을 따옴표로 묶어 명령어 뒤에 다음과 같이 입력하면 args[0] 안에 “JAVA APT 507”이라는 문자열이 들어갑니다. 즉, java OkJavaGoInHomeInput “JAVA APT 507” 이라고 입력값을 전달하면 됩니다. 입력 값을 여러 개 전달하고 싶다면 띄어쓰기로 각각을 구분해서 입력하면 됩니다. 즉, java OkJavaGoInHomeInput “JAVA APT 507” 15.0 과 같이 말이죠. 그럼 JAVA APT 507은 args[0]으로 들어가고 15.0은 args[1]에 들어가게 됩니다.
보다시피 JAVA APT 507이 id 값이 되고 15.0이 bright에 들어가면서 불의 밝기가 15%만큼 밝아지게 됩니다. 이전 수업에서는 이클립에서 프로그램을 실행할 때, 입력값(argument)를 전달하는 방법을 살펴봤습니다. 이클립스에서는 입력값을 전달할 때마다 뭔가 귀찮은 작업들을 해야 했습니다. 그런데 커맨드라인에서 프로그램을 실행할 때 프로그램 실행 명령 뒤에 값을 추가하는 방법으로 프로그램이 원하는대로 동작하게 할 수 있다면 훨씬 더 간편하게 작동하는 아주 편리한 프로그램을 만들 수 있습니다. 명령어 뒤에 입력값을 추가하는 것은 화려한 것도 아니고 우리가 지금까지 사용해온 각종 프로그램과 생긴 것은 많이 다르지만 충분히 가치 있는 일이고 이를 통해 엄청나게 많은 일을 할 수 있다는 것도 기억하면 좋겠습니다. 그럼 이번 수업은 여기까지 하겠습니다
참고자료 및 원본 : 오픈튜토리얼스 생활코딩 (이고잉 님)
- 생활코딩 JAVA 입문 수업 : https://opentutorials.org/course/3930
'[생활코딩] Server > JAVA1(기초)' 카테고리의 다른 글
생활코딩 JAVA 1_지식이란, 지식의 지도 (0) | 2023.05.01 |
---|---|
생활코딩 JAVA 1_자바 문서 보는 법 : {API vs. UI, 패키지, 클래스, 변수, 메서드, 인스턴스, 상속} (0) | 2023.05.01 |
생활코딩 JAVA 1_입력과 출력 (arguments & parameter) (0) | 2023.04.28 |
생활코딩 JAVA 1_디버거 (1) | 2023.04.28 |
생활코딩 JAVA 1_IoT 프로그램 만들기 (0) | 2023.04.28 |