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

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

新規登録して質問してみよう
ただいま回答率
85.37%
JAR

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

Java

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

Q&A

解決済

2回答

26295閲覧

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

cp0831

総合スコア11

JAR

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

Java

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

0グッド

0クリップ

投稿2018/04/18 12:33

編集2018/04/23 01:17

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)

以上です。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KSwordOfHaste

2018/04/18 13:17

ソースを画像で貼り付けちゃうとちょこっとコピペして試してみようという気がおきなくなります。できるだけコピペできるようコードタグで囲んで質問文に書いた方がよいと思います。
退会済みユーザー

退会済みユーザー

2018/04/18 23:01 編集

jar 圧縮の手順を質問へ追記してください
退会済みユーザー

退会済みユーザー

2018/04/18 17:26

見た目では「src/main/resources/」がビルドパスに入っているようなので、Eclipseの「Export -> JAR file」で「folder1/」以下がjarファイルに入るはずです。エクスポートの手順を教えてください。
cp0831

2018/04/23 01:18

遅くなりましたが情報追記しました。ご確認いただけると幸いです。
退会済みユーザー

退会済みユーザー

2018/04/23 08:51

Eclipse Oxygen.3 で同じようなプロジェクトを作成してみましたが問題ありませんでした。ただしfolder1とfolder2のアイコンが違っています。私は「src/main/resources」の下にパッケージ「folder1.folder2」を作成し、その下に「File1.txt」を作成しました。folder1、folder2はどうやって作ったのでしょうか?
cp0831

2018/04/24 02:26

saka1029さん。情報ありがとうございます。こちらでも試してみたのですが、パッケージとして作成してもフォルダーとして作成してもアイコンはフォルダーのもので動作は変わりませんでした。A-pZさんの投稿にある様にビルドパスから除外設定を除去すると思ったようにEclipseからもJarにしてからも同じ方法"folder1/folder2/File1.txt"で正しくアクセスできることを確認しました。saka1029さんの環境ではビルドパスの除外設定の除去を行われた環境なのでしょうか?だとすると、リソース参照する場合はビルドの除外設定を外すというのでストーリーが一致するのですが、如何でしょう?
cp0831

2018/04/24 02:27

ちなみに、ビルドパスから除外設定を除去するとアイコンはフォルダーからパッケージのものに変わりました
cp0831

2018/04/24 02:41

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

退会済みユーザー

2018/04/24 03:34

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

2018/04/24 05:18

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

回答2

0

ベストアンサー

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

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

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

イメージ説明

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

投稿2018/04/23 13:20

A-pZ

総合スコア12011

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cp0831

2018/04/24 02:43

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

2018/04/24 05:16

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

2018/04/24 05:20

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

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 │ └─sample │ AppTest.java │ └─target ├─sample-1.0.0-jar-with-dependencies.jar └─sample-1.0.0.jar

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

java

1// App.java 2package jp.co.panda.sample; 3 4import java.util.ResourceBundle; 5 6/** 7 * エントリポイント 8 * 9 */ 10public class App { 11 public static void main(String[] args) { 12 ResourceBundle bundle = ResourceBundle.getBundle("jp.co.panda.sample.datas"); 13 for(String key : bundle.keySet()) { 14 System.out.println(key + " -> " + bundle.getString(key)); 15 } 16 } 17}
#datas.properties key1=value1 key2=value2 key3=value3

xml

1<!-- pom.xml --> 2<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4 <modelVersion>4.0.0</modelVersion> 5 6 <groupId>jp.co.panda</groupId> 7 <artifactId>sample</artifactId> 8 <version>1.0.0</version> 9 <packaging>jar</packaging> 10 11 <name>sample</name> 12 <url>http://maven.apache.org</url> 13 14 <properties> 15 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 16 </properties> 17 18 <dependencies> 19 <dependency> 20 <groupId>junit</groupId> 21 <artifactId>junit</artifactId> 22 <version>3.8.1</version> 23 <scope>test</scope> 24 </dependency> 25 </dependencies> 26 <build> 27 <plugins> 28 <plugin> 29 <artifactId>maven-assembly-plugin</artifactId> 30 <version>3.0.0</version> 31 <executions> 32 <execution> 33 <id>make-assembly</id> 34 <phase>package</phase> 35 <goals> 36 <goal>single</goal> 37 </goals> 38 </execution> 39 </executions> 40 <configuration> 41 <descriptorRefs> 42 <descriptorRef>jar-with-dependencies</descriptorRef> 43 </descriptorRefs> 44 <archive> 45 <manifest> 46 <mainClass>jp.co.panda.sample.App</mainClass> 47 </manifest> 48 </archive> 49 </configuration> 50 </plugin> 51 </plugins> 52 </build> 53</project> 54

以上ご参考までに

投稿2018/04/18 15:19

編集2018/04/18 15:28
pandaNO12

総合スコア19

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/04/18 15:46

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

2018/04/18 22:39

ご指摘ありがとうございます なるほど、その観点はなかったです 私の回答は参考程度にしてください ちなみに私のサンプルではプロパティファイルでやってるので、通常のテキストファイルでも動きが変わらないか試してみたいですね
cp0831

2018/04/23 01:20

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問