Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8335912: Add an operation mode to the jar command when extracting to not overwriting existing files #608

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion jdk/src/share/classes/sun/tools/jar/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,10 @@ class Main {
* iflag: generate jar index
* nflag: Perform jar normalization at the end
* pflag: preserve/don't strip leading slash and .. component from file name
* kflag: keep existing file
*
*/
boolean cflag, uflag, xflag, tflag, vflag, flag0, Mflag, iflag, nflag, pflag;
boolean cflag, uflag, xflag, tflag, vflag, flag0, Mflag, iflag, nflag, pflag, kflag;

static final String MANIFEST_DIR = "META-INF/";
static final String VERSION = "1.0";
Expand Down Expand Up @@ -397,6 +398,9 @@ boolean parseArgs(String args[]) {
case '0':
flag0 = true;
break;
case 'k':
kflag = true;
break;
case 'i':
if (cflag || uflag || xflag || tflag) {
usageError();
Expand Down Expand Up @@ -431,6 +435,10 @@ boolean parseArgs(String args[]) {
usageError();
return false;
}
if (kflag && !xflag) {
warn(formatMsg("warn.option.is.ignored", "k"));
}

/* parse file arguments */
int n = args.length - count;
if (n > 0) {
Expand Down Expand Up @@ -1058,6 +1066,12 @@ ZipEntry extractFile(InputStream is, ZipEntry e) throws IOException {
output(formatMsg("out.create", name));
}
} else {
if (f.exists() && kflag) {
if (vflag) {
output(formatMsg("out.kept", name));
}
return rc;
}
if (f.getParent() != null) {
File d = new File(f.getParent());
if (!d.exists() && !d.mkdirs() || !d.isDirectory()) {
Expand Down Expand Up @@ -1280,6 +1294,13 @@ protected void error(String s) {
err.println(s);
}

/**
* Print a warning message
*/
void warn(String s) {
err.println(s);
}

/**
* Main routine to start program.
*/
Expand Down
18 changes: 16 additions & 2 deletions jdk/src/share/classes/sun/tools/jar/resources/jar.properties
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ error.incorrect.length=\
incorrect length while processing: {0}
error.create.tempfile=\
Could not create a temporary file
warn.option.is.ignored=\
Warning: The {0} option is not valid with current usage, will be ignored.
out.added.manifest=\
added manifest
out.update.manifest=\
Expand All @@ -62,17 +64,22 @@ out.create=\
\ \ created: {0}
out.extracted=\
extracted: {0}
out.kept=\
\ \ skipped: {0} exists
out.inflated=\
\ inflated: {0}
out.size=\
(in = {0}) (out= {1})

usage=\
Usage: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\n\
Usage: jar {ctxui}[vfmn0PMek] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\n\
Options:\n\
\ \ -c create new archive\n\
\ \ -t list table of contents for archive\n\
\ \ -x extract named (or all) files from archive\n\
\ \ -x, Extract named (or all) files from the archive.\n\
\ \ If a file with the same name appears more than once in\n\
\ \ the archive, each copy will be extracted, with later copies\n\
\ \ overwriting (replacing) earlier copies unless 'k' is specified.\n\
\ \ -u update existing archive\n\
\ \ -v generate verbose output on standard output\n\
\ \ -f specify archive file name\n\
Expand All @@ -85,6 +92,13 @@ Options:\n\
\ \ -M do not create a manifest file for the entries\n\
\ \ -i generate index information for the specified jar files\n\
\ \ -C change to the specified directory and include the following file\n\
Operation modifiers valid only in extract mode:\n\
\ \ -k Do not overwrite existing files.\n\
\ \ If a Jar file entry with the same name exists in the target\n\
\ \ directory, the existing file will not be overwritten.\n\
\ \ As a result, if a file appears more than once in an\n\
\ \ archive, later copies will not overwrite earlier copies.\n\
\ \ Also note that some file system can be case insensitive.\n\
If any file is a directory then it is processed recursively.\n\
The manifest file name, the archive file name and the entry point name are\n\
specified in the same order as the 'm', 'f' and 'e' flags.\n\n\
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@ out.extracted=extrahiert: {0}
out.inflated=\ vergr\u00F6\u00DFert: {0}
out.size=(ein = {0}) (aus = {1})

usage=Verwendung: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] Dateien...\nOptionen:\n -c Neues Archiv erstellen\n -t Inhaltsverzeichnis f\u00FCr Archiv anzeigen\n -x Benannte (oder alle) Dateien aus dem Archiv extrahieren\n -u Vorhandenes Archiv aktualisieren\n -v Ausgabe im Verbose-Modus aus Standard-Ausgabe generieren\n -f Dateinamen f\u00FCr Archiv angeben\n -m Manifestinformationen aus angegebener Manifestdatei einschlie\u00DFen\n -n Pack200-Normalisierung nach Erstellung eines neuen Archivs ausf\u00FChren\n -e Anwendungseinstiegspunkt f\u00FCr Standalone-Anwendung angeben \n in einer ausf\u00FChrbaren JAR-Datei geb\u00FCndelt\n -0 Nur speichern; keine ZIP-Komprimierung verwenden\n -P Komponenten mit vorangestelltem "/" (absoluter Pfad) und ".." (\u00FCbergeordnetes Verzeichnis) aus Dateinamen beibehalten\n -M Keine Manifest-Datei f\u00FCr die Eintr\u00E4ge erstellen\n -i Indexinformationen f\u00FCr die angegebenen JAR-Dateien erstellen\n -C Zum angegebenen Verzeichnis wechseln und folgende Datei einschlie\u00DFen\nFalls eine Datei ein Verzeichnis ist, wird dieses rekursiv verarbeitet.\nDer Name der Manifestdatei, der Name der Archivdatei und der Name des Einstiegspunkts werden\nin derselben Reihenfolge wie die Kennzeichen "m", "f" und "e" angegeben.\n\nBeispiel 1: Archivieren Sie zwei Klassendateien in ein Archiv mit Namen "classes.jar": \n jar cvf classes.jar Foo.class Bar.class \nBeispiel 2: Verwenden Sie die vorhandenen Manifestdatei "mymanifest", und archivieren Sie alle\n Dateien im Verzeichnis foo/ directory in "classes.jar": \n jar cvfm classes.jar mymanifest -C foo/ .\n
usage=Verwendung: jar {ctxui}[vfmn0PMek] [jar-file] [manifest-file] [entry-point] [-C dir] Dateien...\nOptionen:\n -c Neues Archiv erstellen\n -t Inhaltsverzeichnis f\u00FCr Archiv anzeigen\n -x Benannte (oder alle) Dateien aus dem Archiv extrahieren\n -u Vorhandenes Archiv aktualisieren\n -v Ausgabe im Verbose-Modus aus Standard-Ausgabe generieren\n -f Dateinamen f\u00FCr Archiv angeben\n -m Manifestinformationen aus angegebener Manifestdatei einschlie\u00DFen\n -n Pack200-Normalisierung nach Erstellung eines neuen Archivs ausf\u00FChren\n -e Anwendungseinstiegspunkt f\u00FCr Standalone-Anwendung angeben \n in einer ausf\u00FChrbaren JAR-Datei geb\u00FCndelt\n -0 Nur speichern; keine ZIP-Komprimierung verwenden\n -P Komponenten mit vorangestelltem "/" (absoluter Pfad) und ".." (\u00FCbergeordnetes Verzeichnis) aus Dateinamen beibehalten\n -M Keine Manifest-Datei f\u00FCr die Eintr\u00E4ge erstellen\n -i Indexinformationen f\u00FCr die angegebenen JAR-Dateien erstellen\n -C Zum angegebenen Verzeichnis wechseln und folgende Datei einschlie\u00DFen\nFalls eine Datei ein Verzeichnis ist, wird dieses rekursiv verarbeitet.\nDer Name der Manifestdatei, der Name der Archivdatei und der Name des Einstiegspunkts werden\nin derselben Reihenfolge wie die Kennzeichen "m", "f" und "e" angegeben.\n\nBeispiel 1: Archivieren Sie zwei Klassendateien in ein Archiv mit Namen "classes.jar": \n jar cvf classes.jar Foo.class Bar.class \nBeispiel 2: Verwenden Sie die vorhandenen Manifestdatei "mymanifest", und archivieren Sie alle\n Dateien im Verzeichnis foo/ directory in "classes.jar": \n jar cvfm classes.jar mymanifest -C foo/ .\n
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@ out.extracted=extra\u00EDdo: {0}
out.inflated=\ inflado: {0}
out.size=(entrada = {0}) (salida = {1})

usage=Sintaxis: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\nOpciones:\n -c crear nuevo archivo\n -t crear la tabla de contenido del archivo\n -x extraer el archivo mencionado (o todos) del archivo\n -u actualizar archivo existente\n -v generar salida detallada de los datos de salida est\u00E1ndar\n -f especificar nombre de archivo de almacenamiento\n -m incluir informaci\u00F3n de manifiesto del archivo de manifiesto especificado\n -e especificar punto de entrada de la aplicaci\u00F3n para la aplicaci\u00F3n aut\u00F3noma \n que se incluye dentro de un archivo jar ejecutable\n -0 s\u00F3lo almacenar; no utilizar compresi\u00F3n ZIP\n -P conservar componentes iniciales '/' (ruta absoluta) y ".." (directorio principal) en los nombres de archivo\n -M no crear un archivo de manifiesto para las entradas\n -i generar informaci\u00F3n de \u00EDndice para los archivos jar especificados\n -C cambiar al directorio especificado e incluir el archivo siguiente\nSi alg\u00FAn archivo es un directorio, se procesar\u00E1 de forma recurrente.\nEl nombre del archivo de manifiesto, el nombre del archivo de almacenamiento y el nombre del punto de entrada se\nespecifican en el mismo orden que los indicadores 'm', 'f' y 'e'.\n\nEjemplo 1: para archivar archivos de dos clases en un archivo llamado classes.jar: \n jar cvf classes.jar Foo.class Bar.class \nEjemplo 2: utilice un archivo de manifiesto existente 'mymanifest' y archive todos los\n archivos del directorio foo/ en 'classes.jar': \n jar cvfm classes.jar mymanifest -C foo/ .\n
usage=Sintaxis: jar {ctxui}[vfmn0PMek] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\nOpciones:\n -c crear nuevo archivo\n -t crear la tabla de contenido del archivo\n -x extraer el archivo mencionado (o todos) del archivo\n -u actualizar archivo existente\n -v generar salida detallada de los datos de salida est\u00E1ndar\n -f especificar nombre de archivo de almacenamiento\n -m incluir informaci\u00F3n de manifiesto del archivo de manifiesto especificado\n -e especificar punto de entrada de la aplicaci\u00F3n para la aplicaci\u00F3n aut\u00F3noma \n que se incluye dentro de un archivo jar ejecutable\n -0 s\u00F3lo almacenar; no utilizar compresi\u00F3n ZIP\n -P conservar componentes iniciales '/' (ruta absoluta) y ".." (directorio principal) en los nombres de archivo\n -M no crear un archivo de manifiesto para las entradas\n -i generar informaci\u00F3n de \u00EDndice para los archivos jar especificados\n -C cambiar al directorio especificado e incluir el archivo siguiente\nSi alg\u00FAn archivo es un directorio, se procesar\u00E1 de forma recurrente.\nEl nombre del archivo de manifiesto, el nombre del archivo de almacenamiento y el nombre del punto de entrada se\nespecifican en el mismo orden que los indicadores 'm', 'f' y 'e'.\n\nEjemplo 1: para archivar archivos de dos clases en un archivo llamado classes.jar: \n jar cvf classes.jar Foo.class Bar.class \nEjemplo 2: utilice un archivo de manifiesto existente 'mymanifest' y archive todos los\n archivos del directorio foo/ en 'classes.jar': \n jar cvfm classes.jar mymanifest -C foo/ .\n
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@ out.extracted=extrait : {0}
out.inflated=\ d\u00E9compress\u00E9 : {0}
out.size=(entr\u00E9e = {0}) (sortie = {1})

usage=Syntaxe : jar {ctxui}[vfmn0PMe] [fichier-jar] [fichier-manifeste] [point-entr\u00E9e] [-C r\u00E9p] fichiers...\nOptions :\n -c cr\u00E9e une archive\n -t affiche la table des mati\u00E8res de l'archive\n -x extrait les fichiers nomm\u00E9s (ou tous les fichiers) de l'archive\n -u met \u00E0 jour l'archive existante\n -v g\u00E9n\u00E8re une version d\u00E9taill\u00E9e d'une sortie standard\n -f sp\u00E9cifie le nom du fichier archive\n -m inclut les informations de manifeste \u00E0 partir du fichier manifeste sp\u00E9cifi\u00E9\n -n effectue une normalisation Pack200 apr\u00E8s la cr\u00E9ation d'une archive\n -e sp\u00E9cifie le point d'entr\u00E9e d'une application en mode autonome \n int\u00E9gr\u00E9e \u00E0 un fichier JAR ex\u00E9cutable\n -0 stockage uniquement, pas de compression ZIP\n -P pr\u00E9serve les signes de d\u00E9but '/' (chemin absolu) et ".." (r\u00E9pertoire parent) dans les noms de fichier\n -M ne cr\u00E9e pas de fichier manifeste pour les entr\u00E9es\n -i g\u00E9n\u00E8re les informations d'index des fichiers JAR sp\u00E9cifi\u00E9s\n -C passe au r\u00E9pertoire sp\u00E9cifi\u00E9 et inclut le fichier suivant\nSi l'un des fichiers est un r\u00E9pertoire, celui-ci est trait\u00E9 r\u00E9cursivement.\nLes noms du fichier manifeste, du fichier archive et du point d'entr\u00E9e sont\nsp\u00E9cifi\u00E9s dans le m\u00EAme ordre que celui des indicateurs m, f et e.\n\nExemple 1 : pour archiver deux fichiers de classe dans une archive intitul\u00E9e classes.jar : \n jar cvf classes.jar Foo.class Bar.class \nExemple 2 : pour utiliser un fichier manifeste existant 'monmanifeste', puis archiver tous les\n fichiers du r\u00E9pertoire foo/ dans 'classes.jar' : \n jar cvfm classes.jar monmanifeste -C foo/ .\n
usage=Syntaxe : jar {ctxui}[vfmn0PMek] [fichier-jar] [fichier-manifeste] [point-entr\u00E9e] [-C r\u00E9p] fichiers...\nOptions :\n -c cr\u00E9e une archive\n -t affiche la table des mati\u00E8res de l'archive\n -x extrait les fichiers nomm\u00E9s (ou tous les fichiers) de l'archive\n -u met \u00E0 jour l'archive existante\n -v g\u00E9n\u00E8re une version d\u00E9taill\u00E9e d'une sortie standard\n -f sp\u00E9cifie le nom du fichier archive\n -m inclut les informations de manifeste \u00E0 partir du fichier manifeste sp\u00E9cifi\u00E9\n -n effectue une normalisation Pack200 apr\u00E8s la cr\u00E9ation d'une archive\n -e sp\u00E9cifie le point d'entr\u00E9e d'une application en mode autonome \n int\u00E9gr\u00E9e \u00E0 un fichier JAR ex\u00E9cutable\n -0 stockage uniquement, pas de compression ZIP\n -P pr\u00E9serve les signes de d\u00E9but '/' (chemin absolu) et ".." (r\u00E9pertoire parent) dans les noms de fichier\n -M ne cr\u00E9e pas de fichier manifeste pour les entr\u00E9es\n -i g\u00E9n\u00E8re les informations d'index des fichiers JAR sp\u00E9cifi\u00E9s\n -C passe au r\u00E9pertoire sp\u00E9cifi\u00E9 et inclut le fichier suivant\nSi l'un des fichiers est un r\u00E9pertoire, celui-ci est trait\u00E9 r\u00E9cursivement.\nLes noms du fichier manifeste, du fichier archive et du point d'entr\u00E9e sont\nsp\u00E9cifi\u00E9s dans le m\u00EAme ordre que celui des indicateurs m, f et e.\n\nExemple 1 : pour archiver deux fichiers de classe dans une archive intitul\u00E9e classes.jar : \n jar cvf classes.jar Foo.class Bar.class \nExemple 2 : pour utiliser un fichier manifeste existant 'monmanifeste', puis archiver tous les\n fichiers du r\u00E9pertoire foo/ dans 'classes.jar' : \n jar cvfm classes.jar monmanifeste -C foo/ .\n
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@ out.extracted=estratto: {0}
out.inflated=\ decompresso: {0}
out.size=(in = {0}) (out = {1})

usage=Uso: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\nOpzioni:\n -c crea un nuovo archivio\n -t visualizza l'indice dell'archivio\n -x estrae i file con nome (o tutti i file) dall'archivio\n -u aggiorna l'archivio esistente\n -v genera output commentato dall'output standard\n -f specifica il nome file dell'archivio\n -m include informazioni manifest dal file manifest specificato\n -n esegue normalizzazione Pack200 dopo la creazione di un nuovo archivio\n -e specifica il punto di ingresso per l'applicazione stand-alone \n inclusa nel file jar eseguibile\n -0 solo memorizzazione; senza compressione ZIP\n -P conserva i componenti iniziali '/' (percorso assoluto) e \\"..\\" (directory padre) dai nomi file\n -M consente di non creare un file manifest per le voci\n -i genera informazioni sull'indice per i file jar specificati\n -C imposta la directory specificata e include il file seguente\nSe un file \u00E8 una directory, verr\u00E0 elaborato in modo ricorsivo.\nIl nome del file manifest, del file di archivio e del punto di ingresso devono\nessere specificati nello stesso ordine dei flag 'm', 'f' ed 'e'.\n\nEsempio 1: archiviazione di due file di classe in un archivio con il nome classes.jar: \n jar cvf classes.jar Foo.class Bar.class \nEsempio 2: utilizzo del file manifest esistente 'mymanifest' e archiviazione di tutti i\n file della directory foo/ in 'classes.jar': \n jar cvfm classes.jar mymanifest -C foo/ .\n
usage=Uso: jar {ctxui}[vfmn0PMek] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\nOpzioni:\n -c crea un nuovo archivio\n -t visualizza l'indice dell'archivio\n -x estrae i file con nome (o tutti i file) dall'archivio\n -u aggiorna l'archivio esistente\n -v genera output commentato dall'output standard\n -f specifica il nome file dell'archivio\n -m include informazioni manifest dal file manifest specificato\n -n esegue normalizzazione Pack200 dopo la creazione di un nuovo archivio\n -e specifica il punto di ingresso per l'applicazione stand-alone \n inclusa nel file jar eseguibile\n -0 solo memorizzazione; senza compressione ZIP\n -P conserva i componenti iniziali '/' (percorso assoluto) e \\"..\\" (directory padre) dai nomi file\n -M consente di non creare un file manifest per le voci\n -i genera informazioni sull'indice per i file jar specificati\n -C imposta la directory specificata e include il file seguente\nSe un file \u00E8 una directory, verr\u00E0 elaborato in modo ricorsivo.\nIl nome del file manifest, del file di archivio e del punto di ingresso devono\nessere specificati nello stesso ordine dei flag 'm', 'f' ed 'e'.\n\nEsempio 1: archiviazione di due file di classe in un archivio con il nome classes.jar: \n jar cvf classes.jar Foo.class Bar.class \nEsempio 2: utilizzo del file manifest esistente 'mymanifest' e archiviazione di tutti i\n file della directory foo/ in 'classes.jar': \n jar cvfm classes.jar mymanifest -C foo/ .\n
Loading