• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:Java Web Start
#keywords(Java Web Start)
#description(Java Web Startについてのメモで、jarファイルへの署名方法やjnlpファイルのサンプルなどを紹介しています。)
*Java Web Start [#u30e5d3c]
>編集者:[[Terai Atsuhiro>aterai]]~
作成日:2003-12-11~
更新日:&lastmod;

#contents(big)

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

RIGHT:[http://java.sun.com/products/javawebstart/ja/index_ja.html Java Web Start]より引用

*security [#jb1615ab]
デフォルトでは、Java Web Start から起動されるクライアントJavaアプリケーションは、安全な限定的環境で実行されるようになっています。
その環境の中では、以下のような禁止事項があります。
-ローカル・ファイルへのアクセスは禁止
-他のコンピューターへのネットワーク接続などが禁止

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

Java Tutorial にある [http://download.oracle.com/javase/tutorial/uiswing/components/filechooser.html JWSFileChooserDemo] などを実行してみてください。

#ref(http://lh6.ggpht.com/_9Z4BYR88imo/TQsBU1kDkQI/AAAAAAAAAsc/LRbWjDHM7Xs/s800/jws-FileOpenService.png)

*ローカル・マシンに対する完全アクセス [#gbe99659]
ローカル・マシンに対する完全アクセスを得る場合は次の2点が必要です。
-セキュリティ証明書ですべてのJARファイルに署名する
-JNLPファイルに"all-permissions" を指定する

以下では、自分で自分自身を証明しているテスト用の証明書([http://d.hatena.ne.jp/keyword/%A5%AA%A5%EC%A5%AA%A5%EC%BE%DA%CC%C0%BD%F1 オレオレ証明書])を作って説明します。信頼できるセキュリティ証明書は、ちゃんとした証明書発行機関((認証局、CA))から取得してください。
-参考:[http://sqs2.net/tdiary/20060411.html#p01 コード署名証明書の購入~利用プロセス]

**デジタル署名 [#f02ff195]
+JARファイルの作成
>
まず、JARファイルを作ります(Antを使用する場合は、[[Ant(Jarファイルの作成)>Ant/JarPackage]]など)。
 jar cf Test.jar Test.class
<
+キーストア(セキュリティ証明書)の作成
>
次に、キーストア(証明書を保持するデータベース)を作ります。
 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>
<
+JARファイルに署名
>
最後に、JARファイルに署名します。以下はJARファイルに署名するときの、Antターゲットのサンプルです。パスワードを聞かれるので、入力してください。
#code{{
<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ファイル [#xda49b51]
以下は、セキュリティテスト用のjnlpサンプルです。

#code{{
<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" codebase="http://terai.xrea.jp/data/jws/" href="example.jnlp">
  <information>
    <title>JWS all-permissions</title>
    <vendor>Java Swing Tips - at.terai@gmail.com</vendor>
    <homepage href="http://terai.xrea.jp/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>要素を指定すれば、起動はできるようになりますが、上記サンプルで作成したのが自己証明書なのでセキュリティ警告ダイアログが出ます。

**サンプルアプリケーション [#w4e496aa]
-[http://terai.xrea.jp/data/jws/example.jnlp サンプルを Web Start で起動]
--[http://terai.xrea.jp/data/jws/example.jar example.jar]
--[http://terai.xrea.jp/data/jws/src.zip src.zip] (キーストア(この例ではmyKeyStore)は含まれていません)

上記のサンプルを起動すると、以下のようなセキュリティ警告パネルが表示されます。
#ref(http://lh3.ggpht.com/_9Z4BYR88imo/TQr_9JWkB7I/AAAAAAAAAsM/DESyA7Cl5Bk/s800/jws-security1.png)
#ref(http://lh3.ggpht.com/_9Z4BYR88imo/TQr_9V4LxsI/AAAAAAAAAsQ/MNDROeFnaBM/s800/jws-security2.png)

証明書の詳細をクリックすると以下のような証明書情報が表示されます。
-[http://lh5.ggpht.com/_9Z4BYR88imo/TQr_9drZRKI/AAAAAAAAAsU/t4VXML-H-Yk/s800/jws-security3.png &ref(http://lh5.ggpht.com/_9Z4BYR88imo/TQr_9drZRKI/AAAAAAAAAsU/t4VXML-H-Yk/s400/jws-security3.png);]

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

*証明書のインポート [#o3bc3adf]
作成したキーストアから証明書をファイルに書き出します。
 C:\TEST>keytool -export -keystore myKeyStore -alias myAlias -file example.cer
 キーストアのパスワードを入力してください:  **********
 証明書がファイル <example.cer> に保存されました。
 
 C:\TEST\>

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

%%http:// terai.xrea.jp/data/jws/security2.png%%

*「JarファイルをPack200で圧縮」「不必要なアップデートのチェックをしない」で起動を速くする [#ze974b4e]
- default(JumpToClickedPositionSlider): &jnlp2(Swing/JumpToClickedPositionSlider);
-- [[JSliderでクリックした位置にノブをスライド>Swing/JumpToClickedPositionSlider]]のまま
- jnlp.packEnabled, jnlp.versionEnabled: &jnlp2(Swing/Pack200);
-- http://terai.xrea.jp/swing/pack200/src.zip
-- http://terai.xrea.jp/swing/pack200/example__V1.0.2.jar.pack.gz
-- 同じJarファイルをPack200で圧縮して(jnlp.packEnabled)、ダウンロードするファイルのサイズを圧縮
-- ファイル名にバージョンを付加して(jnlp.versionEnabled)、不必要なアップデートのチェックをしない
--- 参考: [http://java.sun.com/docs/books/tutorial/deployment/deploymentInDepth/avoidingUnnecessaryUpdateChecks.html Avoiding Unnecessary Update Checks]
--- [http://java.sun.com/javase/ja/6/docs/ja/technotes/tools/share/pack200.html pack200 - JAR パックツール]

#code{{
  <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 として、バージョンが上がった場合のみダウンロードするようにしても、ファイルサイズが元々小さいせいかあまり差が感じられない

#code{{
<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" codebase="http://terai.xrea.jp/swing/pack200/" href="example.jnlp">
  <information>
    <title>JST Pack200 Test</title>
    <vendor>Java Swing Tips - at.terai@gmail.com</vendor>
    <homepage href="http://terai.xrea.jp/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 のデバッグ [#m7950a4d]
-[http://icoloma.blogspot.com/2005/06/how-to-debug-jwsjnlp.html The 90th percentile: How to debug JWS/JNLP]
 set JAVAWS_VM_ARGS=-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8989,server=y,suspend=n
 javaws http://terai.xrea.jp/swing/zoom/example.jnlp
-[http://www.smg.co.jp/JavaTroubleshooting/column_003Main.html コラム: Java Web Startのリモートデバッグ - SMG]
-[http://d.hatena.ne.jp/Kazzz/20080408/p2 Java web startアプリケーションをデバッグする(Java6) - Kazzzの日記]
 "%JAVA_HOME%\bin\java.exe" "-Xbootclasspath/a:%JAVA_HOME%\jre\lib\javaws.jar;%JAVA_HOME%\jre\lib\deploy.jar" -Djnlpx.home="%JAVA_HOME%\jre\bin" -Djnlp.jvm="%JAVA_HOME%\jre\bin\java.exe" -Djava.security.policy="file:%JAVA_HOME%\lib\security\javaws.policy" -DtrustProxy=true -Xverify:remote -Djnlpx.heapsize=NULL,NULL -Djnlpx.vmargs="-classic -Xdebug -Dnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8918" com.sun.javaws.Main "http://terai.xrea.jp/swing/zoom/example.jnlp"
-[http://pscode.org/janela/ JaNeLA - The Java Network Launch Anaylzer]

*deployJava.js [#j2fe0006]
- https://www.java.com/js/deployJava.js
- &jnlp3(Swing/Pack200);

#code{{
<script src="http://java.com/js/deployJava.js"></script>
<script>deployJava.createWebStartLaunchButtonEx('$url', '1.6+');</script>
}}

Java7をインストールしてから?、deployJava.jsを使うと、Java のダウンロードページに飛ばされるようになってしまった…。
- [https://forums.oracle.com/forums/thread.jspa?threadID=2309585 OTN Discussion Forums : Problems using deployJava.js with Java 7 ...]

*参考リンク [#g131e2b0]
-[http://java.sun.com/javase/6/docs/technotes/guides/javaws/ Java(TM) Web Start]
-[http://java.sun.com/javase/ja/6/docs/ja/technotes/guides/javaws/ Java(TM) Web Start(日本語)]
-[http://java.sun.com/javase/ja/6/docs/ja/technotes/tools/index.html#security JDK の開発ツール#セキュリティーツール]
-[http://java.sun.com/javase/ja/6/docs/ja/jre/api/javaws/jnlp/index.html javax.jnlp (JNLP API Reference 1.5)]
-[http://lopica.sourceforge.net/faq.html Unofficial Java Web Start/JNLP FAQ]
----
-[http://forums.sun.com/forum.jspa?forumID=38 Deploying - Java Web Start & JNLP]
//-%%[http://www.waynegrant.info/keytool.html KeyTool GUI]%%
//-[http://www.ki.rim.or.jp/~kuro/Java/JavaKey/ Java Key 実験場]
-[http://www.ibm.com/developerworks/jp/java/library/j-certgen/ Javaアプリケーションのテスト用に証明書チェーンを生成]
-[http://sqs2.net/tdiary/20051003.html#p01 [dev] 無償で正統的なコードサイニング証明書を入手する方法 - 日々是開発:SQS Development(2005-10-03)]
--[http://www.slideshare.net/hiroya/webstart-maven-plugin webstart-maven-pugin + 無償で正統?なコード署名証明書を入手する方法]
//-[http://nmag.jp/contents/servercertificate/index.html ネットワークマガジン - Network Magagine - 徹底比較 SSLサーバ証明書の「値段」と「品質」]

- [http://blogs.sun.com/thejavatutorials/entry/deploying_your_rich_internet_application Deploying Your Rich Internet Application Nice And Easy!]
- [http://blogs.sun.com/thejavatutorials/entry/deployment_toolkit_101 Deploying a Java Web Start application using the createWebStartLaunchButton function: The Java Tutorials' Weblog]
//- [http://java.sun.com/docs/books/tutorial/deployment/deploymentInDepth/avoidingUnnecessaryUpdateChecks.html Avoiding Unnecessary Update Checks]
//-- default: &jnlp2(Swing/JumpToClickedPositionSlider);
//-- jnlp.packEnabled, jnlp.versionEnabled: &jnlp2(Swing/zJumpToClickedPositionSlider);

*コメント [#t8d59970]
- メモ: [http://sqs2.net/tdiary/20071202.html#p01 [bug] JNLP:JavaWebStartでデスクトップ上に作成したショートカット<アイコンにファイルをドロップすると、そのアプリケーションの起動に失敗し、「このアプリケーションは起動できません」と出る - 日々是開発:SQS Development(2007-12-02)] -- [[aterai]] &new{2007-12-03 (月) 16:29:46};
-- メモ:[http://bugs.sun.com/view_bug.do?bug_id=6646617 Bug ID: 6646617 Dropping a file on a Java Web Start desktop symbol DELETES the file] -- [[aterai]] &new{2008-02-22 (金) 19:12:26};
- メモ:[http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6943522 Bug ID: 6943522 Failed to launch any signed application on 6u19 when cache is disabled] -- [[aterai]] &new{2010-07-20 (火) 18:37:19};
- リンク切れを修正。 -- [[aterai]] &new{2010-10-06 (水) 12:54:15};
- いつもお世話になっております。単体SWINGでは-Djava.net.preferIPv4Stack=trueを付けると、PGMはうまく動きましたが、jnlpにどのように書けばいいかが判らなく、ご教示ください。<resources><property name="java.net.preferIPv4Stack" value="true"/>はだめみたいです。</resources>。いつもご教示、感謝しております。 -- [[panda]] &new{2011-12-05 (月) 16:02:29};
-- こんばんは。[http://docs.oracle.com/javase/7/docs/technotes/guides/javaws/developersguide/syntax.html#resources The following properties, as well as properties beginning with either "javaws." or "jnlp.", are considered "secure" and will be passed to the VM in this way:]、[http://java.sun.com/javase/ja/6/docs/ja/technotes/guides/javaws/developersguide/syntax.html 次のプロパティーは「安全」とみなされ、この方法で VM に渡されます。] …にある安全とみなされるプロパティに、java.net.preferIPv4Stack はないので、<security><all-permissions/></security>として、セキュリティ証明書でjarに署名する必要があるのかもしれません(試していないのでうまくいくか不明ですが)。   -- [[aterai]] &new{2011-12-05 (月) 17:27:46};
-- あと、jnlpに記述する必要がないなら、コマンドラインから、javaws -verbose -J-Djava.net.preferIPv4Stack=true http://terai.xrea.jp/swing/wipe/example.jnlp などとしてテストしてみるのもいいかもしれません。 -- [[aterai]] &new{2011-12-05 (月) 17:43:01};
- ご教示、感謝します。方法1は実施しましたが、だめでした。方法2について、まだ理解していません。JWSにおいて、jnlpに書かない方法はありますか?また方法3として、JAVA PGMに直接System.setProperty("java.net.preferIPv4Stack", "true");しましたが、IPv6を取ってきます。方法2について、もう少しご教示ください。 -- [[panda]] &new{2011-12-06 (火) 09:10:19};

#comment