oscar
oscar

Reputation: 1756

Replace a constant in JAVA code with Maven without modifying the original code

I have a text in a java constant that I want to be replaced according to a maven variable that is configured when generating the artifacts in the following way:

public class FOO {
    public static final String BASE = "/@FOO@";
}

The problem is that if I replace the java code, it is replaced forever and the replacement is no longer performed, so if I change the value of the variable it has no effect:

<plugin>
    <groupId>com.google.code.maven-replacer-plugin</groupId>
    <artifactId>replacer</artifactId>
    <version>1.5.3</version>
    <executions>
        <execution>
            <phase>generate-sources</phase>
            <goals>
                <goal>replace</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <includes>
            <include>${basedir}/src/main/java/com/my/package/Constants.java</include>
        </includes>
        <replacements>
            <replacement>
                <token>@FOO@</token>
                <value>${my.custom.property}</value>
            </replacement>
        </replacements>
    </configuration>
</plugin>

I have fixed this by doing the process in reverse:

 <plugin>
    <groupId>com.google.code.maven-replacer-plugin</groupId>
    <artifactId>replacer</artifactId>
    <version>1.5.3</version>
    <executions>
        <execution>
            <id>first-execution</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>replace</goal>
            </goals>
            <configuration>
                <includes>
                    <include>${basedir}/src/main/java/com/my/package/Constants.java</include>
                </includes>
                <replacements>
                    <replacement>
                        <token>@FOO@</token>
                        <value>${my.custom.property}</value>
                    </replacement>
                </replacements>
            </configuration>                        
        </execution>
        
        <execution>
            <id>second-execution</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>replace</goal>
            </goals>
            <configuration>
                <includes>
                    <include>${basedir}/src/main/java/com/my/package/Constants.java</include>
                </includes>
                <replacements>
                    <replacement>
                        <token>${my.custom.property}</token>
                        <value>@FOO@</value>
                    </replacement>
                </replacements>
            </configuration>                        
        </execution>                    
    </executions>
</plugin>

But this second step can be dangerous, as there can be conflicts and replace something that has the same value in the java code of the class.

Another alternative would be to replace in the .class files as follows:

<plugin>
    <groupId>com.google.code.maven-replacer-plugin</groupId>
    <artifactId>replacer</artifactId>
    <version>1.5.3</version>
    <executions>
        <execution>
            <phase>generate-sources</phase>
            <goals>
                <goal>replace</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <includes>
            <include>${basedir}/target/my-artifact-directory/WEB-INF/classes/com/my/package//Constants$PATHS.class</include>
        </includes>
        <replacements>
            <replacement>
                <token>@FOO@</token>
                <value>${my.custom.property}</value>
            </replacement>
        </replacements>
    </configuration>
</plugin>

The replacement works but the application does not start correctly. Any other ideas on how to perform the replacement without modifying the original code?

Upvotes: 6

Views: 2829

Answers (1)

Gerold Broser
Gerold Broser

Reputation: 14762

I'd create a resource file in src/main/resources that is read in FOO and use the Maven Resources Plugin's Resource Filtering similar to the answer to spring maven profile - set properties file based on compilation profile:

foo.properties

BASE=${propertyName}

pom.xml

<project>
  ...
  <properties>
    <propertyName>property value</propertyName>
  </properties>

  <build>
    <resources>
      <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
      </resource>
    </resources>
    ...
  </build>
  ...

Upvotes: 0

Related Questions