I want to be able to use different log4j configuration for different environments.
In my development environment, I want to use log4j.properties (A). But when I build in Maven for the production environment, I want to use log4j.properties (B).
Please tell me how to configure this in my pom.xml?
1. in your project add 3 folders :
Your Project\src\main\resources\
\A > log4j.properties
\B > log4j.properties
\Default > log4j.properties
2. in pom.xml
<properties>
<param>Default</param>
</properties>
<build>
<resources>
<resource>
<directory>src/main/resources/${param}</directory>
</resource>
</resources>
</build>
3.
- if : mvn clean install : classpath => log4j.properties(Default)
- if : mvn clean install -Dparam=A : classpath => log4j.properties(A)
- if : mvn clean install -Dparam=B : classpath => log4j.properties(B)
> much better than using profiles is more extensible without touching the pom
You can use profiles to achieve the desired behavior:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>log4j</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>output_directory</outputDirectory>
<resources>
<resource>${log4j.file}</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<log4j.file>path_to_file_A</log4j.file>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<log4j.file>path_to_file_B</log4j.file>
</properties>
</profile>
</profiles>
You don't need the maven-resources-plugin if you have a simple environment.
In this example, log4j.properties B
is the file you use for production and is in the directory src/main/java
and log4j.properties A
is the file you use for development and is in the directory /Users/junger/.m2/
.
In your pom.xml:
<properties>
<log4j.properties.directory>src/main/java</log4j.properties.directory>
</properties>
<build>
<resources>
<resource>
<directory>${log4j.properties.directory}</directory>
<includes>
<include>log4j.properties</include>
</includes>
</resource>
</resources>
</build>
Now, in your /Users/junger/.m2/settings.xml (create one if it doesn't exist):
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<log4j.properties.directory>/Users/devuser/.m2/</log4j.properties.directory>
</properties>
</profile>
</profile>
By using this method, each developer can have a different log4j.properties directory and you keep your pom.xml clean.
Simplest way for me,
- Define a system variable ENV and set its value _dev for your development env.
- Where you refer this file use like this log4j${ENV}.properties
So,
In production it simply use log4j.xml and for your dev log4j_dev.xml
- In order to prevent problems it would be better to create also ENV variable for production as _pro so for production log4j_pro.xml, for dev log4j_dev.xml will be used.
I believe that relying on different files than copying resource is better practice.
To some extent you can reference environment variables inside a log4j.properties to add environment dependent behavior.
e.g.
log4j.rootLogger=${rootLoggerLevel}, ${appender}
There is a very simple solution good for small projects with jar
packaging (I haven't tested it on war
packaged projects). The only disadvantage is that you have to duplicate all resources, but if your only resource is log4j.properties
this is not a problem.
If you have a directory tree like this:
...
You should have the following pom:
<build>
<finalName>${project.artifactId}</finalName>
<sourceDirectory>src/</sourceDirectory>
<resources>
<resource>
<directory>${resources.path}</directory>
</resource>
</resources>
</build>
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<resources.path>resources/prod</resources.path>
</properties>
</profile>
<profile>
<id>dev</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<resources.path>resources/dev</resources.path>
</properties>
</profile>
</profiles>
Then when you use dev
profile log4j.properties
from resources/dev
is used. When you use any other profile or no profile at all then log4j.properties
from resources/prod
is used. So your *.jar
should look like this:
Of course if you have different resources location, for example main/java/resources/...
, you should specify it instead of resources/...