Fichier JAR invalide ou corrompu construit par Maven shade plugin
après avoir ajouté la dépendance Maven jFree à mon application existante, Je ne suis pas capable d'exécuter le jar créé.
Le seul message d'erreur que j'obtiens est le suivant:
java -jar target/com.company.product-1.0.0-SNAPSHOT.jar
Error: Invalid or corrupt jarfile target/com. company.product-1.0.0-SNAPSHOT.jar
complet pom.xml
ressemble à ceci:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion
<groupId>com.mycompany</groupId>
<artifactId>com.mycompany.test</artifactId>
<name>${project.artifactId}</name>
<version>1.0.0-SNAPSHOT</version>
<properties>
<java-version>1.7</java-version>
<org.springframework-version>3.1.1.RELEASE</org.springframework-version>
<org.springframework.data-version>1.0.3.RELEASE</org.springframework.data-version>
<org.springframework.ws-version>2.0.4.RELEASE</org.springframework.ws-version>
<org.springframework.ws.oxm-version>1.5.10</org.springframework.ws.oxm-version>
<org.aspectj-version>1.6.12</org.aspectj-version>
<org.slf4j-version>1.5.10</org.slf4j-version>
<selenium-java-version>2.25.0</selenium-java-version>
<browser-mob-version>2.0-beta-6</browser-mob-version>
</properties>
<dependencies>
<!-- Hint A: If we delete this dependency it works -->
<dependency>
<groupId>org.jfree</groupId>
<artifactId>jfreechart</artifactId>
<version>1.0.14</version>
<exclusions>
<exclusion>
<artifactId>itext</artifactId>
<groupId>com.lowagie</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.3.2</version>
</dependency>
<dependency>
<groupId>de.schlichtherle.io</groupId>
<artifactId>truezip</artifactId>
<version>6.6</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>apache-log4j-extras</artifactId>
<version>1.1</version>
</dependency>
<!-- Caching with ehcache -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.5.2</version>
<type>pom</type>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>3.0.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.0.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>3.0.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework-version}</version>
<scope>test</scope>
</dependency>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate.java-persistence</groupId>
<artifactId>jpa-api</artifactId>
<version>2.0-cr-1</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.5.1-Final</version>
</dependency>
<!-- Database Connectors (HSQL should be removed later) -->
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>1.8.0.7</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.16</version>
</dependency>
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<!-- @Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- Spring Data JPA dependencies -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>${org.springframework.data-version}</version>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-oxm</artifactId>
<version>${org.springframework.ws.oxm-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-xml</artifactId>
<version>${org.springframework.ws-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-core</artifactId>
<version>${org.springframework.ws-version}</version>
</dependency>
<dependency>
<groupId>javax.xml</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>javax.xml</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.1</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.0</version>
<scope>test</scope>
</dependency>
<!-- Common Utils -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.2</version>
</dependency>
<!-- Selenium -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>${selenium-java-version}</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-firefox-driver</artifactId>
<version>${selenium-java-version}</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-chrome-driver</artifactId>
<version>${selenium-java-version}</version>
</dependency>
<!-- CSV Lib for Keyword Checker -->
<dependency>
<groupId>net.sf.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>2.0</version>
</dependency>
<!-- Google Places API -->
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>1.10.3-beta</version>
<exclusions>
<exclusion>
<artifactId>jackson-core-asl</artifactId>
<groupId>org.codehaus.jackson</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client-appengine</artifactId>
<version>1.10.3-beta</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.9</version>
</dependency>
<!-- Google Geocode -->
<dependency>
<groupId>com.google.code.geocoder-java</groupId>
<artifactId>geocoder-java</artifactId>
<version>0.9</version>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>net.sf.jgrapht</groupId>
<artifactId>jgrapht</artifactId>
<version>0.8.3</version>
</dependency>
<dependency>
<groupId>jgraph</groupId>
<artifactId>jgraph</artifactId>
<version>5.13.0.0</version>
</dependency>
<!-- Apache Http Client -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.2.1</version>
</dependency>
<!-- Amazon web services client -->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.2.15</version>
<exclusions>
<exclusion>
<artifactId>jackson-core-asl</artifactId>
<groupId>org.codehaus.jackson</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- Docx4j - reading excel files -->
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j</artifactId>
<version>2.8.0</version>
</dependency>
<!-- Browser Mob Proxy -->
<dependency>
<groupId>biz.neustar</groupId>
<artifactId>browsermob-proxy</artifactId>
<version>${browser-mob-version}</version>
<exclusions>
<exclusion>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-api</artifactId>
</exclusion>
<exclusion>
<artifactId>icu4j</artifactId>
<groupId>com.ibm.icu</groupId>
</exclusion>
<exclusion>
<artifactId>jackson-mapper-asl</artifactId>
<groupId>org.codehaus.jackson</groupId>
</exclusion>
<exclusion>
<artifactId>jackson-core-asl</artifactId>
<groupId>org.codehaus.jackson</groupId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Hint B: If we copy this Apache POI dependencies to the top, it works -->
<!-- Apache POI - for reading xlsx files -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.8</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.8</version>
</dependency>
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>ooxml-schemas</artifactId>
<version>1.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java-version}</source>
<target>${java-version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<!-- must be SURE to do this with both spring.handlers and spring.schemas.
otherwise you won't be able to use them in the spring config files. -->
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.mycompany.test.Start</mainClass>
</transformer>
</transformers>
<filters>
<filter>
<artifact>bouncycastle:bcprov-jdk15</artifact>
<excludes>
<exclude>META-INF/BCKEY.DSA</exclude>
<exclude>META-INF/BCKEY.SF</exclude>
<exclude>META-INF/MANIFEST.MF</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Je n'obtiens aucune autre information de débogage si j'exécute le bocal.
y a-t-il une option pour valider le fichier jarfile? Ou d'avoir quelque chose comme java -verbose
...?
les Étapes de reproduire:
- créer un nouveau dossier
- copier le Pom.xml d'en haut dans le dossier.
- Enregistrer le petit " public static void main(...). dans src/main/java/com/miscompany/test / Start.java
- exécuter
mvn clean package
- exécuter
java -jar target/com.mycompany.test-1.0.0-SNAPSHOT.jar
annexe 1:
package com.mycompany.test;
public class Start
{
public static void main(final String[] args)
{
System.out.println("If you are able to get this printed with java -jar you made it. Thanks a lot! :)");
}
}
Edit 1:
j'ai commencé à supprimer certaines dépendances pour identifier problème. Mais je ne comprends pas très bien ce qui ne va pas.
maintenant j'ai compris (voir l'indice B dans la pom.xml) que le fait de déplacer les dépendances du POI D'Apache vers le haut résoudra le problème. Mais je ne sais toujours pas pourquoi et quel est le problème.
2 réponses
de mon côté si je construis votre projet en utilisant le pom.xml
vous avez nous a montré, avec apache-poi
déclarés après jfreechart
, alors comme vous l'avez mentionné je reçois un pot corrompu. Changer l'ordre de ces deux dépendances me donne en effet un bocal correct.
j'ai de l'expérience avec le maven-shade-plugin
et quand je l'ai utilisé j'ai eu du mal avec la création de JAR META-INF
répertoire, donc j'ai vérifié cela pour les défauts.
j'ai essayé de copier (en utilisant Total Commander) le META-INF
répertoire quelque part sur mon système de fichiers local et ce que j'ai remarqué c'est qu'il y avait des erreurs lors de la copie des fichiers dans META-INF/licences/
. Si j'ai essayé de les copier individuellement et que ça a marché, mais je n'ai pas pu tout copier. Ma conclusion était que l'archive JAR/ZIP était corrompue.
Ce que j'ai fait j' entrée ce bocal en commandant Total ( Ctrl+page précédente le fichier JAR) et I renommée thirdpartylicenses.txt
thirdpartylicenses.txt.wtf
. Faire ce Total Commander offre de sauver ceci et il reemballage le pot (J'ai le total7zip Total Commander packer plugin installé - si quelqu'un essaie ceci et il ne fonctionne pas essayer avec cela installé).
Après cela. Elle fonctionne.
(j'ai aussi essayé de tout reconditionner sans renommer quoi que ce soit en utilisant Cygwin's unzip
/zip
commandes, mais cela n'a pas fonctionné la nouvelle archive était toujours corrompue. Total Commander ou le plugin que j'ai mentionné fait de la magie.)
je suppose que le maven-shade-plugin
crée simplement une archive ZIP/JAR corrompue ou invalide. Je ne sais pas pourquoi et peut-être que ce que j'ai décrit ne marchera pas pour quelqu'un d'autre mais j'ai pensé que je le mentionnerais pour que peut-être je puisse aider.
Je ne pouvais pas laisser cela tranquille, donc j'ai creusé plus profondément et je pense que j'ai trouvé la réponse.
mauvais JAR contient 65608 entrées. bonne jar contient 65450 entrée.
Devinez quelle est la limite supérieure de la le nombre d'entrées pour un plaine fichier ZIP? Ouais. L'article Wiki parle d'un format ZIP64 qui surmonte cette limitation.
bonne JAR a moins d'entrées parce que les dépendances réelles changent à cause de la position des déclarations de dépendances dans votre pom.xml
. ( tel que décrit par cette réponse.)
j'ai compté les entrées pareil.
Collections.list(new JarFile("...").entries()).size();
j'ai été en utilisant Java 7 qui semble supporter le nouveau format ZIP64, donc peut-être que si quelqu'un essaie de compter les entrées dans le mauvais JAR en utilisant Java 5 ou 6 va recevoir une erreur (je ne suis pas sûr cependant).
j'ai aussi essayé d'exécuter le POT explosé. J'ai déballé tout le bocal dans un répertoire et j'ai lancé tout le truc comme ça.
java -cp <dir/ com.mycompany.test.Start
fonctionnait comme un charme.
Bas de ligne. Ne pas une surutilisationmaven-shade-plugin
.
j'ai un projet au travail, où je construis mon projet comme celui-ci.
- je copie les dépendances de mon projet en utilisant le
maven-dependency-plugin
. La caisse de l'copy-dependencies
objectif. Cette copie vos dépendances danstarget/dependency
si je me souviens bien. maven-jar-plugin
j'ajoute ces dépendances à mon dernier POT de l'MANIFEST.MF
Class-Path
entrées utilisant ces options dans la configuration des plugins.<classpathPrefix>dependency/</classpathPrefix> <addClasspath>true</addClasspath>
Donc je vais avoir
Class-Path
les entréesdependency/<artifactId>-<version>.jar
, etc.- après cela j'utilise le
maven-assembly-plugin
pour créer une zone de distribution qui contient mon bocal final et le toutdependency/
dossier. - quand je déploie mon application je peux l'exécuter comme
java -jar final.jar
.
J'ai D'abord opté pour cette solution, parce que dans mon projet j'utilise des pots de Château gonflables qui ont des pots extravagants et à l'intérieur de leur META-INF
répertoire. Quand j'ai utilisé l' maven-shade-plugin
pour créer mon dernier runnable JAR tout l'enfer s'est déchaîné et je me suis méchant cette méthode n'a pas pu être trouvée et cette signature n'est pas tout à fait correcte erreurs.
Vous devriez faire quelque chose comme ça aussi. Cette affaire de Maven shade est trop!--37-->ombragé pour être utile, (le jeu de mots destiné.)
Ici un blog sur l'ensemble du processus que j'ai essayé de décrire juste au-dessus (merci à baba), peut-être que cela aidera quelqu'un dans le futur.
j'ai couru mvn dependency:tree
avec votre configuration et il donnera une différence quand vous déplacez le org.apache.poi
plus haut dans les déclarations de dépendances.
Ceci est pris à partir de la Introduction à la Dépendance Mécanisme concernant l'ordre des dépendances:
médiation de la dépendance - ceci détermine quelle version d'une dépendance sera utilisée lorsque plusieurs versions d'un artefact sont rencontrées. Actuellement, Maven 2.0 ne prend en charge que l'utilisation "définition la plus proche" qui signifie qu'elle utilisera la version de la dépendance la plus proche de votre projet dans l'arbre des dépendances. Vous pouvez toujours garantir une version en la déclarant explicitement dans la POM de votre projet. Notez que si deux versions de dépendances sont à la même profondeur dans l'arbre des dépendances, jusqu'à Maven 2.0.8 ce n'est pas défini qui gagnerait, mais depuis Maven 2.0.9 c'est l'ordre dans la déclaration qui compte: la première déclaration gagne.
il semble y avoir un conflit dans la résolution de votre dépendance et qui est à l'origine de votre fichier JAR corrompu (Je ne sais pas pourquoi il est corrompu).
en tout cas, voici les différences entre les deux POM (à gauche c'est l'origine, à droite c'est org.apache.poi
plus haut):
(Peut-être que c'est difficile à voir sur les photos, mais si vous zoomez, vous verrez.)
Le grand la différence est que dans le travail non-pom org.apache.httpcomponents:httpcore:jar:4.2.1
a une dépendance sur commons-codec:commons-codec:jar:1.6
, et dans la pom de travail que la dépendance a été remplacée par commons-codec:commons-codec:jar:1.5
.
je pense qu'il y a un problème avec le 1.6
version de commons-codec
avec org.apache.poi:poi:jar:3.8
ce qui nécessite le 1.5
version.
Modifier
Après cette excellente réponse qui explique pourquoi le fichier jar est corrompu (trop d'entrées dans la jar) je veux juste ajouter une solution simple qui fonctionne au moins pour votre problème particulier.
ajouter la balise <minimizeJar>true</minimizeJar>
pour votre maven-shade-plugin
configuration.
après cela votre java -jar target/com.mycompany.test-1.0.0-SNAPSHOT.jar
la ligne de commande fonctionnera.