Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

maven-resources-plugin set to different phase

Tags:

java

maven

I am trying to force maven-resources-plugin execution for different phase like this:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-resources-plugin</artifactId>
    <version>2.6</version>
    <executions>
        <execution>
            <id>copy-resources</id>
            <phase>test</phase>
            ...

I see in logs this plugin is executed first, before my maven-compiler-plugin:2.3.2:compile:

[INFO] --- maven-resources-plugin:2.6:resources (default-resources)
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource

Why is this the case? (I based above on this docu: http://maven.apache.org/plugins/maven-resources-plugin/examples/copy-resources.html)


I still don't get it. I will describe root cause of my problem. I have this tasks:

  1. maven-war-plugin generates me WAR file (@ phase <phase>compile</phase>)
  2. maven-resources-plugin I want to force execution here
  3. checksum-maven-plugin generates for me a checksum file (@ phase <phase>package</phase>).

Normally I can't do that because form my observation maven-resources-plugin is executed before my war is created. I though I will put this plugin to test phase. But what are your suggestions? What phase will be good for that? How to do that?


Underlying problem description. I want to provide two files as application:

  • WAR file.
  • JAR for deployment which validates WAR file by checksum before deployment.
like image 813
Knight of Ni Avatar asked Oct 20 '25 15:10

Knight of Ni


2 Answers

Because there's another execution for a goal for this plugin defined by a parent POM or lifecycle specification.

Check mvn help:effective-pom in your project's directory and you'll see how your POM actually looks like.

It sounds like you're assuming a plugin execution works like this: "this is where I want to execute the plugin and here only".

However, it actually works more like this: "I'm defining this execution. This execution is to be done for the following phase, and these plugin goals under this configuration are to be executed then. Oh, and here's an ID for the execution, since you say you need it".

In other words: plugin executions are not exclusive for a plugin, or even a plugin goal.

However, as rec correctly points out, you can override the settings of a plugin execution set by a parent POM by specifying your own execution with the same ID. Once again, check the Effective POM to find those IDs. At the moment, for Maven 3, there are two "pre-defined" executions for the resources plugin, in the JAR packaging type : default-resources, and default-testResources.

Note that this is not something you should be normally doing for the resources plugin, as this can break your build.


EDIT: in your situation, it's clear that you have two parts of your project:

  • a WAR that contains some applications,
  • a JAR that deploys your WAR to some container.

Maven differs in from make (in my understanding) is that it decouples the build process of artifacts. In other words, you should create two projects: one with a WAR packaging, the other with the JAR packaging. The latter should copy the WAR package into its JAR. On top of that is what's called a multi-module project.

Specifically what you can do is:

  1. Separate the project into two: the one building the JAR and the one building the WAR.
  2. Create the multi-module project that specifies the other two as modules. The JAR project should be after the WAR project. You can set the multi-module project as a parent to the other two, it will let you to synchronize versions and other configuration.
  3. In your JAR project, add a plugin goal execution that copies the WAR to your package. You can use the dependency:copy goal for this, e.g.:

    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.8</version>
    <executions>
      <execution>
        <id>copy-war</id>
        <phase>generate-resources</phase>
        <goals>
          <goal>copy</goal>
        </goals>
        <configuration>
          <artifactItems>
            <artifactItem>
              <groupId>[your-war-group-id]</groupId>
              <artifactId>[your-war-artifact-id]</artifactId>
              <version>${project.version}</version>
              <type>war</type>
              <overWrite>true</overWrite>
              <outputDirectory>${basedir}/src/main/resources</outputDirectory>
              <destFileName>install.war</destFileName>
            </artifactItem>
          </artifactItems>
        </configuration>
      </execution>
    </executions>
    </plugin>
    

    (an alternative is to specify the package as a dependency and use the assembly plugin)

  4. Run the build for the multi-module project with the install target. You need install because it ensures that the latest version of the WAR project will find its way into your local m2 repository, for the JAR project to pick up.

You can skip the multi-module bit and just create two separate projects. However, in this case you will need to run the WAR project's install target before the JAR project's package manually whenever there's a change in the former.

like image 58
mikołak Avatar answered Oct 22 '25 03:10

mikołak


You're talking about 2 different goals: copy-resources and resources. For most packaging types the latter is bound to the process-resources phase. That's the one you are seeing in the log. To have copy-resources being executed during the test-phase, also add

<goals>
  <goal>copy-resources</goal>
</goals>

Hence, you can read it here too

like image 41
Robert Scholte Avatar answered Oct 22 '25 04:10

Robert Scholte



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!