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:

  1. créer un nouveau dossier
  2. copier le Pom.xml d'en haut dans le dossier.
  3. Enregistrer le petit " public static void main(...). dans src/main/java/com/miscompany/test / Start.java
  4. exécuter mvn clean package
  5. 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.

34
demandé sur d0x 2012-10-23 03:25:43

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.txtthirdpartylicenses.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 dans target/dependency si je me souviens bien.
  • maven-jar-plugin j'ajoute ces dépendances à mon dernier POT de l' MANIFEST.MFClass-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ées dependency/<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 tout dependency/ 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.

45
répondu Kohányi Róbert 2017-05-23 12:33:21

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):

enter image description hereenter image description here

(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.

11
répondu maba 2017-05-23 12:16:36