Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

log4j configuration file in a multi-module Maven project

I am working on a multi-module Maven project, whose structure is like this:

war-module
jar-module

The war-module depends on the jar-module, and will add the jar artifact into the webapp's lib directory after packaging.

And both the war-module and jar-module use Apache log4j for logging, and share the same log4j configuration file (log4j.xml), which locates in jar-module project at present. And this log4j.xml will be packaged into jar-module.jar file, however, I would like to make it into WEB-INF/classes directory in the war package rather than in the jar file so that users will be easy to find this configuration file and modify it if necessary (it is very hard for them to find it if this file is in the WEB-INF/lib/jar-module.jar because there are many other jars under that directory).

My question is: what is the Maven way to solve this problem?

Update:

My real project is a bit more complex, and there is a ear-module which depends on the jar-module too (aka. the jar-module can be used independently in several different projects, and I cannot just put the file into war-module/src/main/resources directory to fix this problem). And I don't want to duplicate some configuration files such as log4j.xml (and other configuration files such as myapp.properties) across the several projects.

like image 401
nybon Avatar asked Nov 12 '10 09:11

nybon


People also ask

Where should I place log4j properties file?

The file is named log4j. properties and is located in the $DGRAPH_HOME/dgraph-hdfs-agent/lib directory. The file defines the ROLLINGFILE appenders for the root logger and also sets the log level for the file. The level of the root logger is defined as INFO and attaches the ROLLINGFILE appender to it.

Does Maven use log4j?

As you can see in this answer, maven supports SLF4J logging. If you just add the Log4j to SLF4j adapter to the plugin. By adding this dependency, log4j will redirect to SLF4j and SLF4j redirects to the maven logging.


3 Answers

I found the answer via some more searching on the web.

Generally, there are three ways to share resources in a multi module Maven project:

  • Cut and paste them.
  • Use Assembly and Dependency plugins
  • Use the maven-remote-resources-plugin

Here's a blog post from Sonatype, the company behind Maven, on sharing resources across projects in Maven, and it is the exact answer I need:

http://www.sonatype.com/people/2008/04/how-to-share-resources-across-projects-in-maven/

like image 97
nybon Avatar answered Oct 24 '22 02:10

nybon


In the jar module, exclude the file from the jar:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.3.1</version>
    <configuration>
      <excludes>
        <exclude>log4j.xml</exclude>
      </excludes>
    </configuration>
</plugin>

Use the buildhelper plugin to attach the log4j.xml to the build as a separate artifact

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <version>1.5</version>
    <executions>
      <execution>
        <id>attach-artifacts</id>
        <phase>package</phase>
        <goals>
          <goal>attach-artifact</goal>
        </goals>
        <configuration>
          <artifacts>
            <artifact>
              <file>${project.build.outputDirectory}/log4j.xml</file>
              <type>xml</type>
              <classifier>log4j</classifier>
            </artifact>
          </artifacts>
        </configuration>
      </execution>
    </executions>
</plugin>

Now in your war artifact, copy the xml to the output directory:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
      <execution>
        <id>copy</id>
        <phase>prepare-package</phase>
        <goals>
          <goal>copy</goal>
        </goals>
        <configuration>
          <artifactItems>
            <artifactItem>
              <groupId>${project.groupId}</groupId>
              <artifactId>your.jar.project.artifactId</artifactId>
              <version>${project.version}</version>
              <type>xml</type>
              <classifier>log4j</classifier>
              <outputDirectory>${project.build.outputDirectory}
              </outputDirectory>
              <destFileName>log4j.xml</destFileName>
            </artifactItem>
          </artifactItems>
        </configuration>
      </execution>
    </executions>
</plugin>

But of course it would be easier to just put the file in [web-artifact]/src/main/resources in the first place :-)

like image 25
Sean Patrick Floyd Avatar answered Oct 24 '22 04:10

Sean Patrick Floyd


From my experience this can be implemented in an easy way , just :

  1. Make the log4j configuration resource at the parent module.
  2. Call the dependency of log4j in all pom modules.

Detailed steps:

  1. Create a project with common-config
  2. In the src/main/resources folder put the log4j or logback config file
  3. Install the artifact in the local Maven repository to be used by other projects
  4. Add the dependency as a normal Maven dependency in the subsequent projects
<dependency> 
  <groupId>com.your.group.id</groupId> 
  <artifactId>common-config</artifactId> 
  <scope>provided</scope> 
</dependency>

I prefer to use the scope provided and provide the file from a classpath config folder at runtime.

like image 35
Hatem Avatar answered Oct 24 '22 04:10

Hatem