Après avoir ajouté la dépendance Maven jFree à mon application existante, je ne suis pas en mesure d'exécuter le fichier jar créé.
Le seul message d'erreur que je reçois 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
Le pom.xml
Complet 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.
Existe-t-il une option pour valider le fichier jar? Ou avoir quelque chose comme Java -verbose
...?
étapes pour reproduire:
mvn clean package
Java -jar target/com.mycompany.test-1.0.0-SNAPSHOT.jar
Pièce jointe 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! :)");
}
}
Modifier 1:
J'ai commencé à supprimer certaines dépendances pour identifier le problème. Mais je n'ai pas une compréhension claire de ce qui ne va pas.
Maintenant, j'ai compris (voir l'indice B dans le pom.xml) que le déplacement des dépendances Apache POI vers le haut résoudra le problème. Mais je ne sais toujours pas pourquoi et quel est le problème.
De mon côté, si je construis votre projet en utilisant le pom.xml
vous nous avez montré, avec Apache-poi
déclaré après jfreechart
, puis comme vous l'avez mentionné, j'obtiens un JAR corrompu. L'échange de l'ordre de ces deux dépendances me donne en effet un JAR correct.
J'ai une expérience antérieure avec le maven-shade-plugin
et quand je l'ai utilisé, j'ai eu des problèmes avec le JAR créé META-INF
répertoire, donc je l'ai vérifié pour les défauts.
J'ai essayé de copier (à l'aide de 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 a eu des erreurs lors de la copie des fichiers dans META-INF/licences/
. Si j'ai essayé de les copier quelque part individuellement et que cela a fonctionné mais je n'ai pas pu copier le tout. Ma conclusion était que l'archive JAR/Zip est corrompue.
Ce que j'ai fait, c'est que j'ai entré ce JAR dans Total Commander (Ctrl+PgDown sur le fichier JAR) et moi renommé thirdpartylicenses.txt
à thirdpartylicenses.txt.wtf
. En faisant cela, Total Commander vous propose de l'enregistrer et de reconditionner le JAR (j'ai installé le plugin Total7Zip Total Commander packer - si quelqu'un essaie cela et que cela ne fonctionne pas, essayez-le avec celui-ci installé).
Après ça. Ça marche.
(J'ai également essayé de reconditionner le tout sans renommer quoi que ce soit à l'aide des commandes unzip
/Zip
de Cygwin, mais cela n'a pas fonctionné, la nouvelle archive était toujours corrompue. Total Commander ou le plugin I '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 fonctionnera pas pour quelqu'un d'autre, mais j'ai pensé le mentionner afin que je puisse aider.
Je ne pouvais pas laisser ça tranquille, alors j'ai creusé plus profondément et je pense avoir trouvé la réponse.
Le mauvais JAR contient 65608 entrées. Le bon JAR contient 65450 entrées.
Devinez quelle est la limite supérieure de le nombre d'entrées pour un plain fichier Zip ? Ouais. L'article Wiki parle d'un format Zip64 qui surmonte cette limitation.
Le bon JAR a moins d'entrées car les dépendances réelles changent à cause de la position des déclarations de dépendance dans votre pom.xml
. ( Comme décrit par cette réponse. )
J'ai compté les entrées comme ça.
Collections.list(new JarFile("...").entries()).size();
J'utilisais Java 7 qui semble prendre en charge le nouveau format Zip64 , donc peut-être que si quelqu'un essaie de compter les entrées dans le mauvais JAR utilisant Java 5 ou 6 recevra une erreur (je ne suis pas sûr cependant).
J'ai également essayé d'exécuter le JAR éclaté . J'ai décompressé l'intégralité du JAR dans un répertoire et exécuté le tout comme ceci.
Java -cp <dir/ com.mycompany.test.Start
A fonctionné comme un charme.
Conclusion. Ne pas abuser du maven-shade-plugin
.
J'ai un projet au travail où je construis mon projet comme ça.
maven-dependency-plugin
. Vérifiez copy-dependencies
objectif . Cela copie vos dépendances dans target/dependency
si je me souviens bien.En utilisant le maven-jar-plugin
J'ajoute ces dépendances à mon JAR final MANIFEST.MF
comme Class-Path
entrées utilisant ces options dans la configuration des plugins.
<classpathPrefix>dependency/</classpathPrefix>
<addClasspath>true</addClasspath>
Je vais donc avoir Class-Path
entrées comme dependency/<artifactId>-<version>.jar
, etc.
maven-Assembly-plugin
pour créer une distribution Zip contenant mon JAR final et l'ensemble dependency/
dossier.Java -jar final.jar
.J'ai principalement choisi d'utiliser cette solution, car dans mon projet, j'utilise des JAR Bouncy Castle, lesquels ont des extravagants ceci et cela dans leur META-INF
répertoire. Quand j'ai utilisé le maven-shade-plugin
pour créer mon JAR exécutable final, tout l'enfer s'est déchaîné et je suis devenu méchant cette méthode n'a pas pu être trouvée et cette signature n'est pas tout à fait correcte .
Vous devriez aussi faire quelque chose comme ça. Cette entreprise d'ombrage Maven est trop ombragée pour être utile (jeu de mots voulu).
Voici n article de blog sur tout le processus que j'ai essayé de décrire juste au-dessus (grâce à baba ), peut-être que cela aidera quelqu'un à l'avenir.
L'Iran mvn dependency:tree
avec votre configuration et cela donnera une différence lorsque vous déplacez le org.Apache.poi
plus haut dans les déclarations de dépendance.
Ceci est extrait de Introduction to the Dependency Mechanism concernant l'ordre des dépendances:
Médiation de dépendance - cela détermine quelle version d'une dépendance sera utilisée lorsque plusieurs versions d'un artefact sont rencontrées. Actuellement, Maven 2.0 prend uniquement en charge l'utilisation de la "définition la plus proche", ce qui signifie qu'il utilisera la version de la dépendance la plus proche de votre projet dans l'arborescence des dépendances. Vous pouvez toujours garantir une version en la déclarant explicitement dans le POM de votre projet. Notez que si deux versions de dépendances sont à la même profondeur dans l'arborescence de dépendances, jusqu'à Maven 2.0.8, il n'était pas défini laquelle gagnerait mais puisque Maven 2.0.9 c'est l'ordre dans le déclaration qui compte: la première déclaration gagne .
Il semble y avoir un conflit dans votre résolution de dépendance et cela provoque votre fichier jar corrompu (je ne sais pas pourquoi il est corrompu).
Quoi qu'il en soit, voici les différences entre les deux poms (à gauche est Origin, à droite est avec org.Apache.poi
plus haut):
( Peut-être que c'est difficile à voir sur les photos mais si vous zoomez vous verrez.)
La grande différence est que dans le pom non fonctionnel, le org.Apache.httpcomponents:httpcore:jar:4.2.1
a une dépendance sur commons-codec:commons-codec:jar:1.6
, et dans le pom de travail, cette dépendance a été remplacée par commons-codec:commons-codec:jar:1.5
.
Je suppose qu'il y a un problème avec le 1.6
version de commons-codec
ensemble avec org.Apache.poi:poi:jar:3.8
qui a besoin du 1.5
version.
Modifier
Après cette excellente réponse qui explique pourquoi le fichier jar est corrompu (trop d'entrées dans le jar), je veux juste ajouter une solution simple qui fonctionne au moins pour votre problème particulier.
Ajoutez la balise <minimizeJar>true</minimizeJar>
à ton maven-shade-plugin
configuration.
Après cela, votre Java -jar target/com.mycompany.test-1.0.0-SNAPSHOT.jar
la ligne de commande fonctionnera.