DrMaemi / blog

1 stars 0 forks source link

[Java] classpath, package, import, compile, execute #136

Open DrMaemi opened 1 year ago

DrMaemi commented 1 year ago

java package, import, compile, execute

초기 디렉토리 구조

.
├── Main.java
└── com
    └── naver
        └── Math.java
Main.java ```java import com.naver.Math; public class Main { public static void main(String[] args) { System.out.println("Hello world"); Math math = new Math(); int a = 1; int b = 3; System.out.printf("1 + 3 = %d\n", math.sum(a, b)); System.out.println("Program terminated successfully"); } } ```
Math.java ```java package com.naver; public class Math { public int sum(int a, int b) { return a + b; } } ```

컴파일

$ mkdir out
$ javac -d ./out Main.java

결과

.
├── Main.java
├── com
│   └── naver
│       └── Math.java
└── out
    ├── Main.class
    └── com
        └── naver
            └── Math.class

실행

java -cp ./out Main

패키지 이동

.
├── com
│   └── naver
│       ├── etc
│       │   └── Math.java
│       └── main
│           └── Main.java
└── out

컴파일(Main.java는 package 문이 작성되지 않았음)

javac -d ./out com/naver/main/Main.java
.
├── com
│   └── naver
│       ├── etc
│       │   └── Math.java
│       └── main
│           └── Main.java
└── out
    ├── Main.class
    └── com
        └── naver
            └── etc
                └── Math.class

Main.java에 package 경로 추가 후 다시 컴파일

.
├── com
│   └── naver
│       ├── etc
│       │   └── Math.java
│       └── main
│           └── Main.java
└── out
    └── com
        └── naver
            ├── etc
            │   └── Math.class
            └── main
                └── Main.class

실행

java -cp ./out com.naver.main.Main

jar

기능 명령어
jar 생성 jar cf [jar-file] [input-file(s)]
jar 파일 내용 보기 jar tf [jar-file]
jar 파일 extract jar xf [jar-file]
jar 파일 내 특정 파일들만 extract jar xf [jar-file] [archived-file(s)]
java application 실행 java -jar app.jar

jar 하나로 묶기

초기 디렉토리 상태(컴파일 이후)

.
├── MANIFEST.MF
├── com
│   └── naver
│       ├── etc
│       │   └── Math.java
│       └── main
│           └── Main.java
└── out
    └── com
        └── naver
            ├── etc
            │   └── Math.class
            └── main
                └── Main.class

MANIFEST.MF

Manifest-Version: 1.0
Created-By: 1.8.0_362 (Amazon.com Inc.)
Main-Class: com.naver.main.Main
jar cvmf MANIFEST.MF example.jar -C out .

jar 실행

$ java -jar example.jar
Hello world
1 + 3 = 4
Program terminated successfully

classpath 추가해 jar 내 main 클래스 실행

jars 디렉토리를 만든 후 example.jar를 옮기면

java -jar ./jars/example.jar

또는

java -cp "./jars/*" com.naver.main.Main

과 같이 main 클래스를 가진 jar 경로를 classpath로 추가해 실행할 수 있다.

소스코드를 외부 라이브러리로 만들어 실행

먼저 sh.lee.Math 클래스를 별도 jar로 만들고 소스코드와 .class 파일을 지운다.

javac -d out sh/lee/Math.java
jar cvf sh-lee-lib.jar -C out .
mkdir libs && mv sh-lee-lib.jar libs
rm -r out && rm -r sh
.
├── MANIFEST.MF
├── com
│   └── naver
│       └── main
│           └── Main.java
└── libs
    └── sh-lee-lib.jar

이후 메인 클래스를 ./libs/*를 classpath에 넣지 않고 컴파일하면 라이브러리를 찾지 못하는 오류가 발생한다.

$ javac -d out com/naver/main/Main.java
com/naver/main/Main.java:3: error: package sh.lee does not exist
import sh.lee.Math;
             ^
...
$ javac -cp "./libs/*" -d out com/naver/main/Main.java

결과
.
├── MANIFEST.MF
├── com
│   └── naver
│       └── main
│           └── Main.java
├── libs
│   └── sh-lee-lib.jar
└── out
    └── com
        └── naver
            └── main
                └── Main.class

실행할 땐 out, libs 모두 classpath에 등록해야 한다.

$ java -cp "./out:./libs/*" com.naver.main.Main
Hello world
1 + 3 = 4
Program terminated successfully

A. 참조