Java Web Start とは

Java Web Start(Javaアプリケーションの配備を簡素化するテクノロジ)を利用すると、Webブラウザで1回クリックするだけでフル装備のアプリケーションを起動できます。複雑なインストール作業なしで、フル機能のスプレッドシートプログラムやインターネットチャットクライアントなどをダウンロードおよび起動できます。

Java Web Startより引用

security

デフォルトでは、Java Web Startから起動されるクライアントJavaアプリケーションは、安全な限定的環境で実行されるようになっています。 その環境の中では、以下のような禁止事項があります。

  • ローカル・ファイルへのアクセスは禁止
  • 他のコンピューターへのネットワーク接続などが禁止

JNLP API

JNLP APIFileOpenServiceを使用すると、証明書などを用意しなくても、ユーザがFileChooserで指定したローカルファイルだけを読み書きすることができます。

Java Tutorialにある JWSFileChooserDemo などを実行してみてください。

jws-FileOpenService.png

ローカル・マシンに対する完全アクセス

ローカル・マシンに対する完全アクセスを得る場合は次の2点が必要です。

  • セキュリティ証明書ですべてのJARファイルに署名する
  • JNLPファイルにall-permissionsを指定する

以下では、自分で自分自身を証明しているテスト用の証明書(オレオレ証明書)を作って説明します。信頼できるセキュリティ証明書は、ちゃんとした証明書発行機関(認証局、CA)から取得してください。

デジタル署名

  1. JARファイルの作成 まず、JARファイルを作ります(Antを使用する場合は、Ant(Jarファイルの作成)など)。
    jar cf Test.jar Test.class
  2. キーストア(セキュリティ証明書)の作成 次に、キーストア(証明書を保持するデータベース)を作ります。
    keytool -genkey -keystore myKeyStore -alias myAlias
    以下のようなことを聞かれます。
    C:\TEST\SECURITY>"%JAVA_HOME%\bin\keytool" -genkey -keystore myKeyStore -alias myAlias
    キーストアのパスワードを入力してください:  **********
    姓名を入力してください。
     [Unknown]:  Terai Atsuhiro
    組織単位名を入力してください。
     [Unknown]:
    組織名を入力してください。
     [Unknown]:  Hoge
    都市名または地域名を入力してください。
     [Unknown]:  Meguro
    州名または地方名を入力してください。
     [Unknown]:  Tokyo
    この単位に該当する 2 文字の国番号を入力してください。
     [Unknown]:  JP
    CN=Terai Atsuhiro, OU=Sample Team, O=Hoge, L=Meguro, ST=Tokyo, C=JP でよろしいですか?
     [no]:  yes
    
    <myAlias> の鍵パスワードを入力してください。
           (キーストアのパスワードと同じ場合は RETURN を押してください):
    
    C:\TEST\SECURITY>
  3. JARファイルに署名 最後に、JARファイルに署名します。以下はJARファイルに署名するときの、Antターゲットのサンプルです。パスワードを聞かれるので、入力してください。
    <target name="sign" depends="init">
      <input message="input pass" addproperty="store.pass" />
      <signjar keystore="${signjar.keystore}" <!-- myKeyStore -->
                  alias="${signjar.alias}" <!-- myAlias -->
              storepass="${store.pass}">
        <fileset dir="${build.dir}" includes="**/*.jar"/>
      </signjar>
    </target>
    

${build.dir}${signjar.keystore}などの各propertyは、任意の値を設定しておいてください。

jnlpファイル

以下は、セキュリティテスト用のjnlpサンプルです。

<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" codebase="http://ateraimemo.com/data/jws/" href="example.jnlp">
  <information>
    <title>JWS all-permissions</title>
    <vendor>Java Swing Tips - aterai@outlook.com</vendor>
    <homepage href="http://ateraimemo.com/JavaWebStart.html" />
    <description>Swing Example</description>
    <description kind="short">example</description>
    <offline-allowed />
  </information>
  <update check="timeout" policy="always" />
  <security>
     <all-permissions />
  </security>
  <resources>
    <java version="1.6+" />
    <jar href="example.jar" main="true" />
  </resources>
  <application-desc main-class="example.MainPanel" />
</jnlp>

もし<security><all-permissions/></security>要素が無い場合、ローカルリソースにアクセスするようなアプリケーションは起動できません。jarなどに署名し、<security>要素を指定すれば、起動はできるようになりますが、上記サンプルで作成したのが自己証明書なのでセキュリティ警告ダイアログが出ます。

サンプルアプリケーション

上記のサンプルを起動すると、以下のようなセキュリティ警告パネルが表示されます。

jws-security1.png
jws-security2.png

証明書の詳細をクリックすると以下のような証明書情報が表示されます。

  • jws-security3.png

先に述べたように、自分で自分を証明しているだけなので、信頼できない団体から発行されていると警告されています(開始を押すとJFileChooserなどが使えるようになりますが、自己責任でお願いします)。上記のソースをダウンロードするなどして署名の実験をしてみてください。

証明書のインポート

作成したキーストアから証明書をファイルに書き出します。

C:\TEST>keytool -export -keystore myKeyStore -alias myAlias -file example.cer
キーストアのパスワードを入力してください:  **********
証明書がファイル <example.cer> に保存されました。

C:\TEST\>

"%JAVA_HOME%\bin\javaws.exe"を起動し、「編集→設定→セキュリティ→証明書」で、上記の証明書ファイルexample.cerをインポートします。"alias"とパスワードを聞かれるので、これを入力し、最初から実行すれば、セキュリティ警告が以下のように変わっていることが確認できます。これで、先のサンプルのような署名をしたアプリケーションが確認なしで実行できるようになります。

http:// ateraimemo.com/data/jws/security2.png

「JarファイルをPack200で圧縮」「不必要なアップデートのチェックをしない」で起動を速くする


以下、AntPack200Taskを使用する場合のメモ

mvn package -Dmaven.test.skip=true
<target name="dist" depends="package, dist-libcopy, prepare-web">
  <mkdir dir="${bkup.dir}" />
  <fileset id="java.file.list" dir="${src.dir}">
    <include name="**/*.java" />
  </fileset>
  <taskdef name="pack200" classname="com.sun.tools.apache.ant.pack200.Pack200Task" />
  <pack200 src="${build.dir}/${name}.jar"
           destfile="${build.dir}/${name}__V${version}.${build.number}.jar.pack.gz"
           gzipoutput="true" />
  <filter token="homepage" value="${jnlp.homepage}" />
  <filter token="title" value="${jnlp.Name}" />
<!-- 以下省略 -->
  • 上記のサンプルだとファイルサイズは、三分の一程度に圧縮される
  • ファイル名にバージョンを追加し、jnlp.versionEnabledとして、バージョンが上がった場合のみダウンロードするようにしても、ファイルサイズが元々小さいせいかあまり差が感じられない
<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" codebase="http://ateraimemo.com/swing/pack200/" href="example.jnlp">
  <information>
    <title>JST Pack200 Test</title>
    <vendor>Java Swing Tips - aterai@outlook.com</vendor>
    <homepage href="http://ateraimemo.com/JavaWebStart.html" />
    <description>Swing Example</description>
    <description kind="short">example</description>
    <offline-allowed />
  </information>
  <update check="background" />
  <resources>
    <java version="1.6+" />
    <jar href="example.jar" main="true"  version="1.0.2" />
    <property name="jnlp.packEnabled"    value="true" />
    <property name="jnlp.versionEnabled" value="true"/>
  </resources>
  <application-desc main-class="example.MainPanel" />
</jnlp>

Web Start のデバッグ

deployJava.js

  • &jnlp3(Swing/Pack200); 無効化
<!-- https://www.java.com/js/deployJava.js -->
<script src="https://java.com/js/deployJava.js"></script>
<script>deployJava.createWebStartLaunchButtonEx('$url', '1.6+');</script>

Java7をインストールしてから?、deployJava.jsを使うと、Javaのダウンロードページに飛ばされるようになってしまった…。

参考リンク


コメント

  • 方法2がうまく動作するのなら、クライアントの環境変数 _JAVA_OPTIONS か、JAVA_TOOL_OPTIONS に、-Djava.net.preferIPv4Stack=true を追加するといいかもしれません。 -- aterai