今回は、2017/07/27にGA予定のJDK 9をTravis CI上で使う方法を簡単に紹介します。
Unstable環境でのお試し版
JDK 9(Oracle JDK 9 Early Access)のサポートについては、travis-ci#gh-5220で対応が行われており、去年の1/28にはUnstable環境上での利用が可能になっていたようです。(今日まで知らなかった・・・)
どうすれば使えるの?
.travis.yml
の設定を以下のようにするだけです。
language: java
sudo: required
dist: trusty
jdk:
- oraclejdk8
- oraclejdk9
before_install: export MAVEN_SKIP_RC=true
install: mvn install
ポイントは・・・・
sudo: required
dist: trusty
-
jdk
にoraclejdk9
を追加 -
before_install: export MAVEN_SKIP_RC=true
(Mavenを使う場合のみ)
の4つです。
sudo
はfalse
でも動くみたいですがrequired
が無難っぽいです。
あと・・・Mavenを使う場合は、MAVEN_SKIP_RC=true
を指定しないと・・・・以下のようなエラーが出てしまいます。
...
$ mvn install
Unrecognized VM option 'MaxPermSize=192m'
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
...
これは、Java 8で廃止された -XX:MaxPermSize
がVMの起動オプションに指定されているためです。Java 8では警告ログを出力した上で実行時は無視するようになっていましたが、Java 9からはエラーになるようになっています。(詳しくは、Issueを参照してください)
実際にTravis CIでJDK 9を試してみよう
「Hallo World !」を標準出力する簡易アプリケーションを作り、Travis CI上でMavenを使ってビルドしてみましょう。
Note:
実際にためした簡易アプリケーションは、以下のGitHubリポジトリに格納してあります。(Mavenビルド時にMaven wapperを使っている点の除けば、本投稿と内容は同じです)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>jdk9-demo-with-maven</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>jdk9-demo-with-maven</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.testTarget>1.8</maven.compiler.testTarget>
<maven.compiler.testSource>1.8</maven.compiler.testSource>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>jdk9</id>
<activation>
<jdk>9</jdk>
</activation>
<properties>
<maven.compiler.target>1.9</maven.compiler.target>
<maven.compiler.testTarget>1.9</maven.compiler.testTarget>
</properties>
</profile>
</profiles>
</project>
package com.example;
public class Jdk9DemoWithMavenApplication {
public static void main(String[] args) {
Message message = new Message("Hello World !");
System.out.println(message.getText());
System.out.println(System.getProperties());
}
static class Message {
private final String text;
Message(String text) {
this.text = text;
}
String getText() {
return text;
}
}
}
package com.example;
import org.hamcrest.core.Is;
import org.junit.Assert;
import org.junit.Test;
public class Jdk9DemoWithMavenApplicationTest {
@Test
public void contextLoads() {
System.out.println(System.getProperties());
Jdk9DemoWithMavenApplication.Message message = new Jdk9DemoWithMavenApplication.Message("Hello World !");
Assert.assertThat(message.getText(), Is.is("Hello World !"));
}
}
language: java
sudo: required
dist: trusty
jdk:
- oraclejdk8
- oraclejdk9
before_install: export MAVEN_SKIP_RC=true
install: mvn install
# 簡易アプリを起動するためのスクリプト
script: mvn exec:java -Dexec.mainClass=com.example.Jdk9DemoWithMavenApplication
これをGitHubにPushすれば・・・
Travis CI上でビルドが開始し、以下のような実行ログが出力されます。
...
$ jdk_switcher use oraclejdk9
Switching to Oracle JDK9 (java-9-oracle), JAVA_HOME will be set to /usr/lib/jvm/java-9-oracle
$ java -Xmx32m -version
java version "9-ea"
Java(TM) SE Runtime Environment (build 9-ea+140)
Java HotSpot(TM) 64-Bit Server VM (build 9-ea+140, mixed mode)
$ javac -J-Xmx32m -version
javac 9-ea
$ export MAVEN_SKIP_RC=true
$ mvn install
...
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.example.Jdk9DemoWithMavenApplicationTest
{awt.toolkit=sun.awt.X11.XToolkit, java.specification.version=9, file.encoding.pkg=sun.io, sun.cpu.isalist=, sun.jnu.encoding=UTF-8, java.class.path=/home/travis/build/kazuki43zoo/jdk9-demo-with-maven/target/test-classes:/home/travis/build/kazuki43zoo/jdk9-demo-with-maven/target/classes:/home/travis/.m2/repository/junit/junit/4.12/junit-4.12.jar:/home/travis/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:, java.vm.vendor=Oracle Corporation, sun.arch.data.model=64, java.vendor.url=http://java.oracle.com/, user.timezone=, os.name=Linux, java.vm.specification.version=9, sun.java.launcher=SUN_STANDARD, user.country=US, sun.boot.library.path=/usr/lib/jvm/java-9-oracle/lib/amd64, sun.java.command=/home/travis/build/kazuki43zoo/jdk9-demo-with-maven/target/surefire/surefirebooter8688134916500123866.jar /home/travis/build/kazuki43zoo/jdk9-demo-with-maven/target/surefire/surefire965005284627576688tmp /home/travis/build/kazuki43zoo/jdk9-demo-with-maven/target/surefire/surefire_05891703120810359159tmp, jdk.debug=release, surefire.test.class.path=/home/travis/build/kazuki43zoo/jdk9-demo-with-maven/target/test-classes:/home/travis/build/kazuki43zoo/jdk9-demo-with-maven/target/classes:/home/travis/.m2/repository/junit/junit/4.12/junit-4.12.jar:/home/travis/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:, sun.cpu.endian=little, user.home=/home/travis, user.language=en, java.specification.vendor=Oracle Corporation, java.home=/usr/lib/jvm/java-9-oracle, file.separator=/, basedir=/home/travis/build/kazuki43zoo/jdk9-demo-with-maven, java.vm.compressedOopsMode=32-bit, line.separator=
, java.vm.specification.vendor=Oracle Corporation, java.specification.name=Java Platform API Specification, java.awt.graphicsenv=sun.awt.X11GraphicsEnvironment, surefire.real.class.path=/home/travis/build/kazuki43zoo/jdk9-demo-with-maven/target/surefire/surefirebooter8688134916500123866.jar, sun.management.compiler=HotSpot 64-Bit Tiered Compilers, java.runtime.version=9-ea+140, user.name=travis, path.separator=:, os.version=4.4.0-51-generic, java.runtime.name=Java(TM) SE Runtime Environment, file.encoding=UTF-8, java.vm.name=Java HotSpot(TM) 64-Bit Server VM, localRepository=/home/travis/.m2/repository, java.vendor.url.bug=http://bugreport.java.com/bugreport/, java.io.tmpdir=/tmp, java.version=9-ea, user.dir=/home/travis/build/kazuki43zoo/jdk9-demo-with-maven, os.arch=amd64, java.vm.specification.name=Java Virtual Machine Specification, java.awt.printerjob=sun.print.PSPrinterJob, sun.os.patch.level=unknown, java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib, java.vm.info=mixed mode, java.vendor=Oracle Corporation, java.vm.version=9-ea+140, sun.io.unicode.encoding=UnicodeLittle, java.class.version=53.0}
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.11 sec
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
...
$ mvn exec:java -Dexec.mainClass=com.example.Jdk9DemoWithMavenApplication
...
Hello World !
{awt.toolkit=sun.awt.X11.XToolkit, exec.mainClass=com.example.Jdk9DemoWithMavenApplication, java.specification.version=9, file.encoding.pkg=sun.io, sun.cpu.isalist=, sun.jnu.encoding=UTF-8, java.class.path=/home/travis/build/kazuki43zoo/jdk9-demo-with-maven/.mvn/wrapper/maven-wrapper.jar, java.vm.vendor=Oracle Corporation, sun.arch.data.model=64, java.vendor.url=http://java.oracle.com/, user.timezone=UTC, os.name=Linux, java.vm.specification.version=9, sun.java.launcher=SUN_STANDARD, user.country=US, sun.boot.library.path=/usr/lib/jvm/java-9-oracle/lib/amd64, sun.java.command=org.apache.maven.wrapper.MavenWrapperMain exec:java -Dexec.mainClass=com.example.Jdk9DemoWithMavenApplication, jdk.debug=release, maven.home=/home/travis/.m2/wrapper/dists/apache-maven-3.3.9-bin/2609u9g41na2l7ogackmif6fj2/apache-maven-3.3.9, sun.cpu.endian=little, user.home=/home/travis, user.language=en, java.specification.vendor=Oracle Corporation, java.home=/usr/lib/jvm/java-9-oracle, file.separator=/, java.vm.compressedOopsMode=32-bit, line.separator=
, java.vm.specification.vendor=Oracle Corporation, java.specification.name=Java Platform API Specification, java.awt.graphicsenv=sun.awt.X11GraphicsEnvironment, sun.management.compiler=HotSpot 64-Bit Tiered Compilers, java.runtime.version=9-ea+140, user.name=travis, path.separator=:, securerandom.source=file:/dev/./urandom, os.version=4.4.0-51-generic, java.runtime.name=Java(TM) SE Runtime Environment, file.encoding=UTF-8, guice.disable.misplaced.annotation.check=true, java.vm.name=Java HotSpot(TM) 64-Bit Server VM, java.vendor.url.bug=http://bugreport.java.com/bugreport/, java.io.tmpdir=/tmp, java.version=9-ea, user.dir=/home/travis/build/kazuki43zoo/jdk9-demo-with-maven, os.arch=amd64, maven.multiModuleProjectDirectory=/home/travis/build/kazuki43zoo/jdk9-demo-with-maven, java.vm.specification.name=Java Virtual Machine Specification, java.awt.printerjob=sun.print.PSPrinterJob, sun.os.patch.level=unknown, java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib, java.vm.info=mixed mode, java.vendor=Oracle Corporation, java.vm.version=9-ea+140, classworlds.conf=/home/travis/.m2/wrapper/dists/apache-maven-3.3.9-bin/2609u9g41na2l7ogackmif6fj2/apache-maven-3.3.9/bin/m2.conf, sun.io.unicode.encoding=UnicodeLittle, java.class.version=53.0}
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.089 s
[INFO] Finished at: 2017-01-06T15:49:53+00:00
[INFO] Final Memory: 12M/43M
[INFO] ------------------------------------------------------------------------
The command "mvn exec:java -Dexec.mainClass=com.example.Jdk9DemoWithMavenApplication" exited with 0.
Done. Your build exited with 0.
まとめ
Travis CI上でJDK 9を使うのは簡単ですね。ただ・・・自分が作っているライブラリやアプリケーションがJDK 9でビルド&実行できるかは別の話です・・・。使っているライブラリがJava 9のJVMで動かない・・・ということは普通にありそうですし、ビルドツールのプラグインがJDK 9をサポートできていないケースなどもあるようです・・・
とりあえず現状を把握するために、Travis CIを使ってJDK 9でビルドしてみるとよいでしょう。
Note:
JavassistやCGLIBなどのバイトコードをいじるライブラリを使っている場合は、実行時にエラーになる可能性たかそう・・・。