4

I have a Java project that packages some resource files into the artifact jar. The files come from a zip that is versioned and stored in the same artifactory as the project's artifact. The zip is referenced as a dependency with a version-range.

The zip is listed as a dependency:

<dependency>
    <groupId>com.example</groupId>
    <artifactId>resource-files</artifactId>
    <version>[1.68.0,1.68.1)</version>
    <type>zip</type>
    <scope>provided</scope>
</dependency>

Then unpacked with dependency plugin:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.10</version>
    <executions>
        <execution>
            <id>unpack-dependencies</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>unpack-dependencies</goal>
            </goals>
            <configuration>
                <includes>**/*.bin</includes>
                <outputDirectory>${basedir}/import</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

Then added as a resource to the jar:

<resource>
    <directory>${project.basedir}/import/resource-files-${version????}</directory>
    <includes>
        <include>*</include>
    </includes>
    <targetPath>bins</targetPath>
</resource>

How can I determine the exact version of the artifact zip? I would like to skip modifying the pom (like versions:resolve-ranges does), if possible.

Gyorgy Szekely
  • 2,654
  • 3
  • 23
  • 32
  • `[1.68.0,1.68.1)` means _1.68.0 <= version < 1.68.1_. Since there is no version between _.0_ and _.1_ this is the same as just `1.68.0`. Or is this just a placeholder for a future "real", wider range? – Gerold Broser Apr 01 '19 at 12:45
  • Actual versions have a build date suffix, so 1.68.0.20190304 or 1.68.0.20190401 are valid versions. – Gyorgy Szekely Apr 01 '19 at 13:40

2 Answers2

4

Well this was fun...

I found 2 ways to get resolved versions: use a specific plugin, or use a small groovy script to query it from maven.

Plugin

There's a dependencyversion-maven-plugin:

<plugin>
    <groupId>io.reformanda.semper</groupId>
    <artifactId>dependencyversion-maven-plugin</artifactId>
    <version>1.0.1</version>
    <executions>
        <execution>
            <id>set-all</id>
            <goals>
                <goal>set-version</goal>
            </goals>
        </execution>
    </executions>
</plugin>

It creates new properties for each dependency in the format groupId:artifactId:type[:classifier].version with the resolved version value. More details here.

Groovy

The same result can be achieved with a small groovy script:

<plugin>
    <groupId>org.codehaus.gmaven</groupId>
    <artifactId>groovy-maven-plugin</artifactId>
    <executions>
        <execution>
            <phase>initialize</phase>
            <goals>
                <goal>execute</goal>
            </goals>
            <configuration>
                <source>
                    for (art in project.getArtifacts())
                        project.properties['resolvedVersion.' + art.getArtifactId()] = art.getVersion()
                </source>
            </configuration>
        </execution>
    </executions>
</plugin>

Since the groovy-maven-plugin nicely exposes maven internals, all kinds of tricks can be implemented.

Almost there...

Both above solutions define a new set of properties with the resolved version, but unfortunately they are not usable in the <build><resources> block. I haven't found documentation on this, but it seem properties in this block are substituted before the lifecycle starts and the newly defined properties simply not exist yet at that point.

The only workaround I found is to explicitly invoke the copy-resources goal on the resources plugin:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-resources-plugin</artifactId>
    <version>3.1.0</version>
    <executions>
        <execution>
            <id>copy-resources</id>
            <goals>
                <goal>copy-resources</goal>
            </goals>
            <phase>process-resources</phase>
            <configuration>
                <outputDirectory>${project.build.outputDirectory}</outputDirectory>
                <resources>
                    <resource>
                        <filtering>false</filtering>
                        <directory>${basedir}/import/resource-files-${resolvedVersion.resource-files}/lib</directory>
                        <includes>
                            <include>*</include>
                        </includes>
                        <targetPath>bins</targetPath>
                    </resource>
                </resources>
            </configuration>
        </execution>
    </executions>
</plugin>

With this block in place (and replacing <build><resources>), all resources correctly copied, and there's no need to hardcode anything.

Though it might not be the most elegant way...

Gyorgy Szekely
  • 2,654
  • 3
  • 23
  • 32
0

You can use the stripVersion parameter

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.10</version>
    <executions>
        <execution>
            <id>unpack-dependencies</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>unpack-dependencies</goal>
            </goals>
            <configuration>
                <includes>**/*.bin</includes>
                <outputDirectory>${basedir}/import</outputDirectory>
                <stripVersion>true</stripVersion>
            </configuration>
        </execution>
    </executions>
</plugin>
  • StripVersion doesn't work in this case. The resource-files- directory is the root directory inside the zip file (the zip is created with the maven assembly plugin). The dependency plugin can't strip some part of the root folder inside the zip (it's more useful for the copy-dependencies goal where it can strip the version from the zipfile itself). – Gyorgy Szekely Apr 01 '19 at 20:29
  • Ok, so maybe https://maven.apache.org/plugins/maven-dependency-plugin/properties-mojo.html can help you, but I‘m not sure if this behaves well with version-ranges – Robert Kleinschmager Apr 02 '19 at 04:20