Question

I'm a Maven newbie and my project is finally compiling and running correctly.

On each run my project writes reports on a dynamic location created at runtime (username_timestamp) and sets a System.property called REPORTS_LOCATION with this location. After execution I would like to copy some static resources (style, images, js, etc) to this dynamic folder using a maven goal.

What I can't figure out is how to let Maven know about this dynamic location or access this System.property

I'm about ready to just let my project copy these resources to the directory but I figure I'll give it another try in case there is an easy/Maven way of doing this.

I've gotten as far as copying the resources to a hard coded location. Here is a snippet of the POM. I'm using Jbehave's Maven goals and they do execute in order

<plugins>
  <plugin>
    <groupId>org.jbehave</groupId>
    <artifactId>jbehave-maven-plugin</artifactId>
    <version>${jbehave.core.version}</version>
    <executions>
      <execution>
        <id>embeddable-stories</id>
        <phase>integration-test</phase>
        <configuration>
          <includes>
            <include>**/Stories.java</include>
          </includes>
          <excludes />
          <metaFilters>
            <metaFilter>${meta.filter}</metaFilter>
          </metaFilters>
        </configuration>
        <goals>
          <goal>run-stories-as-embeddables</goal>
        </goals>
      </execution>
      <!-- Copy the resources AFTER the execution is done -->
      <execution>
        <id>unpack-view-resources</id>
        <phase>integration-test</phase>
        <configuration>
            <viewDirectory>${basedir}/src/main/java/project/reports/{NEED TO FEED DIRECTORY HERE}</viewDirectory>
        </configuration>
        <goals>
          <goal>unpack-view-resources</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
</plugins>
Was it helpful?

Solution

It sounds like you have a piece of Java code calculating {username_timestamp}, and you then want that code to be able to communicate the calculated {username_timestamp} back to Maven for use in later steps of its lifecycle. I'm not sure that this is possible. Instead, how about inverting the process, so that Maven produces the timestamp, and you consume it from your code? You can achieve this using a combination of build-helper-maven-plugin, Maven resource filtering, and Java code to load a properties file.

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>junk</groupId>
    <artifactId>junk</artifactId>
    <packaging>jar</packaging>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <build>
        <plugins>
            <!--
            Use build-helper-maven-plugin to generate a timestamp during the
            initialize phase and store it as a property named "timestamp".
            -->
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
                <version>1.7</version>
                <executions>
                    <execution>
                        <id>timestamp-property</id>
                        <phase>initialize</phase>
                        <goals>
                            <goal>timestamp-property</goal>
                        </goals>
                        <configuration>
                            <locale>en_US</locale>
                            <name>timestamp</name>
                            <pattern>yyyyMMDDHHmmssSSS</pattern>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>

                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>Main</mainClass>
                        </manifest>
                    </archive>

                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>

                    <finalName>${pom.artifactId}</finalName>
                    <appendAssemblyId>false</appendAssemblyId>
                </configuration>

                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>

                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>

        <!--
        Turn on resource filtering so that references to ${timestamp} in a
        properties file get replaced with the value of the timestamp property.
        -->
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>
</project>

src/main/resources/junk.properties

timestamp=${timestamp}

src/main/java/Main.java

import java.util.Properties;

public final class Main {

    public static void main(String[] args) throws Exception {
        Properties props = new Properties();
        props.load(Main.class.getResourceAsStream("/junk.properties"));
        System.out.println(props.getProperty("timestamp"));
    }
}

OTHER TIPS

Thanks a lot cnauroth, this worked like a charm. Here is my working updated POM in case it helps someone else

<resources>
  <resource>
    <directory>${basedir}/src/main/java/resources</directory>
    <excludes><exclude>**/locale/**</exclude></excludes>
    <filtering>true</filtering>
  </resource>
</resources>
<plugins>

<!-- Use build-helper-maven-plugin to generate a timestamp during the initialize 
    phase and store it as a property named "mavenTimestamp". -->
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <version>1.7</version>
    <executions>
        <execution>
            <id>timestamp-property</id>
            <phase>initialize</phase>
            <goals>
                <goal>timestamp-property</goal>
            </goals>
            <configuration>
                <locale>en_US</locale>
                <name>mavenTimestamp</name>
                <pattern>yyyyMMDDHHmmssSSS</pattern>
            </configuration>
        </execution>
    </executions>
</plugin>

  <plugin>
    <groupId>org.jbehave</groupId>
    <artifactId>jbehave-maven-plugin</artifactId>
    <version>${jbehave.core.version}</version>
    <executions>
      <execution>
        <id>embeddable-stories</id>
        <phase>integration-test</phase>
        <configuration>
          <includes>
            <include>**/Stories.java</include>
          </includes>
          <excludes />
          <ignoreFailureInStories>true</ignoreFailureInStories>
          <verboseFailures>true</verboseFailures>
          <threads>5</threads>
          <metaFilters>
            <metaFilter>${meta.filter}</metaFilter>
          </metaFilters>
        </configuration>
        <goals>
          <goal>run-stories-as-embeddables</goal>
        </goals>
      </execution>
      <!-- THIS WORKS :) Copy the resources AFTER the execution is done -->
       <execution>
        <id>unpack-view-resources</id>
        <phase>integration-test</phase>
        <configuration>
            <viewDirectory>${basedir}/src/main/java/project/reports/${mavenTimestamp}</viewDirectory>
        </configuration>
        <goals>
          <goal>unpack-view-resources</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
</plugins>

If you set the folder as an environment variable during the runtime, you can do the following:

just use

    <properties>
        <REPORTS_LOCATION><${env.REPORTS_LOCATION}></REPORTS_LOCATION>
    </properties>

then you can reference to theproperty via ${REPORTS_LOCATION} in you pom

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top