質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.35%

  • Java

    14371questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • JAR

    95questions

    JAR(又はJava ARchive)はコンパイルされた複数のJavaバイトコード及び関連ファイルのリソースを一つのファイルに統合したものです。JARファイルはZIPファイルのフォーマットで構築されています。

Javaでresourcesに配置したテキストファイルがjar化すると読み込めません

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,522

cp0831

score 4

jar化した時にリソースの参照が出来ません。

1.EclipseでMavenプロジェクトを作成。(特にMavenに関係する事象では無いと思いますが)

2.src/main/resources配下にフォルダーを作成してテキストファイルを配置する。

3.リソースを読み込んでSystem.out.printlnする処理を作成。

このような状況で、Eclipseから実行すると正しくテキストファイルの中身が出力されるのですが、Eclipseでjarにエクスポートして実行すると、参照できず例外が発生します。

■ Eclipseで定義している内容とテスト実行してFile1.txtの中身が出力されている実行結果のイメージです。
イメージ説明

■ Jar化したファイルの中身を確認してFile1.txtが含まれていることを確認したうえで実行するとNull参照例外が発生した時のイメージです。

イメージ説明

ちなみに、"folder1/folder2/File1.txt"の部分を"resources/folder1/folder2/File1.txt"に変更してみたところ、逆の事象が発生しました。(Eclipseで実行したらNull参照で、Jarで実行したら正しく参照される)

jarから呼ばれているかどうかをコードの中で聞くのもどうかと思いますし、なにかやり方が間違っているのではないかと思っています。
何か、情報をお持ちの方がいらっしゃいましたら教えて頂けると幸いです。

※ 追記2018-04-23
指摘事項がありましたので、追記します

ソースコードについては以下のように記述しています。

package rsTest;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

public class Main {

    public static void main(String[] args) {
        try {

            StringBuffer sb = new StringBuffer();
            InputStream in = ClassLoader.getSystemResourceAsStream("folder1/folder2/File1.txt");
            InputStreamReader isr = new InputStreamReader(in, "UTF-8");
            BufferedReader br = new BufferedReader(isr);
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line + "\r\n");
            }
            br.close();
            in.close();
            System.out.println(sb.toString());
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


また、Jar化する手順については以下のとおりです。
1.パッケージエクスプローラでプロジェクトを選択して右クリックより「エクスポート」
2.「Java」=>「実行可能Jarファイル」を選択
3.起動構成とエクスポート先を指定し、ライブラリ処理で「生成されるJarに必須ライブラリを抽出」を指定して「完了」
イ![イメージ説明(7fe28d20d8ead40b0599995cee92f38e.png)

以上です。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • cp0831

    2018/04/24 11:41

    たびたびすみません。私の環境で確認したところ、Mavenプロジェクト作成時に「シンプルなプロジェクトの作成(アーキタイプ選択のスキップ)」にチェックしてプロジェクトを作成するとResourcesフォルダーが除外設定付きで作成されました。これが今回の事象の原因だと思われます。Eclipseの環境内であれば参照できてしまうところにややこしさが有りますが原因としては特定できたと思います。ありがとうございました。

    キャンセル

  • 退会済みユーザー

    退会済みユーザー

    2018/04/24 12:34

    私が試したときはプロジェクト作成後にビルドパスを手動で追加したので除外設定は初めから「(なし)」となっていました。

    キャンセル

  • cp0831

    2018/04/24 14:18

    了解しました。私が引っかかった原因がはっきりしました。ありがとう御座いました。

    キャンセル

回答 2

checkベストアンサー

+2

プロジェクトのビルドパス設定に原因があるようです。

画面を拝見したところ、src/main/resources以下が通常のフォルダアイコンになっていましたので、Javaのクラスパスから除外された設定です。

ビルドパス>ビルドパスの構成を開き、src/main/resourcesの除外設定に ** がなされていると、同様の現象、実行可能jarでエクスポートした際にビルドパスに含まれません。
この設定を除外すると、実行可能jarに含まれます。

イメージ説明

通常は除外設定は(なし)になりますが、一部のプロジェクト作成コマンドでは、この設定がデフォルトで ** (すべて除外)にしてあるものもあります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/04/24 11:43

    今回のケースではMavenプロジェクト作成時に「シンプルなプロジェクトの作成(アーキタイプ選択のスキップ)」にチェックしてプロジェクトを作成した場合が、このケースに該当したようです。
    ありがとうございました。

    キャンセル

  • 2018/04/24 14:16

    犯人はシンプルプロジェクト作成でしたか。(シンプルなハズなのに除外って何かヘンですよね。)

    キャンセル

  • 2018/04/24 14:20

    なんか、手順が沢山ありすぎて柔軟な反面問題点が分かりにくいですね。
    今回のは、EclipseでテストしてOKでもJar化してからもう一回流さないといけないのかと思って焦りましたが、微妙に他に内在している環境依存コードは無いのか微妙に不安です(笑)

    キャンセル

0

おそらくeclipse上で実行するか、jarとして実行するかで
ClassLoader.getResourceAsStream内で
基準となるパスが異なるのではないかと推察できます。

どういった方法が一般的かはわかりませんが、
方法のひとつとしてクラスパスからリソースを取得する方法があります。

以下にサンプルを示します。

検証環境
・OS     : windows7
・Java   : SE8
・eclipse: neon

検証手順
mavenプロジェクトを作成
Javaコードを下記のように編集
datas.propertiesを配置
eclipse上からmainを実行し、datas.propertiesの中身が出力されることを確認
mvn installしてjarを作成
コマンドラインから java -jar sample-1.0.0-jar-with-dependencies.jarを実行
datas.propertiesの中身が出力されることを確認

プロジェクト構成
sample
│
├─src
│  ├─main
│  │  ├─java
│  │  │  └─jp
│  │  │      └─co
│  │  │          └─panda
│  │  │              └─sample
│  │  │                      App.java
│  │  │
│  │  └─resources
│  │      └─jp
│  │          └─co
│  │              └─panda
│  │                  └─sample
│  │                          datas.properties
│  │
│  └─test
│      └─java
│          └─jp
│              └─co
│                  └─panda
│                      └─sampleAppTest.java
│
└─target
   ├─sample-1.0.0-jar-with-dependencies.jar
   └─sample-1.0.0.jar


※AppTestはユニットテスト用ファイルなので無視してください。

// App.java
package jp.co.panda.sample;

import java.util.ResourceBundle;

/**
 * エントリポイント
 *
 */
public class App {
    public static void main(String[] args) {
        ResourceBundle bundle = ResourceBundle.getBundle("jp.co.panda.sample.datas");
        for(String key : bundle.keySet()) {
            System.out.println(key + " -> " + bundle.getString(key));
        }
    }
}
#datas.properties
key1=value1
key2=value2
key3=value3
<!-- pom.xml -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>jp.co.panda</groupId>
    <artifactId>sample</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

    <name>sample</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.0.0</version>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <mainClass>jp.co.panda.sample.App</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

以上ご参考までに

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/04/19 00:46

    ちゃう、圧縮するときのコマンド mvn package じゃなく jar コマンドで間違えた圧縮してるせいだとおもうんぞ

    キャンセル

  • 2018/04/19 07:39

    ご指摘ありがとうございます
    なるほど、その観点はなかったです
    私の回答は参考程度にしてください

    ちなみに私のサンプルではプロパティファイルでやってるので、通常のテキストファイルでも動きが変わらないか試してみたいですね

    キャンセル

  • 2018/04/23 10:20

    ありがとうございます。
    プロパティファイルではなくテキストファイルが対象のため、Jar化の手順に間違いがあるのではないかと思っているところです。

    キャンセル

同じタグがついた質問を見る

  • Java

    14371questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • JAR

    95questions

    JAR(又はJava ARchive)はコンパイルされた複数のJavaバイトコード及び関連ファイルのリソースを一つのファイルに統合したものです。JARファイルはZIPファイルのフォーマットで構築されています。