Configure log4j.properties file location when packing to jar - java

I have a concern that where do we have to put log4j.properties file when packaging to jar file by using maven.what is the best practice here.

General recommendation
Put it into src/main/resources. You may want to define a more verbose log4j configuration in src/test/resources, if you do use junit tests.
See maven standard directory layout.
Setting a new configuration for specific executions
If you want to create an executable jar with a main method, you can ship a default configuration in src/main/resources and still provide an overriding log configuration when starting your jvm, using this jvm parameter: -Dlog4j.configuration=file:"<FILE_PATH>".
Building for multiple environments
You can also create multiple subfolders in your resource configuration and have the maven resource plugin copy the correct log4j.xml to the destination via maven profiles.

Related

Ignore log4j2.properties from dependency jar

I have a Maven project, running correctly. I am using a log4j2.xml file to configure the logging. Until today everything was working fine. But now, I have included a dependency of a third-party jar that has its own log4j2.properties file. Unfortunately, this is overwritting my own configuration.
Is there any way I can ignore, exclude... that property file?
Actually, the other answers are incorrect as they are advising you to use the system property log4j 1.x uses, not what Log4j 2 uses.
For Log4j 2 you want to use -Dlog4j2.configurationFile=/path/to/log4j2.xml. If you only specify -Dlog4j2.configurationFile=log4j2.xml then Log4j will look for that file on the class path. Obviously the name can be anything you want. Log4j also supports putting the system properties in a file named log4j2.component.properties so if you do not want to specify them on the command line you can include them in a Java Properties file with that name in your application.
No matter what you do you should open a bug with the third party as putting a logging configuration file in a library jar is a bad practice.
You can add an option to specify your own log4j properties file with
-Dlog4j.configuration=path/to/my.properties
and thats better than excluding everytime a new library tries to override your properties file.

How do I specify a logback configuration for use in a Java webstart application?

I want to add logging to a number of internal Java webstart applications, preferably using the logback logging framework and logback.groovy configuration files. I expect to specify this in the webstart application .jnlp file, but it's not clear how to do this.
I have tried adding the logback.groovy file in the resources of my main jar (i.e. that which contains my main method), but that didn't get picked up by logback.
I have also tried various attempts to add the logback.groovy file to the <resources> section of the .jnlp file:
<jnlp ...>
<resources>
<j2se version="$j2seVersion" />
$dependencies // from maven-webstart-plugin
// some reference to my logback configuration - e.g.
<dir href="log/" />
</resources>
</jnlp>
It's worth noting that logback expects the configuration files to be referenced on the classpath as the folder in which it resides, not to the file itself - see FAQs.
However, I'm really not sure how this would apply to Java Webstart.
Is this possible? If so, how do I do this?
So... the approach that I ended up using for this was (in line with Askel's comments) to put the logback.groovy configuration file into /src/main/resources.
However, we use our Java libraries in a number of different ways, and I didn't want to include the logback configuration file in the jar by default. In part, this is because we have several libraries, and logback doesn't play nicely with multiple configuration files. Also depending on the release, I wanted to use different logback configurations.
For our webstart releases, we use the webstart-maven-plugin to build the library, assemble the dependencies etc. But before doing this build, we copy the logback.groovy configuration file to /src/main/resources - this includes the file in the build for that library. Then, after the build/release, you can remove the configuration file from /src/main/resources.
However, this plugin will also run mvn install, which will put the library with the logback configuration file in your local maven repository. Therefore, after the build/release/temp configuration removal, we do another mvn clean install, which will overwrite that library.

Mock a config file

I'm writing tests for an app that refers to a hardcoded filename "classpath:config.properties". It isn't possible to change this name. Is there any way to test this app with different configs? i.e. different tests supply different configs at runtime?
This is an odd requirement, but I'd deeply appreciate any inputs
Here is another question that might help you:
Dynamically loading properties file using Spring
Or you can always overwrite the properties file using the Java IO libraries.
It's all about classpath - what jars are in classpath and how you organize your project structure.
User maven so that resources from 'src/test/resources' are loaded before 'src/main/resources'. But generally the best way is to separate application-specific config resources from application code.
Alternatively, you can split the project with config resources into 3 or 4 projects:
project with code
project with config resources, added to app classpath, but not to test classpath
project with test resources, added to test classpath, but not to the app classpath
optionally, you can move JUnit test code to separate project
If you load your configuration from classpath:config.properties then these properties reside in src/main/resources folder.
When you run tests you can put your mock configuration in src/test/resources and it will "override" main configuration.

Multiple log4j.properties files

This might not seem a valid question but I have a requirement here. Below is my project structure:
common (built as a jar)
module-1 (war, includes common.jar in its classpath)
module-2 (war, includes common.jar in its classpath)
module-3 (war, includes common.jar in its classpath)
module-4 (war, includes common.jar in its classpath)
The deployment is like below:
module-1 and module-2 is on one server and module-3 and module-4 on another.
The requirement is to have two separate log files(one for each server). So, the way to achieve this is put the log4j.properties (definitely with different names) in the common module and copy the required properties file to the respective server's conf folder.
I am not sure, if I can have the logging properties file with different names, if it is possible, please help me with a direction to do so.
EDIT To make this easier, if you anyone can tell me if I can use a different name for the log4j.properties file and how to load it to the server, I would be able to achieve the rest.
Thanks.
I finally fixed this issue, and yes there is a way of using a name different than log4j.properties for the log4j configuration properties file.
We can name it whatever we want say mylog4j.properties. For the JVM to pick this up we need to pass an argument to the JVM like below:
-Dlog4j.configuration=mylog4j.properties
When running applications using eclipse, you can do this by going to Run Configurations -> Arguments Tab -> VM Arguments and add the property
-Dlog4j.configuration=mylog4j.properties

How are dependencies in multiple log4j.properties files managed under Maven?

I have a maven project with several dependencies and use log4j.properties to control output. In some cases the same class may be referenced in different property files with different parameters. Is there a defined protocol for "overriding" properties or does it depend on the order in which packages are loaded?
(I am locating all log4j.properties directly under src/main/resources - is this the correct place?)
UPDATE:
I have accepted #Assen's answer as it makes sense though it doesn't make the solution easy. Essentially he recommends excluding log4j.properties from the jar. In principle I agree, but it puts the burden on the user to control the output and most of my users don't know what Java is, let alone properties files.
Maybe there is a way of renaming the properties files in each jar and using a switch (maybe with -D) to activates the properties.
I often have similar discussions on projects. I thing log4j.properties is typically something you want to keep out of the application, and not pack it in a war and deliver it together with the code. Logging configuration:
is environment specific. When you write the application, you simply can't define the appenders that will be desired, file locations etc.
its lifecycle is totally different than the application's. After an application is deployed, logging properties can be changed several times a day. Redeploying the application shouldn't override your last logging settings.
Why package logging configuration together with your code then? I usually keep somewhere a configuration folder, with soubfolders like 'dev', 'test-server-01', 'macbook-john' etc. Each subfolder contains list own copy of log4j.properties. None of them is included in the build artifact - jar or war.
When deploying, one of thuse subfolders is delivered separately. For the test server 1, this would be the content of test-server-01 subfolder. Dependng on the application server used, thers is a different trick tu put some files on the classpath.
When developing, I take care to set one of those subfolders on the path. When John develops on his macbook, he might want to put 'macbook-jihn' on the classpath, or create a new one. He can change logging settings and commit without conflicts.

Categories