[JAVA] Comment modifier le contenu du fichier jar sans décompresser

introduction

Dans mon travail de projet Java, j'ai construit le code source sous forme de fichier jar et je l'ai déployé sur le serveur. Lorsque je voulais réécrire le contenu du fichier jar déployé pour le test, je me suis un peu bloqué, donc je vais écrire la solution ici.

Dans cet article, nous utiliserons le projet de framework Spring comme exemple. Le répertoire lors de la décompression du fichier jar est le suivant.

┣ BOOT-INF/
  ┣ classes
    ┗ application.properties <- *Je veux réécrire ce fichier*
  ┗ lib
    ┗ {Pot de la bibliothèque que vous utilisez}
┣ META-INF/
  ┣ maven/
    ┗ {pom.xml}
  ┗ MANIFEST.MF <-Fichier manifeste
┗ org/
  ┗ {Dossier de classe complet}

Plus précisément, j'ai essayé de réécrire / BOOT-INF / classes / application.properties et cela a échoué.

Exemple d'échec

Décompressez puis durcissez avec la commande zip

Le fichier jar est pratiquement le même que le fichier zip, j'ai donc décompressé le fichier jar avec la commande zip, modifié le fichier et essayé de le reconditionner avec la commande zip.

Lorsque j'ai essayé de démarrer l'application avec la commande java -jar basée sur le fichier résultant, j'ai eu l'erreur suivante.

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

Comme le message d'erreur dit «les fichiers jar imbriqués doivent être stockés sans compression», les fichiers jar des bibliothèques sous «BOOT-INF / lib» ont été compressés (?) Et ils n'ont pas été lus comme des fichiers jar. Il semble.

Décompressez et recréez avec la commande jar

Si la simple commande zip ne fonctionne pas, essayez de créer un fichier jar avec la commande jar.

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

Lorsque j'ai essayé de le démarrer en fonction du fichier jar créé par la commande ci-dessus, j'ai eu l'erreur suivante.

no main manifest attribute, in xxx.jar

J'ai spécifié le fichier manifeste comme option, mais il ne semble pas se charger correctement (la cause directe de ce phénomène n'est pas résolue).

Succès

Remplacez le contenu par la commande zip sans décompresser

En réécrivant le contenu sans décompresser le fichier jar, le problème ci-dessus a été résolu.

Tout d'abord, reproduisez le fichier que vous souhaitez réécrire et le répertoire où il se trouve dans votre emplacement local. Je voulais réécrire le fichier BOOT-INF / classes / application.properties cette fois, donc je vais le créer.

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

Après avoir réécrit ce fichier local ʻapplication.properties, incluez-le dans le zip. Apportez le fichier zip (xxx.jar`) que vous souhaitez importer dans le même répertoire et importez-le avec la commande suivante.

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

Le fichier jar résultant a pu fonctionner sans aucun problème, probablement parce qu'il n'avait jamais été décompressé.

Au fait

Voici comment réécrire le contenu du fichier jar. Si vous voulez simplement le voir au lieu de réécrire le contenu, vous pouvez le voir avec la commande suivante.

jar tf xxx.jar

Mon patron s'est mis en colère lorsque je décompressais le fichier jar pour en vérifier le contenu.

Recommended Posts

Comment modifier le contenu du fichier jar sans décompresser
[chown] Comment changer le propriétaire d'un fichier ou d'un répertoire
JAVA: jar, aar, affichez le contenu du fichier
Personnalisez la répartition du contenu de Recyclerview
[Rails] Comment changer le nom de colonne de la table
[Rails] Comment obtenir le contenu des paramètres forts
Comment déboguer le fichier jar généré avec Eclipse
Comment modifier la valeur de réglage de Springboot Hikari CP
[Ruby] Comment récupérer le contenu du double hachage
Comment ajouter des éléments sans spécifier la longueur du tableau
[Swift] Comment modifier dynamiquement la hauteur de la barre d'outils sur le clavier
Comment créer un fichier jar et un fichier war à l'aide de la commande jar
[Rails] Comment changer le titre de la page du navigateur pour chaque page
Comment vérifier le contenu de la chaîne de caractères java de longueur fixe
Comment obtenir la longueur d'un fichier audio avec Java
[Java] Comment utiliser la classe File
Comment ajouter un fichier jar dans ScalaIDE
Comment déterminer le nombre de parallèles
Comment trier une liste de SelectItems
Comment modifier le nombre maximum et maximum de données POST dans Spark
Comment savoir quelle version Java d'un fichier de classe a été compilée
Comment changer la valeur d'une variable à un point d'arrêt dans intelliJ
[swift5] Comment changer la couleur de TabBar ou la couleur de l'élément de TabBar avec le code
Comment trouver la cause de l'erreur Ruby
Je veux var_dump le contenu de l'intention
Comment obtenir le jour d'aujourd'hui
Changer le fuseau horaire du conteneur https-portal en JST
Renommez le nom du package d'un fichier jar existant
Sortie de la façon d'utiliser la méthode slice
Double-cliquez pour ouvrir le fichier jar sous Windows
Comment les microservices changent la façon de développer des applications
Comment afficher le résultat du remplissage du formulaire
[Spring Boot] Comment se référer au fichier de propriétés
Comment définir des variables d'environnement dans le fichier de propriétés de l'application Spring Boot
Je veux voir le contenu de Request sans dire quatre ou cinq
[Java] Comment obtenir l'URL de la source de transition
Comment changer l'action avec plusieurs boutons d'envoi
Comment supprimer / mettre à jour le champ de liste de OneToMany
[Java] Comment extraire le nom du fichier du chemin
[Ruby on Rails] Comment changer le nom de la colonne
Tester le contenu d'un fichier Excel avec JUnit
[Java] Comment obtenir la valeur maximale de HashMap
JavaFX-Spécifiez l'emplacement du fichier CSS par rapport au fichier fxml
[Java] Récupère le fichier dans le fichier jar quel que soit l'environnement
Comment juger le clic de n'importe quelle zone de l'image
Java: utilisez Stream pour trier le contenu d'une collection
Comment télécharger une ancienne version d'Apache Tomcat
[Swift] Comment obtenir l'ID de document Firebase
Si vous utilisez SQLite avec VSCode, utilisez l'extension (comment voir le fichier binaire de sqlite3)
Comment utiliser git avec la puissance de jgit dans un environnement sans commandes git