自動更新機能付きJavaクラスローダーを作る

簡単に言うと Java Web Start のようなものを作りました。

https://github.com/tamurashingo/jalo


## Motivation

 - 社内ツールとかを修正した際に、勝手に更新されるとうれしい。（建前）
 - なんとなく面白そう。（本音）


## 機能

 - java -jar jalo.jar でアプリを起動することができます。（約25KB）
 - アプリ起動時にサーバ側のアプリを自動でダウンロードすることができます。（しないこともできます）
 - スプラッシュスクリーンに対応しています。


## 使い方

### jalo.xmlの編集

```xml
<?xml version='1.0' encoding='utf-8'?>
<jalo>
  <!---
    --- アプリケーション名。
    --- 特に使用しない。
    --->
  <application-name></application-name>

  <!---
    --- app.xml（およびアプリケーション）を配置するディレクトリ。
    --->
  <application-directory></application-directory>

  <!---
    --- 更新用アプリケーションの配置先。
    --->
  <url></url>

  <!---
    --- 自動更新の有無。
    ---  1 : 自動更新する。
    ---  0 : 自動更新しない。
    --->
  <auto-update></auto-update>

  <!---
    --- ダウンロード用モジュールの実装クラス名。
    --->
  <update-class></update-class>

  <!---
    --- ファイル一時配置用のディレクトリ名。
    --->
  <temporary-directory></temporary-directory>
</jalo>
```

### app.xmlの編集

```xml
<?xml version='1.0' encoding='utf-8'?>
<app>
  <!---
    --- アプリケーション名。
    --->
  <name></name>
      
  <!---
    --- アプリケーションのバージョン。
    --- サーバのバージョンのほうが新しければダウンロード可能となる。
    --- >
  <version></version>
      
  <!---
    --- アプリケーション起動に必要なJarファイル。
    --->
  <classpath>
    <path></path>
  </classpath>
      
  <!---
    --- mainメソッドのあるクラス名。
    --->
  <mainclass></mainclass>
</app>
```


注意
バージョン番号の比較には String.compareTo() メソッドを使用しています。そのため、以下のようになるため注意が必要です。

| ローカル | サーバ | ダウンロード |
|----------+--------+--------------|
|      0.1 |    0.1 | しない       |
|      0.1 |    0.2 | する         |
|      0.8 |    0.9 | する         |
|      0.9 |   0.10 | しない       |



### ファイルの配置

1. サーバ側に app.xml およびjarファイルを配置します。
2. jalo.jar および jalo.xml を配布します。
3. java -jar jalo.jar を実行します。

初回のみサーバからアプリケーションをダウンロードします。二回目以降はサーバが更新されていなければ、ダウンロードしません。



## 例

HTTP更新の場合

```xml
<?xml version='1.0' encoding='utf-8'?>
<jalo>
  <application-name>TestHelloWorld</application-name>
  <application-directory>app</application-directory>
  <url>http://tamurashingo.github.io/jalo/testhelloworld</url>
  <auto-update>0</auto-update>
  <update-class>com.github.tamurashingo.jalo.autoupdater.impl.HttpAutoUpdater</update-class>
  <temporary-directory>tmp</temporary-directory>
</jalo>
```

File更新の場合

```xml
<?xml version='1.0' encoding='utf-8'?>
<jalo>
  <application-name>TestHelloWorld</application-name>
  <application-directory>app</application-directory>
  <url>\\fileserver\tools\testhelloworld</url>
  <auto-update>0</auto-update>
  <update-class>com.github.tamurashingo.jalo.autoupdater.impl.FileAutoUpdater</update-class>
  <temporary-directory>tmp</temporary-directory>
</jalo>
```

アプリケーションの設定例

```xml
<?xml version='1.0' encoding='utf-8'?>
<app>
  <name>TestHelloWorld</name>
  <version>0.1</version>
  <classpath>
    <path>TestHelloWorld01.jar</path>
    <path>commons-lang3-3.1.jar</path>
  </classpath>
  <mainclass>test.main.Main</mainclass>
</app>
```


### スプラッシュスクリーン

Jaloは起動時に透明GIFをスプラッシュスクリーンとして使用しています。
スプラッシュスクリーンを使用したい場合は、これを上書きします。

```java
// PNG画像をスプラッシュスクリーンとして表示する。
public Init {
    public void init() {
        SplashScreen screen = SplashScreen.getSplashScreen();
        if (screen != null) {
            try {
                ClassLoader loader = Init.class.getClassLoader(); 
                screen.setImageURL(loader.getResource("splashscreen.png"));
            }
            catch (NullPointerException|IOException|IllegalStateException ex) {
                ex.printStackTrace();
            }
        }
    }
}
```


## 拡張

### 更新モジュール

更新モジュールは

 - HTTP
 - File

のみ対応しています。
com.github.tamurashingo.jalo.autoupdater.AutoUpdaterインタフェースを実装すれば好みのプロトコルに対応させることができます。（LDAPにクラスファイルを格納とかおもしろそうです）