LoginSignup
8
5

More than 3 years have passed since last update.

jarファイルの中身を、解凍せずに変更する方法メモ

Last updated at Posted at 2020-10-11

はじめに

Javaのプロジェクトの仕事の中で、ソースコードをjarファイルとしてビルドをして、それをサーバーにデプロイしていました。そのデプロイされたjarファイルの中身をテスト用に書き換えたくなった時に、少し嵌ったのでここに解決方法をメモしておきます。

尚、本記事ではSpringフレームワークのプロジェクトを例として扱います。jarファイルの解凍時のディレクトリは、以下のようになっています。

┣ BOOT-INF/
  ┣ classes
    ┗ application.properties <- *このファイルを書き換えたい*
  ┗ lib
    ┗ {使用してるライブラリのjar}
┣ META-INF/
  ┣ maven/
    ┗ {pom.xmlとか}
  ┗ MANIFEST.MF <- マニフェストファイル
┗ org/
  ┗ {classファイルがいっぱい}

具体的には、/BOOT-INF/classes/application.propertiesを書き換えようとして、失敗しました。

失敗例

解凍してから、zipコマンドで固める

jarファイルは実質的にはzipファイルと変わらないので、zipコマンドでjarファイルを解凍して、ファイルを修正し、再度zipコマンドで固め直そうとしました。

この結果できたファイルを基にアプリをjava -jarコマンドで起動しようとすると、以下のエラーが出ました。

Exception in thread "main" java.lang.IllegalStateException: Failed to get nested archive for entry BOOT-INF/lib/bcpkix-jdk15on-1.60.jar
        at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchive(JarFileArchive.java:108)
        at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchives(JarFileArchive.java:86)
        at org.springframework.boot.loader.ExecutableArchiveLauncher.getClassPathArchives(ExecutableArchiveLauncher.java:70)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:49)
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)
Caused by: java.io.IOException: Unable to open nested jar file 'BOOT-INF/lib/bcpkix-jdk15on-1.60.jar'
        at org.springframework.boot.loader.jar.JarFile.getNestedJarFile(JarFile.java:256)
        at org.springframework.boot.loader.jar.JarFile.getNestedJarFile(JarFile.java:241)
        at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchive(JarFileArchive.java:103)
        ... 4 more
Caused by: java.lang.IllegalStateException: Unable to open nested entry 'BOOT-INF/lib/bcpkix-jdk15on-1.60.jar'. It has been compressed and nested jar files must be stored without compression. Please check the mechanism used to create your executable jar file
        at org.springframework.boot.loader.jar.JarFile.createJarFileFromFileEntry(JarFile.java:284)
        at org.springframework.boot.loader.jar.JarFile.createJarFileFromEntry(JarFile.java:264)
        at org.springframework.boot.loader.jar.JarFile.getNestedJarFile(JarFile.java:252)
        ... 6 more

エラーメッセージにnested jar files must be stored without compressionとある通り、BOOT-INF/lib以下のライブラリのjarファイル群を圧縮してしまったことで(?)うまくjarファイルとして読み込まれなかったようです。

解凍してから、jarコマンドで再作成

単純なzipコマンドでダメなら、jarコマンドでjarファイルの作成を試みてみます。

jar cvfm xxx.jar ./META-INF/MANIFEST.MF ./

上のコマンドで作成したjarファイルを基に起動しようとすると、以下のエラーが出ました。

no main manifest attribute, in xxx.jar

ちゃんとオプションでマニフェストファイルを指定しているのに、上手く読み込まれていないようです(この現象の直接的な原因は、未解決です)。

成功例

zipコマンドで、解凍せずに中身を入れ替える

jarファイルを解凍せずに中身を書き換えることで、上記の問題をクリアしました。

まず、作業しているローカルの場所で、書き換えたいファイルとそれが置かれているディレクトリを再現します。
私は今回BOOT-INF/classes/application.propertiesというファイルを書き換えたかったので、それを作ります。

mkdir -p BOOT-INF/classes && touch ./BOOT-INF/classes/application.properties

このローカルのapplication.propertiesファイルを書き換えたら、それをzipに取り込みます。
取り込みたいzipファイル(xxx.jar)を同ディレクトリに持ってきて、以下のコマンドで取り込みます。

zip ./xxx.jar ./BOOT-INF/classes/MANIFEST.MF

この結果できたjarファイルは、一度も解凍してないためかエラーが起こらず、問題なく動かすことができました。

ついでに

上に記したのは、jarファイルの中身を書き換える方法でした。
中身を書き換えるのではなく、ただ見るだけであれば、以下のコマンドで見れます。

jar tf xxx.jar

中身を確認するためにわざわざjarファイルを解凍していたら、上司に怒られました。

8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5