2012-12-05 14 views
24

これは私が高く評価しており、これに対する答えは不十分であり、明らかに満足のいく回答は見つかりませんでした。jarコマンドで特定のディレクトリにあるJAR内のファイルを更新します

問題は、JAR内のJAR(またはそのようなファイル)をJAR内で更新したいのですが、このファイルはフォルダ構造内にあります。JARの外部では再生できないようにしたいのですそれ。

例:私はコマンドを使用して、これを更新する場合

Foo.jar (root directory) 
/
|->/folder1 
| 
|->/folder2 
| 
|->/foo 
    | 
    |-->/bar 
     | 
     |---->/baz 
       | 
       |------>file_to_update.jar 

だから、私が最初にJARの外側同じフォルダ構造を作成する必要があり、次に行う

jar -uf Foo.jar -C foo/bar/baz/file_to_update.jar 

しかし、私はこのフォルダ構造の作成を避けたいのですが、特定のファイルについてはかなり深いことがあります。また、コンテナJAR全体の選択したファイルを更新する必要があるかもしれないので、 ific構造のように、jarコマンドを使用してそれらを更新することができます。別の方法でそれを置くために

、私は特定のソースディレクトリ内の特定のソースファイルを使用して、特定の宛先ディレクトリ内の特定の宛先ファイルを更新するコマンドをお伝えしたいと思います。

I.e.

jar -uf Foo.jar -sourceFile /x/y/z/filetoupdate -destFile /a/b/c/filetoupdate 

(私はこの構文がうまくいかないことを知っていますが、私が必要とするものを例示するだけです)。

これはできますか?非常に奇妙であると私は打ち明けるでしょう。jarコマンドでは、フォルダ構造100内のファイルを更新する必要があるので、フォルダ構造全体を模倣する必要があります。フォルダは深い。それは単にファイルを更新するために再現するのは非常に複雑です。

また、私は通常のZIPユーティリティを使うことができると知っていますが、Linuxで利用できるものは、ファイルを更新していないということです(jarファイルを再オープンすると元のバージョンになります)今すぐ別の会社を探すことはできません(会社の方針、時間がない、問題をテストする、名前を付ける)。

最後に、これをコマンドラインから実行できれば、バッチファイルを作成して、フォルダ構造を作成せずにたくさんの特定のファイルを更新できることを意味します。

このJARは2GBまで上がることがあるので、私はunjar、更新、rejarを避けたいと言っていることを忘れてしまったので、これをちょうど少し行います私の巨大なJARへのリソースファイル。

これに関するお手伝いをしております。

+0

あなたがいることを言及Linuxで、あなたはすでにzipパッケージを調べていますか?マニュアルのための '' 'man zip'''。それはあなたが探しているツールだけで、自動化のためのスクリプトとペアリングしているようです。 – TomJ

答えて

5

4129445 : An API to incrementally update ZIP files Sun/Oracleのバグデータベースでは、この機能をjava apiに実装するように求められています。評価から

「誤って、持っている人に同情し、おそらく簡単になり、このバグを修正したい人に同情するのは簡単ですで使用中の既に上書きされたJARファイル。 JVMを実行しています。

「それは瓶&ジップAPIは初日から変更可能なzipファイルに許可されていた場合はよかった。しかし、この時点ではなくJava(またはから& zipファイルをジャーに可変性を追加し、増加しているだろうそれらを変えることの容易さ)はより困難なデバッグの問題を引き起こす可能性が高い」

+0

Eesh ...あまりにも長いショットのようです:/ – Acapulco

+5

正しい答えは以下を見てください。これはそのような時間の無駄です。 – Sorter

1

This previous discussionは、zip(またはjar)ファイルを更新するためのJavaソースコードを示しています。

jar -uを使用するよりも実際にこれが速くなるかどうかは完全にはわかりませんが、ディスク上にファイル構造を再作成する必要がないように、少なくともそのコードを適合させる必要があります。

編集:の 'jar'ユーティリティ - あなたが探している特定の動作が有用であるにもかかわらず、そこにはありません。

私は、コマンドラインインターフェイスは基本的にはUnix/Linuxの 'tar'コマンドのクローンだと思っています。もちろん、tarではなくzip形式を生成します。

編集#2 - ファイルをZIPに追加するには、ファイルの最後から中央のディレクトリを削除し、新しいエントリを追加してから、中央ディレクトリ。エントリをディレクトリに追加する代わりに、新しいディレクトリエントリを指すように既存のディレクトリエントリを更新します。

この可能性を探る中で、Java 7にはこれと同じように見えるzip file system providerが含まれていることがわかりました。

+0

参考にしていただきありがとうございます。私は実際にすでにそれを読んで、それを実装することを考えていました。しかし、私はまだ回避策ではなく、jarコマンドを使用して最終的な答えを探しています。このツールの開発者がそのような操作を許可していないというのは本当に不合理なようです。私はちょうどそれが実際に行えないことを確かめる(ドキュメンテーション、権威のあるソースなど)、そしておそらくなぜそうであるか(歴史的理由など)を望んでいる。私はこのような単純で便利な操作がコマンドにまだ実装されていないとは信じられません。これを望む多くのプログラマーがいなければなりません。 – Acapulco

+0

私は私を信じることができないので、私はそれを見るためにもう一組の目が必要だと思う。私はもちろん、投稿する前にドキュメントを読んだが、もう一度、私は何かが欠けていると思った。だからもう一度見てくれてありがとう。賞金終了時までに何も良いことがなければ、私はあなたの答えを受け入れるでしょう。 しかし、少しばかげても賞金をフルに活用したいと思っています。このシナリオをサポートするためにソースコードを変更する作業をしています。変更を受け入れることがどれほど難しいと思いますか?私はこれが役に立つかもしれない複数の方法を考えることができますおかげさまでもう一度! – Acapulco

+1

それは試してみる価値はありますが、受け入れるのが難しいと思います。受け入れられない場合は、ソースコードがオープンソースであるかどうかを確認してください。そうであれば、それをフォークし、変更して、変更を公開します。 – GreyBeardedGeek

39

受け入れ答えは、すでに指摘したように、あなたが使用することはできませんどちらzipや圧縮ファイル内の特定のディレクトリにファイルシステム上の特定のファイルを挿入するjarコマンド。

しかし、一言で言えば最初に圧縮されたファイル内の特定のファイルを抽出し、この回避策が、そこにある、あなたはそれを更新してから圧縮されたファイルに戻ってそれを置くことができます。

1.単一の抽出しますファイル:
のみhello.txtを抽出するには、以下の内容

$ jar tvf foo.jar 
0 Thu Jan 10 00:05:06 IST 2013 META-INF/ 
68 Thu Jan 10 00:05:06 IST 2013 META-INF/MANIFEST.MF 
0 Thu Jan 10 00:04:30 IST 2013 x/ 
0 Thu Jan 10 00:07:36 IST 2013 x/b/ 
9 Thu Jan 10 00:07:36 IST 2013 x/b/hello.txt 
0 Thu Jan 10 00:04:30 IST 2013 x/a/ 

とjarファイルを考えてみましょう、あなたは、ファイルへの抽出物の完全修飾パスを与える必要があります。 Jarは適切なフォルダも作成します。

例:

$ jar xvf foo.jar x/b/hello.txt 
inflated: x/b/hello.txt 

$ tree x/ 
x 
└── b 
    └── hello.txt 
1 directory, 1 file 

2.単一ファイル

  1. の更新は、抽出されたファイル
  2. 更新 'U' フラグを使用して、ジャーを変更します。展開されたディレクトリルートを提供すると、jarはその下にあるすべてのパス要素を更新します。

例:私はこれを試してみたjarファイルのバージョン

$ jar vfu foo.jar x/ 
adding: x/(in = 0) (out= 0)(stored 0%) 
adding: x/b/(in = 0) (out= 0)(stored 0%) 
adding: x/b/hello.txt(in = 23) (out= 11)(deflated 52%) 

3.?

私はここに述べたすべての手順を確認しているのFedora 17


にJDK 7にバンドルさjarを使用。お役に立てれば。

+0

これは確かに良い答えですが、私は上記のように回避策を探していませんでした。バッチスクリプトでさえ、確かにうまくいくかもしれませんが、私が賞金を始めた理由は、それが可能かどうかに決定的な答えを得ることです。今はそうではないことを知っていますし、回避策が唯一の選択肢です。いずれにしても、解決策を感謝します。これは私が言う最も真っ直ぐな前進の1つです。 – Acapulco

+0

あなたは素晴らしいです、ありがとう! – lorraine

+0

これは役に立ちました。最初は、私が更新しようとしていたファイルが代わりに削除されるため、ファイルが無視されているという出力があるため、動作していないと思っていました。しかし、これは私が更新していたファイルがMETA-INF/MANIFEST.MFだったからです。マニュアルページで説明したように、マニフェストファイルの削除を避けるには、オプションMを使用する必要があります。私はそれを行うときにこの答えに記載されているとおりに動作します。また、Cオプションを使用してjarファイルを一時的に更新したディレクトリに変更しました。私はOpenJDK Java 7とJava 8でテストしました。 – MidnightJava

1

これは、java.util.zipパッケージのクラスがどのように機能するかによると思います。 ストリームの上に座っています。

ZipFileクラスは、ZipFileInputStreamの上に構築されます。 ZIPファイルを書き込むには、ZipEntriesを1つずつZipOutputStreamに送ります。

jar実行ファイルがこれらのクラスの上に構築されていると仮定します。

0

また、jarのファイル構造をjarファイルの外部に再現せずにjarファイルを更新しようとしていましたが、何らかの理由でjar uf jarFileName -C ... commandというファイルがjarの子ディレクトリにコピーされることはありません。次に、ubuntu 14.04のアーカイブマネージャー(jarファイルを右クリックし、「アーカイブマネージャーで開く」を選択してjarのファイル構造内のどこにでもファイルを貼り付ける)を使用して、ジャーナルにファイルを切り貼りしてみました。 。それはcliソリューションではありませんが、動作します。これで誰か他の人が時間を節約できることを願っています。

-2

これは機能しますが、あなたが目にしているような解決策ではありません。代わりに、手動でフォルダ構造を作成するので

、私は、全体のパスを言及するよう要求していますので、MKDIRフォルダを作成し、サブディレクトリは、このことができますtoo.hopeます....

set /p Folder=where you want to move inside jar 
set /p File=Mention path of file to be moved 
set /p Jarfile=Where is your jar file 
mkdir %Folder% 
copy %File% %Folder% 
jar -uvf %Jarfile% %File% 
rd /s /q %Folder% 
rmdir %Folder% 
関連する問題