0

I have a maven project with a reactor and a couple of modules, most of which are being packed as war. The order in which they are specified in the reactor / root pom.xml defines the order in which they are built.

pom.xml

....
<module>library1</module>
<module>library2</module>
<module>webapp1</module><!--war-->
<module>webapp2</module><!--war-->
<module>blackduck-scan</module><!-- create file to be placed into webapp2 post-build but pre-packaging of webapp2 -->
...

The last module, purposely, is destined to simply run an executable in the prepare-package phase. More precisely a blackduck license scanner, which itself eventually produces the license notice file which is then placed into the /webapp folder of one of the web applications to be displayed after deployment.

The idea is what this notice file is being placed after compilation of the applications but before packaging these as WAR artifacts to have it included in the current delivery of our pipeline without re-building just for the sake of re-packaging.

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.0</version>
<configuration>
    <executable>java</executable>
    <workingDirectory>.</workingDirectory>
    <arguments>
        <argument>-jar</argument>
        <argument>synopsys-detect-8.4.0.jar</argument>
    </arguments>
    ...
</configuration>
<executions>
    <execution>
        <goals>
            <goal>exec</goal>
        </goals>
        <phase>prepare-package</phase>
    </execution>
</executions>
</plugin>

I've tried two options to achieve this without success.

a) Adding the plugin/goal to the reactor pom.xml leads to the goal being executed first as soon as the target phase is prepare-package and thus may lead to incomplete scan results while the actual project has not yet been built.

b) Adding then plugin/goal as a module as described above puts the execution at the end of the chain, however, packaging of the webapps has already been concluded.

c) The third (arguably working) but less elegant approach would be to split this into two separate maven calls:

mvn clean install && mvn package

I see that modules are build in sequence and for good reason. However, is there any method to "synchronize" build phases such that each phase is started only after the previous phase has been completed for all modules? Effectively to simply call, all included:

mvn clean install
jenszo
  • 98
  • 5
  • 1
    There one very important error in your assumptions: `reactor / root pom.xml defines the order in which they are built.`. You have to define correct dependencies between the modules which defines the build order... – khmarbaise Jan 13 '23 at 07:02
  • 1
    If you have to use that `synopsys-detect...` thing you should define that in your parent pom and execute it the appropriate life cycle phase and generate appropriate file in your project. The packaging of the module will pick that up.. also I would recommend to write a plugin to integrate better into the life cycle than using exec-maven-plugin... – khmarbaise Jan 13 '23 at 07:13
  • I have not understood why it is a problem if the blackduck runs at the beginning of `prepare-package`. What interesting things happen in `prepare-package` in your build? – J Fabian Meier Jan 13 '23 at 14:18
  • The problem arises with more than one artifact / module. The scanner is supposed to scan *all* of them (the project, globally), at once and only once at the end of the build and not on a per-module basis. Therefore, the scan task is not part of every module but has as stand-alone module. As this, however, it cannot control the build phases of all the other modules and they have been packaged before the report - that is to be packaged as well - has been concluded. In know, fairly specific problem. – jenszo Jan 13 '23 at 19:21

1 Answers1

0

I believe the option is:

  • disable war creation and run exploded goal instead
  • use maven-assembly-plugin to pack target war
  • inject execution of blackduck between maven-war-plugin and maven-assembly-plugin

smth. like:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <executions>
        <execution>
            <!-- disabling building war -->
            <id>default-war</id>
            <phase>none</phase>
        </execution>
        <execution>
            <id>exploded</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>exploded</goal>
            </goals>
        </execution>
    </executions>
</plugin>

<!-- blackduck execution here -->

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <descriptors>
            <descriptor>war-assembly.xml</descriptor>
        </descriptors>
        <appendAssemblyId>false</appendAssemblyId>
    </configuration>
</plugin>

war-assembly.xml:

<assembly>
    <id>war</id>
    <formats>
        <format>war</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <fileSets>
        <fileSet>
            <directory>${project.build.directory}/${project.build.finalName}</directory>
            <outputDirectory>.</outputDirectory>
            <includes>
                <include>/**/*</include>
            </includes>
        </fileSet>
    </fileSets>
</assembly>
Andrey B. Panfilov
  • 4,324
  • 2
  • 12
  • 18