[Java] 10. 라이브러리와 모듈

JK·2024년 4월 17일
0

[Java]

목록 보기
10/11

라이브러리

라이브러리(library)는 프로그램 개발 시 활용할 수 있는 클래스와 인터페이스들을 모아놓은 것이다. 일반적으로 JAR(Java ARchive) 압축 파일(.jar) 형태로 존재한다. JAR 파일에는 클래스와 인터페이스의 바이트코드 파일(.class)들이 압축되어 있다.

특정 클래스와 인터페이스가 여러 응용 프로그램을 개발할 때 공통으로 자주 쓰인다면 JAR 파일로 압축해서 라이브러리로 관리하는 것이 좋다. 프로그램 개발 시 라이브러리를 이용하려면 라이브러리 JAR 파일을 ClassPath에 추가해야 한다.

ClassPath란 말 그대로 클래스를 찾기 위한 경로를 말한다. ClassPath에 라이브러리를 추가하는 방법은 java 명령어를 실행할 때 -classpath 명령어로 제공하는 방법이 있고, CLASSPATH 환경 변수에 경로를 추가하는 방법이 있다.

모듈

모듈(Module)은 자바 9 버전 부터 지원되는 기능으로, 패키지 관리 기능까지 포함된 라이브러리를 말한다. 일반 라이브러리는 내부에 포함된 모든 패키지에 외부 프로그램에서의 접근이 가능하다. 하지만 모듈은 일부 패키지를 은닉하여 접근할 수 없게 만들 수 있다.

또한 모듈은 자신이 실행할 때 필요로 하는 의존 모듈을 모듈 기술자(module-info.java)에 기술하여 모듈 간의 의존 관계를 쉽게 파악할 수 있다. 모듈도 라이브러리이므로 JAR 파일 형태로 배포된다.

대규모 응용 프로그램은 기능별로 모듈화해서 개발하는 것이 더 유리하다. 모듈별로 개발하고 조립하는 방식을 사용하면 재사용성을 높이고 유지보수를 효율적으로 할 수 있기 때문이다.

응용 프로그램 모듈화

응용 프로그램은 규모가 커질수록 협업과 유지보수 측면에서 서브 모듈로 쪼개서 개발하는 것이 유리하다. 이렇게 개발된 서브 모듈을 다른 응용 프로그램에서도 재사용할 수 있다.

일반적으로 모듈 기술자(module-info.java)가 포함된 프로젝트를 모듈이라고 한다. 다른 모듈들을 조합해서 사용하기만 하는 응용 프로그램도 어떤 모듈을 가져와 사용할 것인지를 기술하기 위해 모듈 기술자가 필요하고, 모듈 기술자가 포함되어 있기 때문에 모듈이라고 할 수 있다.

패키지 은닉

모듈은 모듈 기술자에서 exports 키워드를 사용해 내부 패키지 중 외부에서 사용할 패키지를 지정한다. exports 키워드로 지정되지 않은 패키지는 자동적으로 은닉된다.

모듈이 패키지를 은닉하는 이유는 첫째로 모듈 사용 방법을 통일하기 위해서이다. 다른 패키지를 은닉해서 사용하지 못하게 하고 특정 하나의 패키지만을 사용할 수 있게 하면 사용 방법을 통일할 수 있다. 둘째로 수정이 쉽기 때문이다. 은닉된 다른 패키지를 수정하더라도 공개된 패키지가 달라지지 않으면 외부에 영향을 주지 않는다.

전이 의존

module my_application {
  requires my_module_a;
}
module my_module_a {
  exports pack1;
  requires my_module_b;
}

모듈 기술자가 위와 같이 작성되어 있다면 my_application은 my_module_a에 의존하고 my_module_a는 my_module_b에 의존한다. 따라서 my_application은 my_module_a를 사용할 수 있고, my_module_a는 my_module_b를 사용할 수 있지만 my_application은 my_module_b를 사용할 수 없다.

module my_module_a {
  exports pack1;
  requires transitive my_module_b;
}

이 상태에서 위와 같이 my_module_a에서 transitive 키워드로 my_module_b를 설정하면 의존 설정이 전이되어 my_module_b를 my_application에서 사용할 수 있게 된다. my_module_a에서도 역시 여전히 my_module_b를 사용할 수 있다.

집합 모듈

집합 모듈은 여러 모듈을 모아놓은 모듈을 말한다. 자주 사용되는 모듈을 일일이 requires 하는 번거로움을 피하기 위해 사용한다.

자체적인 패키지를 가지지 않고, 모듈 기술자에게 전이 의존 설정만 한다.

리플렉션 허용

은닉된 패키지는 기본적으로 다른 모듈에 의해 리플렉션을 허용하지 않는다. 여기서 리플렉션(reflection)은 실행 도중에 타입(클래스, 인터페이스 등)을 검사하고 구성 멤버를 조사하는 것이다.

필요한 경우 아래와 같이 은닉된 패키지도 리플렉션을 허용할 수 있다.

  1. 모듈 전체를 리플렉션 허용
open module 모듈명 {
  ...
}
  1. 지정된 패키지에 대해 리플렉션 허용
module 모듈명 {
  ...
  opens 패키지1;
  opens 패키지2;
}
  1. 지정된 패키지에 대해 특정 외부 모듈에서만 리플렉션 허용
module 모듈명 {
  ...
  opens 패키지1 to 외부모듈명, 외부모듈명, ...;
  opens 패키지2 to 외부모듈명;
}

자바 표준 모듈

JDK는 자바 프로그램에서 활용할 수 있는 표준 라이브러리를 제공한다. 자바 표준 라이브러리는 Java 9부터 모듈화되었다.

모듈 간의 의존 관계를 표시한 Java 17 전체 표준 모듈 그래프

java.base는 모든 모듈이 의존하는 기본 모듈이다. 그래서 requires 하지 않아도 사용할 수 있지만, 다른 모듈들은 모듈 기술자에 requires를 명시하고 사용해야 한다.

java.se는 JDK가 제공하는 모든 모듈을 제공하는 집합 모듈로, 자바 표준 라이브러리가 모듈화되기 전인 Java 8 이전 버전과 같이 자바 표준 라이브러리를 제한 없이 사용하고 싶을 경우 requires 해서 사용할 수 있다.

마찬가지로 자바 표준 라이브러리를 제한 없이 사용하고 싶을 경우, 모듈 기술자가 없는 프로젝트를 만들면 모듈로 인식되지 않기 때문에 자바 표준 라이브러리를 제한없이 사용할 수 있다.

표준 라이브러리를 모듈화한 이유는 응용 프로그램을 실행하는데 필요한 모듈로 구성된 작은 사이즈의 자바 실행 환경(JRE)를 만들기 위해서이다. 작은 사이즈의 자바 실행 환경이 필요한 경우는 크게 두 가지로 볼 수 있다.

하나는 응용 프로그램과 표준 라이브러리를 가진 독립 실행형으로 배포하는 경우이다. 이 경우에는 표준 라이브러리가 작을 수록 배포 사이즈가 줄어든다. 다른 하나는 제한된 자원만 가지고 있는 소형(임베디드) 기기에 사용하는 경우이다. 이 경우 사이즈가 작은 자바 실행 환경이 필요하다.


"한빛 미디어 출판 도서, 이것이 자바다"를 읽고 학습한 내용을 토대로 작성되었습니다.

0개의 댓글