본문 바로가기

Learning

JAVA 9 모듈방식(modularity) 코딩 힐끗보기

JAVA 9가 점점 우리에게 다가오는 것이 느껴진다. 소개된 새로운 특징들을 보니, 모듈방식 코딩 지원과 'jshell'이 눈에 띈다.


모듈방식 (Modularity)

모듈에 대한 구체적인 지원을 담는 내용이 포함된 이유는 무엇일까? 모듈 혹은 서비스 그리고 이전에는 객체 중심의 개발이 설계 및 유지보수등에 주는 이점에 대한 얘기는 너무도 당연하게 여겨지는데, JAVA 9 에서는 이를 언어스펙으로 넣어 버렸다. 그래서 코딩단계부터 컴파일 심지어는 새로이 도입된 링크에 모듈 기능이 추가 되었고, 20년 이상 유지해온 기존의(레거시) 라이브러리들 또한 재설계를 했다.

모든 개발자들의 마음이 같지 않다.

보통 인터페이스 와 이를 구현한 객체, 부모 객체와 자식 객체가 있다면 데이터 형을 선언할 때  가능한 상위 객체를 사용하는게 좋다. 개인적으로 외부업체 혹은 레거시 시스템의  라이브러리등을 사용할 때 흔히 보는 혼선이 'List' 혹은 'Map'의 형선언이다. 이 때 가능한 'List' 심지어는 'Collection' 등을 사용하면 유지보수시 유용한 경우가 많다. 그런데 여러 개발자들이 'LinkedList', 'HashMap'처럼 구현된 객체를 형으로 선언하는듯 하다. 'Map'도 마찬가지이다. 만약 여러 쓰레드에서 처리되서 생기는 충돌을 막기 위해 'java.util.concurrent' 패키지등의 객체를 쓰게 되었다면, 제약이 되거나, 많은 곳을 고쳐야 되는 경우가 많다. 그러나 이럴 때도 많은 개발자들은 말한다 "그럴 일은 없습니다."

하여튼, 자바 설계자들은 이것을 근본적으로 막고 싶어한 듯 하다. 많은 개발자들이 함수의 반환 형 혹은 매개변수 형으로 LinkedList, HashMap등을 쓰는 것은 그 것이 자신의 namespace에서 보이고 사용할 수 있기 때문이다. JAVA9의 모듈 기능을 쓰면 필요한 것만 밖에서 참조할 수 있게 설정할 수 있다. 따라서 아예 보이지 않으면 못 쓰게 되니, 앞서의 혼선을 막을 수 있다고 보는 듯 하다.
하지만  현실에서는 수많은 예외적인 상항에 따른 만만치 않은 반론이 존재한다. 만약 본인이 'LinkList'로 쓸지 'ArrayList'로 쓸지를 결정하지 못하다면 이 또한 답답한 상황이 될 때가 많다.

배포관리 시스템 & JRE vs Human Developer

점점 더 시스템이 커지면서 개발 비용보다는 관리 비용이 더 많이 드는 경우가 많다. 이 경우에 기존의 자바의 경우 어려운 것은 배포시 빠진 jar파일이 있는지 시스템에 의해 확인하는 것이다.  개발자들이 조금 불편하겠지만 의존성을 명시한다면 maven등의 도움 없이도 배포시 jar파일 의존성 검사를 완전 자동화 할 수 있다.
또한 JAVA Runtime 관련 프로그램도 부담을 덜게 되는데, 예를들면 어떤 패키지가 여러 jar파일에 걸쳐 중복되어 있을 때, 기존의 JRE는 이들을 모두 적재했는데, 이제는 이 것을 거를 수 있게 된다. 아주 좋은 기능이라고 본다. 그런데 심정적으로 왠지 회의장에서 하니마니 논쟁하다가 기계들에게 진 느낌이다.

How to

  • 코딩 : 모듈 디렉토리 와 module-info.java
  • 컴파일 : 모듈 컴파일, 컴파일된 모듈 포함시키기
  • 실행 : 의존된 모듈 포함시키기

코딩

아래는 데모용으로 작업한 곳의 파일 및 디렉토리 트리구조이다.

jaeda@JLINUX:~/study/java9/test.module$ tree
.
├── TestModule.class
├── TestModule.java
├── mymodule
│   └── guru.zcube.mymodule
│       ├── guru
│       │   └── zcube
│       │       └── mymodule
│       │           ├── Gentleman.java
│       │           └── HelloUtil.java
│       └── module-info.java
└── out
    └── guru.zcube.mymodule
        ├── guru
        │   └── zcube
        │       └── mymodule
        │           ├── Gentleman.class
        │           └── HelloUtil.class
        └── module-info.class

10 directories, 8 files

이 구조는 절대적인 것이 아니다. 각각의 개발 환경에 따라 달라 질 수 있다. 주목할 것은 빨간 배경색의 모듈이 구성된 모습이다. 모듈디렉토리 와 module-info.java파일이 있으면 된다.
  • 모듈디렉토리 : 'guru.zcue.mymodule' 디렉토리
  • 그 아래에 'module-info.java'

디렉토리 이름은 데모처럼 패키지명의 합으로 안해도 된다. 다만 module-info.java 안에 설정된 모듈이름과 같으면 된다.


module-info.java (밑줄 그어진 부분이 모듈 디렉토리명과 같으면 된다.)
module guru.zcube.mymodule 
{
exports guru.zcube.mymodule;
}

컴파일-모듈

javac -d out --module-source-path mymodule -m guru.zcube.mymodule

  • -d : 컴파일된 결과가 출력될 곳
  • --module-source-path : 모듈디렉토리(들)이 있는 위치(디렉토리)
  • -m : 컴파일할 디렉토리

컴파일-모듈이 아닐 때

javac --module-path out --add-modules guru.zcube.mymodule TestModule.java

'TestModule.java'는 테스트용 코드이다.
  • --module-path : 컴파일된 모듈이 있는 위치(디렉토리)
  • --add-modules : 모듈일 경우 'module-info.java'에 참조할 모듈을 명시한다. 그러나 모듈이 아닐 때는 이 옶션에서 명시한다.

실행

java --module-path out --add-modules guru.zcube.mymodule TestModule
  • --module-path  : 컴파일된 모듈이 있는 위치(디렉토리)
  • --add-modules : 모듈을 실행한다면 이 옵션은 필요하지 않을 수도 있다. 그러나 실행하는 클래스가 모둘이 아니므로...

마치며

지금은 많은 좋은 개발 툴 및 환경이 갖추어졌기 때문에 위의 명령어의 옵션을 다 알 필요는 없다고 본다. 그러나 앞으로는 모듈방식 코딩이 권장사항이 아니라 의무사항이 될 수도 있겠다. OSGi의 극악함으로 인해 다만 바라는 것이 있다면 의존성등 오류에 대한 메시지가 직관적이기만을 바랄 뿐이다. 


시간이 되면 몇가지 실무적인 궁금한 점에 대해서도 써보고 싶다. 위의 데모와 관련된 소스를 파일로 공유하니 필요하다면 작은 도움이 되었으면 한다.



'Learning' 카테고리의 다른 글

JAVA9 jshell(REPL)  (0) 2018.01.29
My-SQL 8 RC2 흘끗보기 - JSON  (0) 2017.11.11
프로그램언어 GO 흘끗 보기  (0) 2017.10.23
자바스크립트 프레임웤 vue.js 흘끗보기  (0) 2017.09.30
JAVA 람다함수 총정리  (0) 2017.08.01