Dev

IntelliJ 의 JShell Console 을 활용하자

prostars 2018. 4. 30. 21:41
최근에 Java 를 실무에 사용하면서 JShell 이 있어서 참 다행이라고 생각하고 있다. IntelliJ 가 JShell Console 이라는 기능으로 툴 안에서 JShell 을 연동해주고 있어서 더 편리하게 사용하고 있는데 이번 글에서는 JShell 에 대한 간단한 소개와 유용함을 알아보자. 이 글은 macOS 를 기준으로 하며 다음의 내용을 다룬다.

  1. JShell 에 대한 간단한 소개
  2. Java 8, 9, 10 를 손쉽게 전환하면서 사용하는 방법
  3. IntelliJ 의 JShell Console 사용하기
  4. IntelliJ 의 JShell Console 에서 사용자 클래스 사용하기 

JShell 에 대한 간단한 소개

JShell 은 node.js 의 shell 이나 scala 의 shell 처럼 코드를 바로바로 실행하고 결과를 확인할 수 있는 REPL(Read-Evaluate-Print Loop) 이다. 그냥 터미널 하나 열어서 기본 shell 만 사용해도 간단한 로직을 코딩하고 바로 실행해서 확인할 수 있어서 상당히 유용하다. JShell 은 Java 9 버전부터  추가되었다. 다음은 JShell 의 간단한 사용 예제이다.
$ jshell
|  Welcome to JShell -- Version 9.0.4
|  For an introduction type: /help intro

jshell> List<Integer> numbers = new ArrayList<>()
numbers ==> []

jshell> numbers.add(10)
$2 ==> true

jshell> numbers.add(20)
$3 ==> true

jshell> numbers.add(30)
$4 ==> true

jshell> numbers.stream().map(a -> a / 2).collect(Collectors.toList())
$5 ==> [5, 10, 15]
약간의 설정으로 사용자 클래스를 임포트해서 테스트를 할 수도 있다. JShell 의 세부 기능은 다른 문서를 참고 바란다. 하지만 아직은 Java 8 이하로 실무를 진행하는 상황이 많으니 JShell 을 사용하자고 Java 9 이상을 설치해서 기본으로 설정하기는 부담스럽다. Java 8, 9 이상을 모두 설치해두고 전환하면서 사용하는 방법을 알아보자.

Java 8, 9, 10 을 손쉽게 전환하면서 사용하는 방법

/usr/libexec/java_home 를 사용하면 현재 설정된 java home 경로를 구할 수 있다. java_home 유틸리티의 도움말을 살펴보자.
$ /usr/libexec/java_home -h
Usage: java_home [options...]
    Returns the path to a Java home directory from the current user's settings.

Options:
    [-v/--version   <version>]       Filter Java versions in the "JVMVersion" form 1.X(+ or *).
이하 생략

-v 옵션을 사용하면 해당 버전의 java home 경로를 구할 수 있다. jdk 8, 9, 10 모두 설치된 상태에서 다음과 같이 버전 별로 실행해 보자.
$ /usr/libexec/java_home -v 1.8
/Library/Java/JavaVirtualMachines/jdk1.8.0_162.jdk/Contents/Home

$ /usr/libexec/java_home -v 9
/Library/Java/JavaVirtualMachines/jdk-9.0.4.jdk/Contents/Home

$ /usr/libexec/java_home -v 10
/Library/Java/JavaVirtualMachines/jdk-10.0.1.jdk/Contents/Home

이제 java 8, 9, 10 의 java home path 를 구할 방법을 확보했으니 다음과 같이 환경 변수를 설정하자. macOS 의 기본 shell 인 bash 기준으로 user home directory 에 있는 .bash_profile 파일에 아래의 내용을 추가하면 된다.
alias setJdk8='export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)'
alias setJdk9='export JAVA_HOME=$(/usr/libexec/java_home -v 9)'
alias setJdk10='export JAVA_HOME=$(/usr/libexec/java_home -v 10)’

파일에 위 내용을 추가하고 저장했다면 현재 shell 에 내용을 적용하자.
$ source ~/.bash_profile

그리고 테스트해보자. java 8, 9, 10 순서로 설치했다면 현재 설정은 java 10 으로 되어 있을 것이다.
$ java -version
java version "10.0.1" 2018-04-17
Java(TM) SE Runtime Environment 18.3 (build 10.0.1+10)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10.0.1+10, mixed mode)

위에서 추가한 alias 를 사용해서 java 8 로 변경한다.
$ setJdk8
$ java -version
java version "1.8.0_162"
Java(TM) SE Runtime Environment (build 1.8.0_162-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, mixed mode)

$ setJdk9
$ java -version
java version "9.0.4"
Java(TM) SE Runtime Environment (build 9.0.4+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, mixed mode)

$ setJdk10
$ java -version
java version "10.0.1" 2018-04-17
Java(TM) SE Runtime Environment 18.3 (build 10.0.1+10)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10.0.1+10, mixed mode)

제대로 동작하는 것을 확인했다.

IntelliJ 의 JShell Console 사용하기

우선 설치된 IntelliJ 의 버전을 확인하자. JShell 지원은 IntelliJ IDEA 2017.3 이상부터 된다. 지원 버전이라면 Tools 메뉴에 JShell Console 이 있을 것이다. 선택해서 실행해보자.

아래와 같은 에러가 발생할 수도 있다.

아래와 같은 상태에서 JRE: 1.8 을 9.0 으로 변경하면 해결된다.

처음에 터미널에서 JShell 을 소개할 때 사용했던 코드를 Intelli 의 JShell Conole 에서 사용하면 다음과 같은 결과를 볼 수 있다.

아쉽지만 위에 보이는 것처럼 Java Generic 을 JShell Console 에서 사용하면 IntelliJ 가 문법 체크에서 오류를 표시하기 때문에 IntelliSense 가 제대로 동작하지 않는다.

Updated
generic 변수를 final로 정의하면 오류 표시는 사라지고, IntelliSense를 사용할 수 있다.

스크린샷 왼쪽 위의 플레이 버튼을 클릭하거나 Command key + enter 단축키로 코드를 실행할 수 있다. 코드를 실행하면 다음과 같은 결과가 출력된다.

비록 에디터 창에는 문법 오류로 빨간 줄이 표시되지만 실행해보면 코드는 정상적으로 실행되는 것을 확인할 수 있다. 간단한 인터페이스 하나와 클래스 두 개를 구현해서 사용해보자. JShell 을 사용하면 하나의 에디터 창에서 모두 코딩하고 테스트해볼 수 있다.

이번에는 아무런 문법 에러도 표시되지 않고 IntelliSence 도 정상 동작하며 IntelliJ 의 Override 지원 기능(control + O) 도 정상 동작한다. 실행하면 다음과 같은 결과를 볼 수 있다.

IntelliJ 의 JShell Console 에서 사용자 클래스 사용하기 

자 이제 목적지가 보인다. 이미 구현된 클래스를 JShell Console 에서 바로바로 실행하면서 테스트해보자. 위에서 사용한 코드를 각각의 파일로 생성하자. interface Log 는 Log.java, class FileLog 는 FileLog.java, class DBLog 는 DBLog.java 로 각각 생성한다.

아래와 같이 JShell Console 에서 FileLog 를 사용해보자.


아래와 같이 기대한 것과 다른 결과를 보여준다.

JShell Console 상단 메뉴바에 보이는 ‘Use classpath of’ 설정을 변경해보아도 결과는 동일하다. IntelliJ 의 Project Structure 설정에서 직접  class path 를 추가해야 한다.

위의 메뉴를 선택하면 열리는 창에서 Project compiler output 경로를 확인한다.

그리고 아래와 같이 Libraries 설정에 class 파일의 위치를 추가한다.

설정을 적용하고 다시 JShell Console 로 돌아가서 실행해보자. 여전히 에러가 발생할 것이다.
JShell Console 를 닫고 다시 실행하자.

다시 실행하면 아래와 같이 기대한 결과가 나온다.

이제부터는 사용자 클래스도 JShell Console 에서 편하게 테스트해볼 수 있는 환경이 되었다. 특정 라인을 블럭으로 선택하고 실행하면 전체가 아닌 선택된 라인만 실행된다.  주의할 점은 JShell Console 은 class 파일을 바라보고 있으므로 사용자 클래스를 변경하게 된다면 컴파일을 다시 해야만 한다.

마치며

IntelliJ 의 Scala Console 에 비해서 아직 JShell Console 기능이 미흡하지만 유용한 기능이다. 만약 본인이 만든 클래스를 JShell Console 에서 생성하는 것이 너무 어렵다면 외부 의존성이 너무 높은 것은 아닌지 다시 생각해보자.

Java 에 적응하면서 정리한 내용이라 미흡한 내용이 있을 수도 있습니다. 틀린 내용이 있다면 피드백 부탁합니다.


반응형

'Dev' 카테고리의 다른 글

Codility Lessons 1 ~ 5 완료  (0) 2019.02.06
7가지 동시성 모델  (0) 2018.12.17
NHN Ent 경력 공채  (0) 2018.04.19
JAVA 8 에서 케이크 패턴(Cake Pattern)을 사용해보자  (2) 2018.04.01
Setting ZeroMQ for MacOS  (0) 2018.01.12