Home > Maven > Maven – Disabling (escaping) properties interpolation

Maven – Disabling (escaping) properties interpolation

It seems someone up there is taking a great care of me so that I have some kind of unique problem to solve on a daily basis. That’s Ok, I don’t mind, keep on doing that, whoever you are ..

Today I had this weird case with Maven’s properties interpolation. Interpolation in dynamic languages is a process of replacing ${project.build.directory} property (or expression) with it’s actual value. It happens on different levels: in Ant, Perl and Groovy it happens inside strings: “this is just an ${example} (Groovy’s GStrings provide a complete EL inside ${…}, much like JSP EL, which is .. well, groovy!). In Maven, interpolation is mostly known as filtering (which is done by “maven-resources-plugin” via “maven-filtering”) and <properties> where one can define a property as <artifactsDir>${project.build.directory}</artifactsDir> (related issues: 1, 2, 3, 4).

Maven also interpolates variables that are specified in plugin configurations:

<properties>
    <somePath>${project.basedir}/../../</somePath>
</properties>
...
<configuration>
    <root>${somePath}</root>
</configuration>

Here Mojo “root” parameter will be assigned a value of ${somePath} property defined above which is project’s basedir + two directories up.

So far so good. Right now I’m working on a plugin that is capable of making replacements in files copied (similar to filtering but using inline “from” pattern and “to” replacement that do not involve any Maven properties, I think it’s more convenient in some cases):

 

<resource>
    <targetPath>${directory.to.copy.the.file.to}</targetPath>
    <file>${directory.to.take.the.file.from}/build.xml</file>
    <replace>
        <to>
            <![CDATA[
<project default="run">
    <target name="run">
        <exec executable="${basedir}/some.exe" spawn="true"/>
    </target>
</project>
            ]]>
        </to>
    </replace>
</resource>

Here <from> tag is missing which means that all content of a file copied will be replaced by the content of a <to> tag. Which is what I’m doing here – generating a new “build.xml” file that <exec>s an .exe file, residing in the same directory where “build.xml” is generated. Note ${basedir} – that’s an expression I want to appear in generated “build.xml”. Unfortunately, Maven replaces it with value of ${project.basedir} which is POM’s current directory (so I end up with hardcoded POM’s basedir in the generated Ant file). Neither of suggested solutions to escape interpolation worked for me: \${basedir}, $${basedir}, ${dollar}{basedir}. Whatever I did – Maven (v2.2.0) was pretty determined to make a replacement! In the end, I’ve decided to trick it and generate a file in two phases:

  1. I’m writing just {basedir} to the file and no Maven interpolation is triggered
  2. I append a $ to it with \$$$1: $1 is original ${basedir} matched by <from> pattern and \$$ is a dollar .. yeah, it took me some time to figure it out)
                                

<resource>
    <targetPath>${directory.to.copy.the.file.to}</targetPath>
    <file>${directory.to.take.the.file.from}/build.xml</file>
    <replace>
        <to>
            <![CDATA[
<project default="run">
    <target name="run">
        <exec executable="{basedir}/some.exe" spawn="true"/>
    </target>
</project>
            ]]>
        </to>
    </replace>
</resource>
<resource>
    <targetPath>${directory.to.copy.the.file.to}</targetPath>
    <file>${directory.to.copy.the.file.to}/build.xml</file>
    <replace>
        <from>(\{basedir\})</from>
        <to>\$$$1</to> <!-- To get a "${basedir}" in output -->
    </replace>
</resource>

I now have a ${basedir} expression in my generated Ant file! Never imagined it could take so long .. But that what makes our profession so nice, isn’t it ?

Advertisements
Categories: Maven Tags: ,
  1. No comments yet.
  1. July 28, 2009 at 18:44
  2. March 19, 2011 at 02:26

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: