Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

POM

...

Expression

...

evaluation

...

Expressions

...

in

...

the

...

pom

...

generally

...

look

...

like

...

this:

Code Block


{code} ${foo}{code}

or

Code Block


{code} ${bar.baz}{code}

The

...

bar

...

in

...

the

...

last

...

example

...

can

...

be

...

a

...

special

...

token:

...

pom

...

,

...

env

...

,

...

or

...

the

...

legacy

...

project

...

which

...

is

...

deprecated

...


and

...

means

...

the

...

same

...

as

...

pom

...

.

...


In

...

this

...

case

...

bar

...

is

...

called

...

a

...

prefix

...

and

...

the

...

baz

...

expression

...

is

...

evaluated

...

against

...

the

...

project

...

model

...


using

...

reflection,

...

so

Code Block

 
{code} ${pom.version}{code}

evalueates

...

to

...

the

...

value

...

of

...

the

...

<project><version>

...

tag.

...

If

...

the

...

prefix

...

is

...

env

...

,

...

the

...

expression

...

evaluates

...

to

...

the

...

value

...

of

...

System.getEnv(

...

"baz"

...

);

...

In

...

all

...

other

...

cases,

...

if

...

the

...

prefix

...

is

...

NOT

...

pom

...

or

...

env

...

,

...

the

...

current

...

context

...

is

...

consulted.

...


It

...

typically

...

contains

...

the

...

basedir

...

value,

...

the

...

system

...

properties,

...

and

...

any

...

key/value

...

pairs

...

specified

...

with

...

the

...

-Dkey=value

...

commandline

...

option.

...

When

...

the

...

context

...

does

...

not

...

contain

...

the

...

value

...

for

...

the

...

expression,

...

the

...

POM

...

properties

...

are

...

consulted.

...

Maven

...

2.0.x

...

behaviour

...

In

...

Maven

...

2.0.x

...

the

...

prefix

...

was

...

discarded

...

if

...

it

...

was

...

pom

...

,

...

project

...

,

...

or

...

env

...

.

...

The

...

remaining

...

expression

...

was

...

evaluated

...

using

...

the

...

following

...

algorithm:

...

  • check

...

  • the

...

  • context;

...

  • if

...

  • the

...

  • key/value

...

  • exists,

...

  • use

...

  • that.

...

  • If

...

  • the

...

  • key

...

  • exists

...

  • but

...

  • the

...

  • value

...

  • is

...

  • null,

...

  • skip

...

  • this

...

  • term,

...

  • and

...

  • leave

...

  • the

...

  • _$

...

  • {expression

...

  • }

...

  • as

...

  • is.

...

  • check

...

  • the

...

  • model

...

  • properties.

...

  • If

...

  • that

...

  • value

...

  • exists,

...

  • use

...

  • that.

...

  • check

...

  • the

...

  • model

...

  • using

...

  • reflection.

...

  • If

...

  • that

...

  • yields

...

  • a

...

  • value,

...

  • use

...

  • that.

...

  • check

...

  • the

...

  • environment

...

  • variables

...

  • if

...

  • the

...

  • expression

...

  • refers

...

  • to

...

  • itself

...

  • abort.

...

  • This

...

  • check

...

  • is

...

  • broken

...

  • in

...

  • several

...

  • ways:

...

    • it

...

    • tests

...

    • for

...

    • string

...

    • equality

...

    • but

...

    • both

...

    • pom.*

...

    • and

...

    • project.*

...

    • refer

...

    • to

...

    • the

...

    • same

...

    • object.

...

    • so

...

    • "${pom.foo}"

...

    • evaluating

...

    • to

...

    • "${project.foo}
      "

...

    • will

...

    • introduce

...

    • recursion:

...

    • since

...

    • it

...

    • discards

...

    • the

...

    • prefix,

...

    • Code Block

...

    • 
      <scm><connection>${scm.connection}</connection></scm>

...

    • 
      
      will introduce recursion.
    • it only checks 1 level deep:
      Code Block
      
      <properties><foo>${bar}</foo><bar>${foo}</foo></properties>

...

    • 
      
      .

...

    • Even

...

    • if

...

    • this

...

    • works,

...

    • try

...

    • adding

...

    • another

...

    • level,

...


    • or

...

    • even

...

    • this:

...

    • Code Block

...

    • 
      <properties><foo>${pom.bar}</foo><bar>${foo}</bar></properties>

...

    • 
      
      .

Some unexpected results can occur, and have caused some bugs. Poms containing _${pom.version

...

}

...

or

...

even

...

_$

...

{version

...

}

...


can

...

break

...

the

...

build

...

if

...

-Dversion=foo

...

is

...

supplied

...

on

...

the

...

commandline.

...

So,

...

expressions

...

like

...

$

...

{version

...

}

...

or

...

$

...

{artifactId

...

}

...

,

...

or

...

even

...

$_

...

{pom.version

...

}

...

can

...

cause

...

all

...

sorts

...

of

...

problems.

...

Final

...

algorithm.

...

The

...

algoritm

...

is

...

simple,

...

were

...

it

...

not

...

for

...

backwards

...

compatibility

...

check

...

due

...

to

...

the

...

enormous

...

amount

...

of

...

faulty

...

poms

...

in

...

the

...

repository.

...


Therefore,

...

we'll

...

use

...

the

...

new

...

approach

...

but

...

still

...

support

...

legacy

...

(broken)

...

poms,

...

though

...

the

...

behaviour

...

may

...

be

...

a

...

little

...

bit

...

different.

...

The

...

first

...

problem

...

we

...

need

...

to

...

solve

...

is

...

the

...

fact

...

that

...

both

...

$

...

{pom.version

...

}

...

and

...

_$

...

{version

...

}

...

are

...

resolved

...

using

...

the

...

same

...

algorithm.

...


This

...

will

...

solve

...

the

...

problem

...

of

...

commandline

...

arguments

...

and

...

system

...

properties

...

inadvertedly

...

overriding

...

pom

...

attributes,

...

like _${version}.
Only if the expression has a pom. or project. prefix, reflection will be used.

Here's the complete algorithm:

  • determine the prefix: there is only a prefix if the expresssion starts with pom., project., or env.. In all other cases there is no prefix (it equals the empty string).
  • if the prefix is project., log warning about project. prefix deprecation and replace it with the pom. prefix.
  • if the expression has a prefix of pom., evaluate using reflection. If no result found, continue.
  • if the expression has a prefix of env., evaluate using environment vars. If no result found, continue.
  • check the context for the full expression, including prefix. If there was a key, but the value was null, don't touch this expression, but leave it as an expression in the original string, and continue to the next expression. If the key didn't exist, continue.
  • check the model properties for the full expression, including prefix. If the value is null, continue.
  • if all this still didn't yield a result, fall back to legacy behaviour: apply the prefix-stripped expression on the model; both ${version} and _${pom.version} will result in _<project><version>.