実行可能Jarファイルから外部ファイルへアクセスしてみた

年明けてから、仕事はVC++が9割です。

Java症候群禁断症状が出そうです。

なので、プライベートでは専らJavaをいじってます。

Antの勉強も兼ねて、実行可能Jarファイルを自動生成させています。

その実行可能Jarファイルから

複数の外部Jarファイルやプロパティファイルなどを参照するのにちょっと手こずったので、

自分の備忘録として。

build.xml

<!-- Mainクラス -->
<property name="main" value="SampleMain"/>

<!-- カレントディレクトリ -->
<property name="base.dir" value="."/>

<!-- Jarライブラリやpropertiesファイルのディレクトリ -->
<property name="build.lib" value="lib" />

<!-- クラスファイルのディレクトリ -->
<property name="build.class" value="classes" />

<!-- Jarファイル名 -->
<property name="build.jar" value="sample.jar" />

<!--クラスパス(コンパイル時にも利用)-->
<path id="classpath">
  <fileset id = "class" dir="${build.lib}">
    <include name="*.jar"/>
  </fileset>
</path>

<!-- 実行可能JarファイルのClass-Path -->

<!-- 1.カレントディレクトリの絶対パス取得 -->
<pathconvert property="current.path">
  <path path="${base.dir}"/>
</pathconvert>
<!-- 2.区切り文字を"/"から半角スペースに置換 -->
<pathconvert pathsep=" " dirsep="/" property="jar.classpath" refid="classpath">
  <!-- ${classpath}のカレントディレクトリまでのパスを"."に置換 -->
  <map from="${current.path}" to="${base.dir}"/>
</pathconvert>

<!-- Jarファイル生成 -->
<target name="jar">
  <jar destfile="${build.jar}">
    <fileset dir="${build.class}"/>
    <!-- 3.Jarファイル内に設定ファイルを格納する -->
    <fileset dir="${build.lib}">
    <include name="*.properties"/>
  </fileset>
  <manifest>
    <attribute name="Main-Class" value="${main}"/>
    <attribute name="Class-Path" value="${jar.classpath}"/>
  </manifest>
  </jar>
</target>

こんな感じ。

まぁ、1とか2らへんは、いろんなサイトのパクリなんだけれども。

ちなみに、

「3.Jarファイル内に設定ファイルを格納する」ってところは

propertiesファイルをJarファイル内に含めたい時のみ必要。

ResourceBundleで例えると・・・

クラスローダからの取得の場合

// 実行可能Jarファイルにsample.propertiesを含める必要あり
ResourceBundle bundle = ResourceBundle.getBundle("sample");
// ↑は↓と同じ
// getBundle("sample", Locale.getDefault(), this.getClass().getClassLoader());

実行可能JarファイルのClass-Pathにpropertiesファイルへの相対パスを書いても

クラスローダが読み込んでくれないため(たぶん)、

アクセスできる外部ファイルはJarファイルやクラスファイルのみ。

無論、propertiesファイルを修正した場合、Jarファイルを生成しなおさなければならない。

が、propertiesファイルを違うディレクトリに移動される心配がない。

ソフトウェアの配布向け。

FileInputStreamからの取得の場合

// 実行可能Jarファイルにsample.propertiesを含める必要無し
InputStream in = new BufferedInputStream(new FileInputStream("sample.properties"));
ResourceBundle bundle = new PropertyResourceBundle(in);

FileInputStreamのファイルアクセス=OSのファイルシステムでのファイルアクセスであるため、

実行可能Jarファイルの外部のファイルに自由にアクセスできるが、

Jarファイル内へのファイルアクセス(?)はできない。

propertiesファイルの修正がVM再起動のみで反映される。

システム向け。

まぁ、ズラッと調子こいて書いたけども解釈が間違っている可能性有り。

なんせ、業界歴1年未満で勉強不足なので・・・(言い訳)

間違ってたら是非ともご指摘頂きたいと思います。

よろしくお願いします><

このエントリーをはてなブックマークに追加
comments powered by Disqus