log4j.properties in my /src/test/resources is not overriding main - maven

How do I get my src/test/resources/log4j.properties file to override my /src/main/resources/log4j.properties during testing? The first ends up under target/test-classes, and the second is under target/classes.
Yes, I've looked for duplicates, but in this case, I don't have a mix of loggers - I'm using
only slf4j-log4j12.

You could use maven profiles combined with filtering and maven-war-plugin, all in pom.xml. With this you can define what you need to have in log4j.properties.
Example with logback:
Defining a variable in config.test.properties:
basepath_log=/var/log/ProjectName
Defining a placeholder in logback.xml (equivalent to log4j.properties):
<appender>
...
<file>${basepath_log}/ProjectName.log</file>
...
</appender>
Profile definition:
<profiles>
<profile>
<id>test</id>
<properties>
<targetenv>test</targetenv>
</properties>
</profile>
</profiles>
Filtering (pom.xml):
<filters>
<filter>src/main/resources/filter/config.${targetenv}.properties</filter>
</filters>
Then you could use profiles directly with maven using option -Ptest or selecting it in your IDE (Netbeans, Eclipse...)

Sorry, my bad. This bug suggested maybe my issue was a dependency on a bad version. Sure enough - 2.3 was too old; updated version behaves as expected.

Related

How does maven replace text #env# in application.yml?

There is some profiles defined in pom.xml.
<profile>
<id>test</id>
<properties>
<env>test</env>
</properties>
</profile>
spring.profiles.active: #env# defined in application.yml and bootstrap.yml.
When I run mvn install -P test, text #env# in application.yml would be replaced by test.
How does it work?
Why it does't work for bootstrap.xml?
It works for application.yml because you are obviously using the Spring Boot Starter Parent. See the POM here: https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-starters/spring-boot-starter-parent/pom.xml
The magic part is the <resources> configuration within that parent POM. You see that the application config files are explicitly copied with filtering. That is why the maven-resources-plugin resolves placeholders in these files.
If you want to add more files to be handled like this you can add your own <resources> section to your POM and extend it by more file patterns.

maven update pom property

I'm looking for a way to update pom property to given value, i.e. my pom.xml contains:
<properties>
<abc.def>aaaaa</abc.def>
<properties>
now i want to call :
mvn some_plugin:some_goal -Dabc.def=XYZ
and finally my pom.xml should looks like
<properties>
<abc.def>XYZ</abc.def>
<properties>
I was reading about maven-release-plugin & versions-maven-plugin but i do not see there any matching goal.
Thank you in advance for any reply.
mvn versions:update-properties -Dproperties=[XYZ] -DincludeProperties={abc.def}
Read more here.
and here.
In short:
In versions-maven-plugin, the update-properties goal sets properties to the latest versions of specific artifacts.
includeProperties is a comma separated list of properties to update.
properties are any restrictions that apply to specific properties.
The accepted answer does not work for arbitrary values since it performs sanity checks (links to the documentation for set-property goal since for some reason the documentation for update-properties does not mention this).
To set some arbitrary value on a property use set-property since - as documented - it skips sanity checks:
mvn versions:set-property -Dproperty=your.property -DnewVersion=some_value
Ok, i found some case of solution. I'm using maven-replacer-plugin where:
my properties definition in pom.xml :
<properties>
<abc.def>aaaaa</abc.def>
<properties>
my plugin configuration :
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.2</version>
<configuration>
<file>pom.xml</file>
<replacements>
<replacement>
<token>${abc.def}</token>
<value>${replacer.abc.def}</value>
</replacement>
</replacements>
</configuration>
</plugin>
and finally my maven invocation :
mvn replacer:replace -Dreplacer.abc.def=XYZ
It works for me but I don know is there any better way to achieve it with maven-relase-plugin and/or versions-maven-plugin as #khmarbaise and #Conan said.
I agree with #khmarbaise above, the versions-maven-plugin will do just this, or you could move to the Maven Release Plugin if you want a much heftier approach to managing your versions, but you could also just run a script to sed the pom.xml file using Jenkins' BUILD_NUMBER environment variable, which is a quicker and dirtier approach.

Enable certain Maven tests by passing a command line switch

I have a single module project that has some unit tests that require an external hardware device. I don't want these tests to execute unless I indicate that the device is available.
I feel like this is solvable using Maven properties and the SureFire exclusion/inclusion configuration, but I can't quite see how to do it. A similar question shows how to disable/enable all the tests in a project based on a Maven property, but doesn't quite answer my issue.
In summary, I wish to identify a pattern (e.g. **/*ResourceTest.java) that describes the tests I don't want to run, unless I pass a Maven property to enable them.
E.g.
mvn clean install (runs the standard tests, but skips device-related tests)
mvn -Drun.device.tests=true clean install (runs all the tests)
Thanks in advance.
(Edited to remove the misleading usage of the word "resource" > replaced with "hardware device").
You also can just use the JUnit Assume methods to decide (inside the test) if a test should be executed or skipped.
The best option IMHO would however be to 'declare' the device dependend tests to be "integration tests" and let them be executed by the Maven Failsafe Plugin. I think this would be the "build in" maven solution without any profile 'magic'.
The link you provided gave the good answer.
The right way
Use a mix of Profile Management and Surefire Configuration inclusion / exlcusion is the right way.
You should ask yourself WHY you want to activate some tests dependings on a resource. The resource should always been in your classpath.
If not, you probably just want to activate some test manually, for some tricky reasons. In that case consider this is a bad use of Maven (how would you automate that on a distant server for instance ?)
What you asked
If you really really want to do that, because you have some good reasons that we are not aware of, simply use this :
This example will trigger the profile when the generated file target/generated-sources/axistools/wsdl2java/org/apache/maven is missing.
Example from Maven official doc : http://maven.apache.org/guides/introduction/introduction-to-profiles.html
<profiles>
<profile>
<activation>
<file>
<missing>target/generated-sources/axistools/wsdl2java/org/apache/maven</missing>
</file>
</activation>
...
</profile>
</profiles>
As of Maven 2.0.9, the tags and could be interpolated. Supported variables are system properties like ${user.home} and environment variables like ${env.HOME}. Please note that properties and values defined in the POM itself are not available for interpolation here, e.g. the above example activator cannot use ${project.build.directory} but needs to hard-code the path target.
You could find more information here : http://www.sonatype.com/books/mvnref-book/reference/profiles-sect-activation.html
Hope that will help.
Don't hesitate to challenge my point of view with you own reasons (even legacy code ;) ) or experience
To expand on #Jean-Rémy answer, I have done the following in my project POM file:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12</version>
<configuration>
<excludes>
<exclude>${tests.to.skip}</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<!-- This profile will be used when running tests without a device -->
<id>default-profile</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<tests.to.skip>**/*DeviceTest.java</tests.to.skip>
</properties>
</profile>
<profile>
<id>device-profile</id>
<activation>
<property>
<name>device</name>
<value>true</value>
</property>
</activation>
<properties>
<!-- Unsure how to match nothing -->
<tests.to.skip>NOTHING</tests.to.skip>
</properties>
</profile>
This creates two profiles, the default profile will exclude the device tests, whereas the "device-profile" will execute all tests.
To execute the device profile, one can execute mvn -Ddevice=true test.

read Maven variable from properties file using profile

I want to read a maven variable for configure a build plugin from a properties file. It's not needed in and further project files e.g. context files.
1) made a profile (it works, can use mvn ... -P private)
<profile>
<id>private</id>
<properties>
<env>private</env>
</properties>
</profile>
2) created the filter file with this content (it works)
foo.path=/home/foo/path
3) try to configure the plugin (does not work)
<build>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>foo-plugin</artifactId>
<version>${foo-plugin.version}</version>
<configuration>
<!--<fooPath>home/foo/path></fooPath> that works -->
<fooPath>${foo.path}</fooPath> <!--works not -->
</configuration>
...
</build>
Thx a lot
The name of your property is 'env' but you don't use env anywhere in your configuration.
When Maven docs mention "filter files" they usually mean a file used when processing resources (i.e. copying resources from /src/main/resources to target/classes). As far as I know the properties in those files aren't used for plugin configuration out-of-the-box. I have used the Codehaus properties-maven-plugin:read-project-properties goal do do what you are attempting. Make sure you bind the goal to the lifecycle before any plugins that need the properties for config.
Also, see this answer; you may load properties used to configure other plugins, but not to configure core Maven project elements.

I can't get maven to use properties defined in ~/.m2/settings.xml?

I am using ~/.m2/settings.xml to store a number of property names used throughout the pom.xml files in my project. If I make the XML invalid (by adding another < for example), maven immediately generates an error, saying that it cannot parse that file. If I leave the XML valid, settings in my appBeans.xml file do not pick of references to properties defined in settings.xml.
Has anyone experienced this problem? I am sort of at my wits end here.
Reflecting properties from Maven configurations works by resources filtering.
Make sure your settings.xml, project pom and the target xml file contain correct configurations and reside in correct places.
If I understood correctly, you want to store a property name and value in the settings.xml so the props can be used in your project files. I'll provide a working example:
Define a default profile and properties in settings.xml:
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<someProp>Value</someProp>
</properties>
</profile>
</profiles>
Define resource folder's filtering=true in pom.xml:
<build>
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
Define the property in the xml file (that resides in the src/main/resources folder):
...
<element>${someProp}</element>
...
After this you should see the filtered result e.g. in target/classes/appBeans.xml.
Bear in mind that if you're using Eclipse & m2eclipse or similar plugin, it probably won't start using the updated settings.xml without restarting Eclipse and it's automatic build will sometimes overwrite your files in the target folder. I'm talking from experience here :)
Maven properties do not get reflected in miscellaneous XML files.
If you add one of these properties to the <properties/> element of the specific pom that runs the specific plugin that reads allBeans.xml, does that work? I believe that it will not, and your problem will turn out to be adding to the <configuration/> for the plugin to pass the maven properties to it.
If you edit your question to show the plugin that processes appBeans.xml I can make this more specific.

Resources