Search code examples
mavenpom.xmlmaven-profiles

how to understand the value !false in maven profile


I encounter a very strange question when using profile in maven.The code segment is below.

<profile>
        <id>update-jboss-as</id>
        <activation>
            <property>
                <name>release</name>
            </property>
        </activation>
        <modules>
            <module>ddd-djn</module> 
            <module>jboss-as</module>
        </modules>
    </profile>

I have not set release property, so this profile can't be activated, the module will not execute, now everything is ok.

but when I add a code line and the code segment as below:

 <profile>
        <id>update-jboss-as</id>
        <activation>
            <property>
                <name>release</name>
                <value>!false</value>
            </property>
        </activation>
        <modules>
            <module>ddd-djn</module> 
            <module>jboss-as</module>
        </modules>
    </profile>

the new added content is <value>!false</value>

in my mind, the profile will not be activated either. It will be activated only there exist release property and its value is not false, and here I have not set the release property at all. Strangely, in practice this profile is activated.

Question: I don't know why this happens, maybe the value !false has unique meaning?


Solution

  • The issue is reproducible with any name and value:

    <profile>
        <id>test-profile</id>
        <activation>
            <property>
                <name>something</name>
                <value>!a</value>
            </property>
        </activation>
        ...
    </profile>
    

    The profile above will actually be active by default. This is in contradiction with the official Maven profile documentation on the !true value example:

    The following profile will be activated when the system property "debug" is defined with a value which is not "true".

    Note: bold is mine.

    Since such a property name (any) would not be inherited by a potential default property defined in the super POM, then indeed it is not defined and as such it should not match the condition. However, it seems like the ! operator plays an important role adding to the rule also the case to activate the profile when the property is not specified (as such, not being specified would also mean it did not provide the value, matching the value condition, but indeed slightly changing the name part).


    If the mechanism is still implemented by the SystemPropertyProfileActivator, deprecated but not documented by which componenet it was replaced, if already replaced, then the bug is confirmed by the following shortened code:

    ActivationProperty property = activation.getProperty();
    
    if ( property != null ) {
        String name = property.getName();
        boolean reverseName = false;
    
        String sysValue = properties.getProperty( name );
    
        String propValue = property.getValue();
        if ( StringUtils.isNotEmpty( propValue ) ) {
            boolean reverseValue = false;
            if ( propValue.startsWith( "!" ) ) {
                reverseValue = true;
                propValue = propValue.substring( 1 );
            }
    
            // we have a value, so it has to match the system value...
            boolean result = propValue.equals( sysValue );
    
            if ( reverseValue ) {
                return !result;
            }
            else {
                return result;
            }
        }
    }
    

    The issue is: the sysValue real property value by the defined name is not taken into account, it will be null in this specific case. However, its check on equals will return false, but then the further check on reverseValue would turn it to true, regardless of the existence of the name property and effectively activating the profile in this case.


    Update
    Following the related bug report I reported on the official Maven JIRA, the issue has been clarified: it is not a bug but rather wrong documentation.
    Hence the expected behavior is indeed to have the profile active by default with such a configuration.