在单个 jar 中合并多个 spring 依赖项时避免 spring.handlers/spring.schemas 被覆盖的想法

发布于 2024-10-31 14:25:55 字数 1383 浏览 1 评论 0原文

当使用 context:annotation-config 运行 (java -jar) 由 maven-assemble-plugin 组装并包含我的项目及其所有依赖项的 jar 时,我收到错误 无法找到 NamespaceHandler

正如其他人在 forum.springsource.org 线程(消息 #7/8) 上正确发现的问题发生这种情况的原因是,当 maven-assemble-plugin 重新打包时,不同 jar 中存在的文件 META-INF/spring.handlersMETA-INF/spring.schemas 会被覆盖jars 在一个文件中。

查看两个 spring-*.jar 文件的内容,您可以看到这些文件相对于类路径位于相同的位置。

$ 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

是否可以将 META-INF 文件夹放在特定的包中?如果是这样,我建议的想法(希望它适用)是将 META-INF/spring.shemasMETA-INF/spring.handlers 文件放在他们引用的包。

$ 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

这样,当它们合并到一个 jar 中时就不会发生冲突。你对此有何看法?

I got the error Unable to locate NamespaceHandler when using context:annotation-config running (java -jar) a jar assembled by the maven-assembly-plugin and containing my project and all its dependencies.

As other people correctly spotted on the forum.springsource.org thread (message #7/8) the problem occurs because the files META-INF/spring.handlers and META-INF/spring.schemas that are present in different jars, get overwritten when the maven-assembly-plugin repackages the jars in a single file.

Looking at the content of two spring-*.jar files you can see the files sits in the same position relatively to the 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

Isn't it is possible to put the META-INF folder in a specific package? If so the idea I'd suggest, (hope it's applicable) is to put the META-INF/spring.shemas and META-INF/spring.handlers files under the package they refer to.

$ 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

This way they won't conflict when merged in a single jar. What do you think about it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

┊风居住的梦幻卍 2024-11-07 14:25:55

我设法使用着色器插件而不是(有缺陷的)汇编器插件来消除该错误:

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

我想我在 springsource 论坛上找到了解决方案..自从我查找它以来已经有一段时间了..真的不能记住作者。不管怎样,还是要向他致敬:p

干杯

I managed to get rid of the bug using the shader plugin instead of the (buggy) assembler plugin:

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

I think I found the solution on the springsource forums.. it has been quite some time since I looked it up.. can't really remember the author. Kudos to him anyways :p

cheers

烟织青萝梦 2024-11-07 14:25:55

与蚂蚁。

<!--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>

With 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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文