36 votes

Idée pour éviter que spring.handlers/spring.schemas ne soient écrasés lors de la fusion de plusieurs dépendances de Spring dans un seul jar.

J'ai obtenu l'erreur Unable to locate NamespaceHandler when using context:annotation-config exécuter (java -jar) un jar assemblé par le maven-assembly-plugin et contenant mon projet et toutes ses dépendances.

Comme d'autres personnes l'ont correctement remarqué sur le forum.springsource.org fil (message n° 7/8) le problème se produit parce que les fichiers META-INF/spring.handlers et META-INF/spring.schemas qui sont présents dans différents jars, sont écrasés lorsque le plugin maven-assembly repackage les jars dans un seul fichier.

En regardant le contenu de deux fichiers spring-*.jar, vous pouvez voir que les fichiers se trouvent à la même position par rapport au classpath

$ jar tf spring-oxm-3.0.3.RELEASE.jar
META-INF/spring.handlers
META-INF/spring.schemas
org/springframework/oxm/GenericMarshaller.class
...

$ jar tf spring-context-3.0.3.RELEASE.jar
META-INF/spring.handlers
META-INF/spring.schemas
org/springframework/context/ApplicationContext.class

N'est-il pas possible de placer le dossier META-INF dans un paquet spécifique ? Si c'est le cas, l'idée que je suggère (en espérant qu'elle soit applicable) est de placer le dossier META-INF dans un paquet spécifique. META-INF/spring.shemas et META-INF/spring.handlers sous le paquet auquel ils font référence.

$ jar tf spring-oxm-3.0.3.RELEASE.jar
org/springframework/oxm/META-INF/spring.schemas
org/springframework/oxm/META-INF/spring.handlers
org/springframework/oxm/GenericMarshaller.class
...

$ jar tf spring-context-3.0.3.RELEASE.jar
org/springframework/context/META-INF/spring.handlers
org/springframework/context/META-INF/spring.schemas
org/springframework/context/ApplicationContext.class

Ainsi, ils n'entreront pas en conflit lorsqu'ils seront fusionnés dans un seul bocal. Qu'est-ce que vous en pensez ?

86voto

chzbrgla Points 2667

J'ai réussi à me débarrasser du bug en utilisant le plugin shader au lieu du plugin assembleur (buggé) :

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <transformers>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                <mainClass>at.seresunit.lecturemanager_connector.App</mainClass>
                            </transformer>
                            <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>
                        </transformers>
                    </configuration>
                </execution>
            </executions>
        </plugin>

Je crois que j'ai trouvé la solution sur les forums de springsource. Cela fait un certain temps que je ne l'ai pas cherché je ne me souviens plus vraiment de l'auteur. Félicitations à lui en tout cas :p

salutations

2voto

Sithsu Points 901

Avec Ant.

<!--define couple of properties to identify spring jar files-->
<property name="spring-beans-jar" value="spring-beans-4.0.5.RELEASE.jar"/>
<property name="spring-context-jar" value="spring-context-4.0.5.RELEASE.jar"/>

<!--other properties-->

<target name="dist" depends="compile" description="Prepare distribution">
    <!--dump spring-context into build classes (or some place else)-->
    <unjar src="${lib.dir}/${spring-context-jar}" dest="${build.classes.dir}"/>

    <!--dump spring-beans on top of it overwriting META-INF/spring.* files-->
    <unjar src="${lib.dir}/${spring-beans-jar}" dest="${build.classes.dir}"/>

    <!--get overwritten META-INF/spring.* files of spring-context to some other place-->
    <unjar src="${lib.dir}/${spring-context-jar}" dest="${build.tmp.dir}">
        <patternset>
            <include name="META-INF/spring.handlers"/>
            <include name="META-INF/spring.schemas"/>
            <include name="META-INF/spring.tooling"/>
        </patternset>
    </unjar>

    <!--skipped spring-beans/META-INF/spring.factories as its not present in spring-context-->
    <!--handled only spring-context and spring-beans as that's what I needed at this point-->

    <!--append content from spring-context/META-INF/spring.* files-->
    <concat destfile="${build.classes.dir}/META-INF/spring.handlers" append="true">
        <filelist dir="${build.tmp.dir}" files="META-INF/spring.handlers"/>
    </concat>
    <concat destfile="${build.classes.dir}/META-INF/spring.schemas" append="true">
        <filelist dir="${build.tmp.dir}" files="META-INF/spring.schemas"/>
    </concat>
    <concat destfile="${build.classes.dir}/META-INF/spring.tooling" append="true">
        <filelist dir="${build.tmp.dir}" files="META-INF/spring.tooling"/>
    </concat>

    <jar destfile="${build.dist.dir}/application.jar">
        <fileset dir="${build.classes.dir}"/>

        <!--include all .jar files except already extracted ones-->
        <zipgroupfileset dir="${lib.dir}" includes="*.jar"
                         excludes="${spring-beans-jar}, ${spring-context-jar}"/>
        <manifest>
            <attribute name="Main-Class" value="${main-class}"/>
        </manifest>
    </jar>
</target>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X