BukkitのPluginをJava11で作る

#今回の内容
- OracleのJDK11を用いてMinecraftプラグイン（Spigot version 1.13以降）を作る
- JRE11を自作してSpigot Serverを動かし、自作プラグインを試す

##対象
- 巷に転がっているチュートリアルをある程度クリアし、EclipseやMavenを何となく知っている人
- 一度は簡単なBukkitのPluginを作ってみた人
- Java9以降に乗り換えようと考えているが迷っているPlugin作者並びにサーバー運営者
- プラグイン初級or中級者（私自身は中級者だと勝手に自負していますが、実は初めての記事なので間違ってることも多いかも...?）

#OracleのJDK11とは
##JDK
JDKとは Java Development Kitのことで、コンパイル（Javaで人間がコードを書いて、それがコンピューターが理解できる形へと変化する作業）を行ったり実行環境を提供したりします。JDKから実行環境だけを抜き取ったものがJRE（Java Runtime Environment）です。Windowsを使う方には「Javaの最新版が公開されました」なんてポップアップが出て更新を促された経験がある方もいらっしゃるのではないでしょうか。それはJREの更新を促すメッセージなわけです。
##11
Javaはバージョンアップを重ね2020年6月現在バージョン13系まで公開されています。数字が上がる方がより新しいバージョンであることを表わしています。今回はバージョン11（正確にはJDK-11.0.7）を使っていきます。Javaは基本的には下位互換であるので、バージョンを上げたからといって、昔作ったものが使えなくなるということはないようです。
##Oracle
Javaを作っている会社の一つです。他にもRedhatJDKやOpenJDKなどが存在しますが、今回はOracleJDKを用います。どれを選んでもらってもほとんど性能に差はなく互換性があります（...そのはず）。ただしOracleのものを使うと実行環境の整備にちょっと苦労します。というのもJava8まではJDKとJREは別々に配布されていたのですが（現にJDKがインストールされていないPCでもJavaのポップアップが出てきてJREのインストールが促される）、最近はJRE単体での配布は行われず、もしJREが必要ならばJDKを使ってJREを自作しなければならなくなりました。RedHatのJavaでは現在もJREが単体で配布されているようなので、今回紹介する面倒な作業を避けたい場合はそちらを利用するのも手になります。

#何が嬉しいのか？
- 2020年でJava8はサポート切れになることになっていて、そろそろ乗り換えを検討したいところ。
- 最新のモダンな書き方を実践できる。
 - listやmapに対するstreamでfor文を読みやすく
 - nullを回避するOptional（OptionalはJava8でも使えるはずだがより機能が強化されている。）


#JDK11でBukkitプラグインを作る
##環境
チュートリアルなんかでおなじみのEclipseを用いてコードを書き、Mavenを用いて依存関係の管理をしています。
##Oracle JDK11を入手する
現在最新バージョンは13になっており、古いバージョンのJDKの取得にはOracleへの無料会員登録が必要でした。少々面倒。

##パスを通す
入手したJDKを適当なフォルダに設置したのち、Pathを通してください
設置場所はWindowsのProgram Filesの中のJavaの中でもいいと思います。自分はそうしています。

##Eclipseの設定
eclipseのexeがあるフォルダにはeclipse.iniファイルがあると思います。その中の
-vmという項目を先ほど設置したJDKのパスに書き換えます。
例）C:\Program Files\Java\jdk-11.0.7\bin


##MavenでJava11を設定する
Eclipseでpom.xmlを以下のように設定しプロジェクトの更新を行います。チュートリアルでよく見かけるような形からMavenをいじっているので、「注目すべきはここ！」以外の箇所は気にしないでください。

```xml:pom.xml（一部抜粋）

<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>自分のGithubレポジトリなど</groupId>
  <artifactId>今回のプラグインの名前</artifactId>
  <version>適当なバージョンの名前</version>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
　　<!-- 今回注目すべきはここ！-->
    <java.version>11</java.version>
  </properties>
  
  <build>
   <plugins>
     <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-compiler-plugin</artifactId>
       <version>2.3.2</version>
       <configuration>
　　　　　<!-- 今回注目すべきはここ！※${java.version}は11を参照しています-->
         <source>${java.version}</source>
         <target>${java.version}</target>
       </configuration>
     </plugin>
     <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>2.2</version>
        <executions>
          <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
            <goal>single</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
          <archive>
            <manifest>
              <mainClass>メインクラス</mainClass>
            </manifest>
          </archive>
        </configuration>
      </plugin>
   </plugins>
 </build>
 
 <repositories>
   <repository>
     <id>spigot-repo</id>
     <url>https://hub.spigotmc.org/nexus/content/groups/public</url>
   </repository>
 </repositories>
 <dependencies>
   <dependency>
     <groupId>org.bukkit</groupId>
     <artifactId>bukkit</artifactId>
     <!-- Bukkitのバージョン -->
     <version>1.15.2-R0.1-SNAPSHOT</version>
   </dependency>
 </dependencies>
</project>
```

##コードを書き、コンパイル（Maven install）する
あとは思う存分Javaのモダンな書き方を試してください。


#実行環境（Spigot Server）の整備
Windows上でSpigot Serverを動かしていきます。ここが一番の鬼門だと思います。私も試行錯誤を繰り返してなんとかうまくいったので、あくまでも一つの事例として参考にしてみてください。もっといい方法あるよ、っていうのはぜひ教えてください。
##Spigot Serverのビルド
1. BuildTools.jarを公式サイトからダウンロードし、サーバーを立てる用のフォルダの中に持ってくる
2. 以下のbatファイルを同じフォルダ内に作成・実行してBuildToolsを動かすためのJREを自作する。このJREはMinecraft Java Edition 自体を動かしたりサーバーを起動させたりするときにも不足なく動いてくれるようです。詳しくはjdepsやjlinkなどで検索してみてください。

    ```bat:jrebuild.bat
    FOR /F %%i in ('jdeps --print-module-deps BuildTools.jar') do set x=%%i
    echo %x%
    jlink --compress=2 --module-path "C:\Program Files\Java\jdk-11.0.7\bin" - 
    -add-modules %x% --output jre-min
    pause
    ```
このコードを実行するとjre-minという名前のJREフォルダができます。

3. 作成したJREにパスを通す。その際他のバージョンのJREへのパスは一旦消した方がいいかもしれない？当然ながらMinecraft以外でJavaを使う機会がある方はそっちでエラーがでる可能性は念頭に入れておいてください。
4. gitでjava -jar BuildTools.jar --rev 1.15.2を実行。（めでたくSpigotがJava11に対応する。）
5. サーバーを起動しEULAなどの設定を済ませ、作ったプラグインを入れる。無事起動したら終わり。

##生じうる問題
- JREのバージョンが古いままだと、Java11などで新しく導入されたメソッドを呼び出した際にエラーを吐きます。JDKとJREのバージョンは揃えてください。
- Spigot Serverを起動したときにjava base なんちゃらが不足しています、みたいなエラーを吐いたときは、自作したJREに含まれるユニットが足りていない可能性があります。頑張って追加してください。適当ですみません。
- 我々の実験環境ではDymapが変な挙動を示した。Javaのバージョンによるものなのかは不明。

#終わりに
非常に適当な説明ですが、一応我々のサーバーほぼほぼJava11で問題なく動いています。もし他で試している方がいらっしゃったらぜひご連絡ください。
また、私たちは現在新たな公開サーバーを立ち上げ中です。運営陣はサーバー管理のため会費の支払いが求められますが、建築などでも興味ある方がいらっしゃればTwitterのDMなどでお声かけください。