135

Where should I put the log4j.properties file when using the conventional Maven directories?

kc2001
  • 4,580
  • 4
  • 40
  • 79
user496949
  • 75,601
  • 138
  • 297
  • 413
  • 6
    src/test/resources - the consumer of your artifact would set the logging levels required for deployment. I would however recommend slf4j if you're doing this for commercial work. This gives the option of switching logging frameworks at deployment. http://www.slf4j.org/ – David Victor Feb 27 '11 at 10:23
  • 2
    BTW if you just wish to experiment its possible to use log4j without a properties/xml config file. From 'http://logging.apache.org/log4j/1.2/manual.html - Configuration' "The invocation of the BasicConfigurator.configure method creates a rather simple log4j setup." Also see: http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/BasicConfigurator.html#configure() http://maven.apache.org/plugins/maven-resources-plugin/examples/resource-directory.html – David Victor Feb 27 '11 at 12:58

7 Answers7

148

src/main/resources is the "standard placement" for this.

Update: The above answers the question, but its not the best solution. Check out the other answers and the comments on this ... you would probably not shipping your own logging properties with the jar but instead leave it to the client (for example app-server, stage environment, etc) to configure the desired logging. Thus, putting it in src/test/resources is my preferred solution.

Note: Speaking of leaving the concrete log config to the client/user, you should consider replacing log4j with slf4j in your app.

lambda
  • 3,075
  • 1
  • 24
  • 31
Jan Galinski
  • 10,521
  • 7
  • 48
  • 68
  • I found no resources diretcory be created. Do I need to do it manually? – user496949 Feb 27 '11 at 09:31
  • 3
    yep. Manually create `resources` and `log4j.properties` in the folder mentioned in the answer. – Nishant Feb 27 '11 at 09:49
  • @user496949: files under `src/main/resources` will be copied per default to `target/classes` – splash Feb 27 '11 at 09:54
  • 18
    Unless you intend to export your log4j settings as part of your artifact - it is far better to put it under src/test/resources – David Victor Feb 27 '11 at 10:16
  • why it is better to but it under src/test? – Feras Odeh Sep 27 '11 at 13:22
  • 1
    @FerasOdeh to exclude it from generated artifacts (jars, wars, etc.) and only be used during testing, "Unless you intend to export your log4j settings as part of your artifact". – Ali Shakiba Feb 24 '12 at 06:01
  • This is stupid. You normally want to have logging and applicatiobn properties outside (or alongside) your jar. So you can then modifiy its contents without the need to repackage everything... Or tell me that normal application properties should also be INSIDE the jar as a standard maven way of doing things ? – David Hofmann Apr 14 '14 at 11:57
  • Say suppose if we need to have different log4j settings on test vs prod environments - HOw do we do that in maven ? src/main/resources - Prod ? and src/test/resources - Test ? – Balaji Boggaram Ramanarayan Feb 17 '15 at 21:52
  • There is a lot discussion going on, I updated my answer (from quite a while ago) to reflect these aspects. I myself would not include logging properties in my jars anymore. – Jan Galinski Feb 18 '15 at 09:03
  • @JanGalinski - Can log4j appenders ever be defined inside a pom file ? – MasterJoe Jul 11 '18 at 15:39
  • Not that I would know. You could somehow generate a log4j.properties via maven. – Jan Galinski Jul 11 '18 at 15:40
61

Just putting it in src/main/resources will bundle it inside the artifact. E.g. if your artifact is a JAR, you will have the log4j.properties file inside it, losing its initial point of making logging configurable.

I usually put it in src/main/resources, and set it to be output to target like so:

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <targetPath>${project.build.directory}</targetPath>
            <includes>
                <include>log4j.properties</include>
            </includes>
        </resource>
    </resources>
</build>

Additionally, in order for log4j to actually see it, you have to add the output directory to the class path. If your artifact is an executable JAR, you probably used the maven-assembly-plugin to create it. Inside that plugin, you can add the current folder of the JAR to the class path by adding a Class-Path manifest entry like so:

<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <mainClass>com.your-package.Main</mainClass>
            </manifest>
            <manifestEntries>
                <Class-Path>.</Class-Path>
            </manifestEntries>
        </archive>
        <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
    </configuration>
    <executions>
        <execution>
            <id>make-assembly</id> <!-- this is used for inheritance merges -->
            <phase>package</phase> <!-- bind to the packaging phase -->
            <goals>
                <goal>single</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Now the log4j.properties file will be right next to your JAR file, independently configurable.

To run your application directly from Eclipse, add the resources directory to your classpath in your run configuration: Run->Run Configurations...->Java Application->New select the Classpath tab, select Advanced and browse to your src/resources directory.

Zoltán
  • 19,217
  • 10
  • 81
  • 124
  • 2
    another option might be to put it under src/test/resources so that it doesn't get bundled. – rogerdpack Dec 05 '14 at 17:24
  • Wow. Thanks for that. This was just what I needed! – blissfool Jul 17 '15 at 18:25
  • @Zoltán, I find it hard to go about adding the output directory to the classpath as you've advised. Is there a way I can do it manually, like go into the .classpath file of the particular project and add this log4j output directory there so that log4j can see the .properties file after the app has been bundled to a .war file. Also, the targetPath tag, should the value be used as-is ```${project.build.directory}``` or should be edited to the actual path the project lives in my local drive? – Ercross Apr 11 '20 at 11:03
27

Some "data mining" accounts for that src/main/resources is the typical place.

Results on Google Code Search:

  • src/main/resources/log4j.properties: 4877
  • src/main/java/log4j.properties: 215
splash
  • 12,499
  • 1
  • 40
  • 64
  • 4
    how does this answer differ in any respect than the one answered 20 mins ago? Also, it's `resources` not `resource`, if I remember correctly. – Nishant Feb 27 '11 at 09:48
  • 6
    @Nishant: it's not different, because when I opened the answer box I left the PC. After coming back and answering the question I missed that the question was already answered. `resource` was only a typo. – splash Feb 27 '11 at 09:59
  • @splash that's alright. A good idea is to see the new answer/s when a warning message appears at the top saying, "1 new answer available" – Nishant Feb 27 '11 at 10:14
  • It is not right to put this under src/java - please do not post incorrect Google searches. – David Victor Feb 27 '11 at 10:18
  • @David Victor: the Google search for `src/main/java` was correct, otherwise it wouldn't result in 215 matches. Can't see your problem. – splash Feb 27 '11 at 10:58
  • 1
    I would suggest doing some reading around maven, the maven compiler plugin, conventions for layout of maven projects. Maybe look at what goes where under 'target' when your artifact is built. Then perhaps you might modify your answer. – David Victor Feb 27 '11 at 11:32
  • @David Victor: Sorry David, I still can't get you. I know that `src/main/java` isn't the conventional place, but the OP asks for what is usual and I think some statistics are useful for showing how the conventions are applied. Maybe you are confused, because you are referring to `src/java` in your first comment? – splash Feb 27 '11 at 15:25
  • 4
    The correct answer is src/xxx/resources - it is not a convention. See: http://maven.apache.org/plugins/maven-resources-plugin/examples/resource-directory.html - here 'xxx' may be 'main' or 'test'. Unless you wish to provide pre-configured logging levels it is generally wiser to configure logging as required for testing - via 'src/test/resources' - and allow the consumer of your artifact to set the logging level. – David Victor Feb 27 '11 at 17:19
  • @David Victor: I totally agree with you. I'm only using `src/test/resources` for testing. On production systems the logging configuration is injected via spring beans. – splash Feb 27 '11 at 18:06
  • Glad to hear it. :-) So perhaps it would be helpful to have that reflected in your answer. – David Victor Feb 27 '11 at 18:46
  • 23
    Google results for "Jump off a bridge": 18.200.000. Google results for "Do not jump off a bridge": 137.000 – djjeck Jan 11 '13 at 00:35
  • 1
    @djjeck: Unfortunately I can't search for `"Jump off a bridge"` at Google Code anymore. Would be interesting too. ;-) – splash Jan 11 '13 at 08:52
9

The resources used for initializing the project are preferably put in src/main/resources folder. To enable loading of these resources during the build, one can simply add entries in the pom.xml in maven project as a build resource

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering> 
        </resource>
    </resources>
</build> 

Other .properties files can also be kept in this folder used for initialization. Filtering is set true if you want to have some variables in the properties files of resources folder and populate them from the profile filters properties files, which are kept in src/main/filters which is set as profiles but it is a different use case altogether. For now, you can ignore them.

This is a great resource maven resource plugins, it's useful, just browse through other sections too.

Ofri Raviv
  • 22,321
  • 3
  • 51
  • 54
devastator
  • 321
  • 3
  • 4
6

When putting resource files in another location is not the best solution you can use:

<build>
  <resources>
    <resource>
      <directory>src/main/java</directory>
      <excludes>
        <exclude>**/*.java</exclude>
      </excludes>
    </resource>
  </resources>
<build>

For example when resources files (e.g. jaxb.properties) goes deep inside packages along with Java classes.

Ali Shakiba
  • 18,573
  • 17
  • 59
  • 86
1

If your log4j.properties or log4j.xml file not found under src/main/resources use this PropertyConfigurator.configure("log4j.xml");

   PropertyConfigurator.configure("log4j.xml");
   Logger logger = LoggerFactory.getLogger(MyClass.class);
   logger.error(message);
ethemsulan
  • 2,113
  • 24
  • 19
0

Add the below code from the resources tags in your pom.xml inside build tags. so it means resources tags must be inside of build tags in your pom.xml

<build>
    <resources>
        <resource>
            <directory>src/main/java/resources</directory>
                <filtering>true</filtering> 
         </resource>
     </resources>
<build/>