Maven overwrite resource file in dependency

可紊 提交于 2019-11-29 02:17:57

Ok, Maven Resources Plugin and Assembly plugin did not cut it, so I dug some more.

It seems this is doable with Maven Shade plugin.

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>1.4</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <transformers>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                <!-- Main class -->
                                <mainClass> <!-- fully qualified package and class name --> </mainClass>
                                <manifestEntries>
                                    <Class-Path>.</Class-Path>
                                </manifestEntries>
                            </transformer>
                        </transformers>

                        <filters>
                            <filter>
                                <artifact>org.something:SomeDependency</artifact>
                                <excludes>
                                    <exclude>*.properties</exclude>
                                </excludes>
                            </filter>
                        </filters>

                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

So, inside the <configuration> ... </configuration> -tags I've defined two things: a transformer-implementation that takes care of modifying the jar-manifest to be runnable and use the current directory as classpath root, and excluding all the files ending with .properties from inside of dependency org.something:SomeDependency.

The actual filtering part is where you can exclude the files you don't want to end up in the final jar built by shade. You can exclude the files from all the dependencies and the current project using <artifact>*:*</artifact> inside the defined <filter>, or you can select only certain dependency using <artifact>dependcyGroupId:dependencyArtifact</artifact>, for example <artifact>junit:junit</artifact>, or even using wildcards for one or the other (<artifact>*:junit</artifact>). The excluded files are then defined inside the <excludes>...</excludes> -tags. Again, you can use exact filenames or wildcards. This should get you going with your current problem, although I'd suggest reading the documentation from the plugin-site, because shade can do a lot more than this.

I know this is 3 years old but I had the same problem and this is the closest question I found, but still without correct answer so maybe someone will find it useful.

Example maven-assembly descriptor based on jar-with-dependencies (fixes overriding of log4j.properties by dependencies):

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
    <id>jar-with-dependencies</id>
    <formats>
        <format>jar</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <dependencySets>
        <dependencySet>
            <outputDirectory>/</outputDirectory>
            <useProjectArtifact>false</useProjectArtifact>
            <unpack>true</unpack>
            <unpackOptions>
                <excludes>
                    <exclude>log4j.properties</exclude>
                </excludes>
            </unpackOptions>
            <scope>runtime</scope>
        </dependencySet>
    </dependencySets>
    <fileSets>
        <fileSet>
            <directory>${project.build.outputDirectory}</directory>
            <outputDirectory>/</outputDirectory>
        </fileSet>
    </fileSets>
</assembly>

The key is to provide different rules for dependencies and the actual project (top of hierarchy). Those can be split by using <useProjectArtifact>false</useProjectArtifact> and providing separate rules in fileSets for the project. Otherwise none of log4j.properties would be packed, including the top one.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!