sbt / sbt-assembly

Deploy über-JARs. Restart processes. (port of codahale/assembly-sbt)
MIT License
1.95k stars 224 forks source link

ManifestResourceTransformer for assembly #250

Open geoHeil opened 7 years ago

geoHeil commented 7 years ago

Maven shade plugin has some special transformer to handle resources. Is there something similar to ManifestResourceTransformer for assembly?

<artifactId>maven-shade-plugin</artifactId>
              <version>1.3.1</version>
              <executions>
                  <execution>
                      <phase>package</phase>
                      <goals>
                          <goal>shade</goal>
                      </goals>
                      <configuration>
                          <transformers>
                              <!-- This bit sets the main class for the executable jar as you otherwise -->
                              <!-- would with the assembly plugin                                       -->
                              <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                  <manifestEntries>
                                      <Main-Class>org.geotools.demo.Quickstart</Main-Class>
                                  </manifestEntries>
                              </transformer>
                              <!-- This bit merges the various GeoTools META-INF/services files         -->
                              <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
                          </transformers>
                      </configuration>

from: http://docs.geotools.org/latest/userguide/faq.html#how-do-i-create-an-executable-jar-for-my-geotools-app

tilayealemu commented 4 years ago

This feature would be helpful.

For those looking for an alternative solution, take a look at what ManifestResourceTransformer does:

A resource processor that allows the arbitrary addition of attributes to the first MANIFEST.MF that is found in the set of JARs being processed, or to a newly created manifest for the shaded JAR.

You may also need ServicesResourceTransformer like the OP:

Resources transformer that relocates classes in META-INF/services and appends entries in META-INF/services resources into a single resource.

In my case it wasn't important to merge manifests from all the jars my project depended on. So I simply discarded them (a new manifest will be generated). Merging services was important for me though. My final solution:

val mergeStrategy = assemblyMergeStrategy in assembly := {
  case path if path.contains("META-INF/services") => MergeStrategy.concat
  case PathList("META-INF", _*) => MergeStrategy.discard
  case _ => MergeStrategy.first
}

Merge strategies are documented in the readme:

MergeStrategy.deduplicate is the default described above
MergeStrategy.first picks the first of the matching files in classpath order
MergeStrategy.last picks the last one
MergeStrategy.singleOrError bails out with an error message on conflict
MergeStrategy.concat simply concatenates all matching files and includes the result
MergeStrategy.filterDistinctLines also concatenates, but leaves out duplicates along the way
MergeStrategy.rename renames the files originating from jar files
MergeStrategy.discard simply discards matching files```