Ch 01. 코틀린 시작하기

커맨드 라인으로 실행시키기

다음 Hello.kt 파일을 만든다.

// running/Hello.kt
fun main() = println("Hello World")
$ kotlinc-jvm Hello.kt -d Hello.jar
  • Hello.kt 파일의 코드를 Java 바이트코드로 컴파일하고, Hello.jar 파일을 만들어 넣어둘 것이다.

$ java -classpath Hello.jar HelloKt
Hello World
  • Hello.ktmain 함수만 갖고 있고 클래스가 아니기 때문에, 코틀린 컴파일러(kotlinc-jvm)가 자동으로 확장자를 제거한 파일 이름을 가지고, Kt라는 접미사를 추가한 클래스 이름을 만든다.

classpath 커맨드라인 옵션을 열거하는 대신에 jar 옵션으로 코드를 실행시킬 수 있다. 왜냐면 main() 함수를 찾을 때 코틀린 컴파일러가 jar 파일에 Main-Class 매니페스트 어트리뷰트를 추가했기 때문이다. Hello.jar 파일에서 아래의 커맨드를 실행해도 같은 결과가 나온다.

$ java -jar Hello.jar
Hello World

이 예제에서 코틀린 스탠다드 라이브러리 중 아무것도 사용하지 않았다. 그러나 코틀린 스탠다드 라이브러리에 있는 클래스와 함수를 사용하게 될텐데, java 툴만을 이용해서 실행하면 java.lang.NoClassDefFoundError 예외와 함께 실패할 것이다. 이를 방지하기 위해 kotlin-stdlib.jar 파일을 클래스패스에 추가해줘야 한다.

$ java -classpath Hello.jar:$KOTLIN_PATH/lib/kotlin-st
dlib.jar HelloKt
Hello World

환경변수는 코틀린이 설치된 디렉토리를 참조한다. Unix-like 시스템에서는 환경변수로 $KOTLIN_PATH를, 윈도우에서는 %KOTLIN_PATH% 가 사용된다. 윈도우에서는 클래스패스 내의 패스를 구분하기 위해 콜론(:)이 아닌 세미콜론(;)을 사용한다.

java 툴을 사용하는 대신 코틀린 툴을 사용할 수 있는데, 이렇게 하면 kotlin-stdlib.jar 을 참조할 필요가 없다.

$ kotlin -classpath Hello.jar HelloKt
Hello World

프로젝트에서 대부분 Java를 사용하고 코틀린을 혼합해서 사용하는 경우라면 java 툴을 사용하고, 그렇지 않다면 코틀린 툴을 사용하는 편이 더 간단하다.

IDE로 실행하기

  • IntelliJ IDEA

  • Eclipse Neon+

  • Netbeans with NetBeans Kotlin Plugin

REPL 실험

어떤 언어들은 코드 스니펫을 위해 REPL 커맨드 라인 쉘을 지원하며, 필자는 그런 시스템을 ‘마이크로프로토타이핑 툴' 이라고 부른다고 한다.

코딩을 하고 있거나, 자동화 테스트를 통과시킬 때, 특정 함수가 무엇인지 생각해보는 대신 REPL을 통해 빠르게 해당 부분을 실행시킬 수 있다.

지금까지 사용한 코틀런 컴파일러 (kotlinc-jvm) 대신 REPL 쉘로 실행시키면 옵션이나 파일 이름 없이 실행시킬 수 있다. 대화형 도구는 kotlinc-jvm 을 실행시키면 된다.

REPL을 실행할 때 직접 만든 jar 파일이나 서드파티의 jar 파일의 클래스패스를 명시할 수도 있다. 그렇게 하면 직접 만든 클래스나 서드파티의 클래스를 REPL에서 대화형으로 사용할 수 있다.

스크립트로 실행하기

앞에서 코틀린 코드를 바이트코드로 컴파일하고, jar 파일을 만들고 java와 코틀린 명령어를 이용해 실행시켜보기도 했다. 이런 두 단계의 프로세스는 많은 파일을 갖고 있는 큰 애플리케이션에서 유용하다.

하지만 우리가 작성하는 모든 코드가 크거나 엔터프라이즈 스케일인 것은 아니다. 프로그램의 크기가 작을 때 쉘 스크립트와 배치파일을 사용한다.

백엔드 작업, 파일 파싱, 특정 구성에 의한 파일 복사 작업 등 일반적으로 쉘 스크립트를 사용해서 하는 작업을 해야할 때 코틀린으로 스크립트를 작성하면 된다. 장점으로는 sh, zsh, bash, Windows CMD, PowerShell 등등 쉘 커맨드를 기억할 필요가 없다는 점이다.

// running/listktfiles.kts
java.io.File(".")
    .walk()
    .filter { file -> file.extension == "kts" }
    .forEach { println(it) }
$ kotlinc-jvm -script listktfiles.kts
./listktsfiles.kts

Unix-like 시스템을 쓴다면 kotlinc-jvm -script를 쓰지 않고 스크립트를 쓰고 싶다면 셔뱅(shebang)을 이용하면 된다.

#!/usr/bin/env kotlinc-jvm -script
java.io.File(".")
    .walk()
    .filter { file -> file.extension == "kts" }
    .forEach { println(it) }
$ chmod 700 listktfiles.kt
$ ./listktfiles.kts
./listktsfiles.kts

시스템에 따라 /usr/bin/env 대신 kotlinc-jvm이 위치한 전체 경로를 적어야 하는 경우도 있다.

스크립트를 프로덕션에서 사용할 목적이라면 kscript가 유용하다. kscript는 컴파일드 스크립트 캐싱을 포함한 코틀린 스크립트에서 동작하는 몇몇 기능을 제공해주는 라이브러리다.

코틀린 코드는 Java 바이트코드로만 컴파일되는 것이 아니다. 다른 몇몇 포맷으로도 컴파일이 가능하다.

  • Android 기기: 코틀린은 안드로이드 개발에서 가장 우선시되는 언어이다.

  • JavaScript 변환: 트랜스파일(transpile, 변환)은 한 언어의 소스코드에서 다른 언어의 소스코드로 변환된다는 것을 의미한다.

  • 네이티브 타깃: 가상 머신으로 컴파일하지 않을 때, 코틀린/네이티브는 소스 코드를 iOS, Linux, macOS, Windows 등의 네이티브 타깃으로 컴파일을 한다. 그리고 그렇게 컴파일된 프로그램은 가상머신 없이 실행이 가능하다.

  • 브라우저에서 실행하기 위한 WebAssembly: 코틀린/네이티브를 사용하면 코틀린 소스 코드를 웹어셈블리 또는 모던 브라우저에서 실행 가능한 바이너리 포맷인 WASM 로 컴파일한다.

어떤 옵션을 선택해야할까?

코틀린은 새로운 코드를 실행시킬 때 특정 옵션 설정을 강제하지 않는다. 모두 개발자의 요구사항과 선호도에 달려있다. 옵션을 선택할 때 고려할 사항이다.

  • 코틀린을 JVM에서 실행시키며 Java 또는 다른 언어와 섞어서 이용해야 한다면 kotlinc-jvm을 이용해서 컴파일하라. 그리고 클래스패스 또는 모듈패스에 kotlin-stdlib.jar 파일과 함께 생성된 jar 파일을 추가한다. 그러면 javac로 컴파일한 Java 소스코드로 만들어진 jar처럼 사용할 수 있다.

  • 여러 개의 코틀린 파일들을 통합해 하나의 코틀린 프로그램으로 실행시켜야 한다면 kotlin 툴을 이용하여 코드를 실행시켜라.

  • 코틀린을 사용하여 시스템 레벨 또는 백엔드 태스크를 구현해야 한다면 코틀린 파일 하나를 만들어서 -script 옵션을 사용하여 코틀린 스크립트로 실행하라. 또는, 셔뱅(shebang)을 사용하면 커맨드라인이나 크론 태스크를 이용하여 직접 스크립트를 실행시킬 수 있다.

  • 웹 애플리케이션 생성을 위한 코틀린의 정적 타이핑과 컴파일 시간 검증을 이용하기 위해서 코틀린을 JavaScript로 컴파일(트랜스파일)하는 옵션을 사용해라.

  • 코틀린 코드를 다른 iOS, WebAssembly와 같은 다른 네이티브 플랫폼에서 사용하기 위해서 코틀린/네이티브를 이용하여 컴파일한다.

  • 개발 과정에서 개발을 편하게 하는 좋은 옵션은 IDE에서 코드를 실행시키는 것이다.

  • 실험을 위해서 스니펫 코드를 실행시킬 때에는 kotlinc-jvm을 REPL로 이용해라.

Last updated