web-dev-qa-db-ja.com

実行中のjarファイルに関連するファイルのロード

質問はそれをすべて言います。

私の場合の専門は、現在の作業ディレクトリがjarファイルの場所ではなく、_c:\Windows\system32_(私のjarファイルは、右クリックメニューを使用してWindowsによって開始されるため、フォルダのパスをとして渡したいことです。 jarへのパラメータ)。

ここで、jarと同じフォルダーにある_config.xml_という構成ファイルをロードします。もちろん、ファイルの目的はjarの設定を提供することです。簡単に編集できるように、xmlファイルがjarファイルのoutsideであることが重要です。

そのファイルをロードするのに苦労しています。 Windowsは行を実行します

_cmd /k Java -jar D:\pathToJarfile\unpacker-0.0.1-SNAPSHOT-jar-with-dependencies.jar
_

_cmd /k_を使用してすべてを呼び出すと、Windowsコマンドのプロンプトが開いたままになり、jarの出力を確認できます。

相対パスにnew File(".")またはSystem.getProperty("user.dir")を使用することはできません。これらの関数は、それぞれ_C:\Windows\system32\._および_C:\Windows\system32_(Windowsが実行するすべての作業フォルダー)を返すためです。私の知る限り)。

Launcher.class.getResourceAsStream("/../config.xml")でも成功していません。そのパスは_/_で始まるため、検索はjarのルートノードから始まります。 _../config.xml_に移動すると、そのファイルを正確に指しますが、呼び出しはnullを返します。

誰かが私を正しい方向に向けることができますか?私は本当にここで立ち往生しています。このファイルの読み込みは、毎回本当にバグがあります...

自分での要件:

  • Javaソースコードでパスをハードコーディングしたくない
  • ファイルのパスをパラメーターとして_Java -jar_呼び出しに渡したくない(main(String[] args)へのパラメーターとしても_-Dpath=d:\..._を使用してシステムプロパティを設定することもしない)

元の問題に加えて、_Class-Path: ._を使用するときに、maven2が_MANIFEST.MF_を_jar-with-dependencies_(BalusCが投稿したソリューション)に配置するのに苦労しました。問題は、その行が通常のjarのMANIFESTファイルに表示されたが、jar-with-dependencies.jarのMANIFESTファイルには表示されなかったことでした(2つのjarファイルが生成されます)。私がそれをどのようにしたかを気にする人のために:

_<plugin>
    <artifactId>maven-Assembly-plugin</artifactId>
    <version>2.2-beta-5</version>
    <configuration>
      <archive>
        <manifest>
          <mainClass>${mainClass}</mainClass>
          <addClasspath>true</addClasspath>
          <!--at first, i tried to place the Class-Path entry
              right here using <manifestEntries>. see below -->
        </manifest>
      </archive>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
    </configuration>
    <executions>
      <execution>
        <goals>
          <goal>attached</goal>
        </goals>
        <phase>package</phase>
        <configuration>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
          <archive>
            <manifest>
              <mainClass>${mainClass}</mainClass>
            </manifest>
            <!--this is the correct placement -->
            <manifestEntries>
              <Class-Path>.</Class-Path>
            </manifestEntries>
          </archive>
        </configuration>
      </execution>
    </executions>
  </plugin>
_
14
f1sh

Launcher.class.getResourceAsStream("/../config.xml")を機能させるには、JARのClass-PathファイルのMANIFEST.MFエントリにパスを追加する必要があります。これは通常の方法です。

6
BalusC

Class.getProtectionDomain() を使用した1つの可能な解決策は次のとおりです。

final Class<?> referenceClass = YourMainClass.class;
final URL url =
    referenceClass.getProtectionDomain().getCodeSource().getLocation();

try{
    final File jarPath = new File(url.toURI()).getParentFile();
    System.out.println(jarPath); // this is the path you want 
} catch(final URISyntaxException e){
    // etc.
}

YourMainClassは、jar内の任意のクラスに置き換えることができます。


Class.getProtectionDomain() ドキュメントから:

Returns the ProtectionDomain of this class.
If there is a security manager installed, this method first calls
the security manager's checkPermission method with a
RuntimePermission("getProtectionDomain") permission to ensure it's
ok to get the ProtectionDomain.

Returns:
  the ProtectionDomain of this class
Throws:
  SecurityException - if a security manager exists and its
  checkPermission method doesn't allow getting the ProtectionDomain.
12