Ways to configure Log4j XML Configuration - java

I am using log4j to log information in my web application. I have chosen log4j.xml type of configuration instead of log4j.properties. I remember that, for log4j.properties configuration, I did not write Java code lines to find the log4j.property file location. However, for log4j.xml file configuration I am specifying explicitly to find it like this
DOMConfigurator.configure("log4j.xml");//it reads file from classpath, working!
Also, tested my application removing the above statement from source. It doesn't see to work. None of the debug statements were printed except
System.out.println();
I have read that log4j by default looks for log4jproperties file or log4j.xml file in the classpath. I checked in the deployed web application, log4j.xml file is in web-inf/classes.
Even though it can't find log4j.xml.
Is it that, the above code line is mandatory for log4j xml configuration in Java?
In fact, can't Java source code doesn't pickup log4j.xml from the classpath without explicit specification as above?

From log4j manual:
The exact default initialization algorithm is defined as follows:
Setting the log4j.defaultInitOverride system property to any other value
then "false" will cause log4j to skip the default initialization
procedure (this procedure).
Set the resource string variable to the value of the log4j.configuration system
property. The preferred way to specify the default initialization file
is through the log4j.configuration system property. In case the system
property log4j.configuration is not defined, then set the string variable
resource to its default value "log4j.properties".
Attempt to convert the resource variable to a URL.
If the resource variable cannot be converted to a URL, for example
due to a MalformedURLException, then search for the resource from the
classpath by calling org.apache.log4j.helpers.Loader.getResource(resource, Logger.class)
which returns a URL. Note that the string "log4j.properties"
constitutes a malformed URL. See Loader.getResource(java.lang.String) for the list of searched locations.
If no URL could not be found, abort default initialization. Otherwise, configure log4j from the URL. The PropertyConfigurator will be used to parse the URL to configure log4j unless the URL ends with the ".xml" extension, in
which case the DOMConfigurator will be used. You can optionaly specify
a custom configurator. The value of the log4j.configuratorClass system
property is taken as the fully qualified class name of your custom
configurator. The custom configurator you specify must implement the
Configurator interface.
So, without code, you can (and should!) define the system property to tell where your config file is. If not, it by default will search for log4j.properties in the classpath. That is the only file it is searching for by default.
System property is usually defined as a startup parameter for your app (app server), something like -Dlog4j.configuration=path/to/your/config.xml.

Related

log4j.properties outside the non executable jar file

I have a library (non- executable) jar file and I need to place the log4j.properties outside the jar.
In executable jar files, I can pass the path through -Dlog4j.configuration. But how can I do it in this case?
From https://logging.apache.org/log4j/1.2/manual.html:
The exact default initialization algorithm is defined as follows:
Setting the log4j.defaultInitOverride system property to any other value then "false" will cause log4j to skip the default initialization procedure (this procedure).
Set the resource string variable to the value of the log4j.configuration system property. The preferred way to specify the default initialization file is through the log4j.configuration system property. In case the system property log4j.configuration is not defined, then set the string variable resource to its default value "log4j.properties".
Attempt to convert the resource variable to a URL.
If the resource variable cannot be converted to a URL, for example due to a MalformedURLException, then search for the resource from the classpath by calling org.apache.log4j.helpers.Loader.getResource(resource, Logger.class) which returns a URL. Note that the string "log4j.properties" constitutes a malformed URL.
See Loader.getResource(java.lang.String) for the list of searched locations.
If no URL could not be found, abort default initialization. Otherwise, configure log4j from the URL.
The PropertyConfigurator will be used to parse the URL to configure log4j unless the URL ends with the ".xml" extension, in which case the DOMConfigurator will be used. You can optionaly specify a custom configurator. The value of the log4j.configuratorClass system property is taken as the fully qualified class name of your custom configurator. The custom configurator you specify must implement the Configurator interface.
You can use PropertyConfigurator.configure to initialize log4j and specify the path to your log4j.properties via a system property, another config file, an environment variable, etc.
However, you may not want to have a separate logging mechanism/configuration for your JAR instead of letting it use the one(s) from the application(s) calling it.

Set where to find the config file for audit4j

I've looked all over the documentation, but was unable to find one. How can I achieve this?
According to the Audit4j documentation and javadoc there are multiple ways to specify the configuration:
It can be injected into the Context directly by calling static methods of the Context class (e.g. at application startup before doing any audit!):
Context#initWithConfiguration(Configuration configuration) with the appropriate Configuration
or Context#initWithConfiguration(String configFilePath) to specify the configuration as file.
Other ways to specify the path to the configuration file without manually initializing the Context are:
Setting path in environment variable "AUDIT4J_CONF_FILE_PATH"
Setting path in Java system property variable "audit4j.conf.file.path"
Also the configuration file can be put into the application classpath or the user directory. In this case the name of the configuration file has to be "audit4j.conf.yml" or "audit4j.conf.yaml" for YAML style or "audit4j.conf.xml" for XML style.

log4j logger overwriting into jxl.log file

I am using log4j for logger purpose. At the same time I am also using JXL to read/write Excel file.
But instead of writing log into log4j logger file, it is writing into jxl.log file.
What can be issue?
Looks like you have been using jxl-2.6.3.jar or similar version.
Log4j picks up the first configuration file with default file name ( i.e. log4j.xml or log4j.properties ) in your classpath if you haven't specified a specific name via JVM parameters. As jxl-2.6.3.jar contains a log4j.xml you ended up printing everything to jxl.log as defined in the log4j.xml
The best way to deal with these kind of problems is to run your application with -Dlog4j.debug JVM parameter. This would print a few line snippet when the log4j is initialized.
log4j: Using URL [jar:file:/C:/YourApp/WEB-INF/lib/jxl-2.6.3.jar!/log4j.xml] for automatic log4j configuration.
log4j: Preferred configurator class: org.apache.log4j.xml.DOMConfigurator
...{Blah Blah Blah}
There are many ways in which you can solve this problem.
Use the newer versions of jxl which doesn't contain log4j.xml.
Make sure your log4j.properties file is on top of classpath.
Remove the log4j.xml from the jxl-2.6.3.jar (Dirty solution).
Pass the configuration file name in VM parameter as -Dlog4j.configuration=log4j.properties. This would atleast make sure log4j.xml inside jxl-2.6.3.jar will not be used. (But what if another jar with same name as log4j.properties?).
Rename your log4j.properties file to log4j-yourApp.properties and add VM parameter -Dlog4j.configuration=log4j-yourApp.properties This would definitely help and this is how it should be done to avoid these kind of situations.
More details on Log4j here

Issue overriding application properties in Spring-boot (profile-specific) application launched with PropertiesLauncher

I'm having difficulty trying to override a property declared in a profile-specific application properties file on the classpath with another value declared in an overrides file on the file system.
I have an auto-configured Spring-boot application (that is, using #EnableAutoconfiguration) that has multiple profiles, which I launch using PropertiesLauncher rather than JarLauncher (the reason having to do with deployment constraints - I need to deploy an exploded directory rather than an archive into a read-only filesystem.)
Within the root of my application, I have some profile-specific application properties, for example:
application-dev.properties
application-qa.properties
application-prd.properties
And let's say, for the sake of argument that application-dev.properties contains:
foo.bar=baz
foo.baz=other
For any environment, it may be necessary to override an existing property, as well as supply an absent one (like a production password, for example), and the issue I'm seeing is with overriding properties already declared in an application-${profile}.properties file on the classpath. (Supplying properties not present in the classpath file works fine, this is not the issue.)
Say I have an overrides properties file in a file system location such as:
/local/appname/dev/overrides/application.properties
and I want to override the property, foo.bar, as well as declare a new property, foo.password.
Therefore the contents of the overrides file are:
foo.bar=overridden-value
foo.password=something
When I launch the application, I use a command line something like this:
java -Dspring.config.location=file:/local/appname/dev/overrides/
-Dspring.profiles.active=dev
org.springframework.boot.loader.PropertiesLauncher
--debug &
The issue I am seeing is that although foo.password, the property not declared in the application-dev.properties file is picked up, the override of foo.bar is ignored - I still see the value, baz from application-dev.properties rather than the value, overridden-value from /local/appname/dev/overrides/application.properties.
With the --debug option enabled, I can see the ConfigFileApplicationListener logging that it has loaded both the overrides file (from the filesystem) and the profile-specific file (from the classpath), in that order.
I'm tempted into the perhaps naïve conclusion that because the overrides file is listed first, it is being loaded first then overridden by the 'default' profile-specific file from the classpath, which is listed later. I do appreciate however, that order of listing in the log doesn't necessarily correlate with behaviour. And I have tried varying the order of paths declared on the spring.config.location property, so that classpath: is listed before file:... but this hasn't helped and I't not convinced it would anyway, given that the Spring-boot documentation clearly states that the default properties locations are always searched even if you supply a value for spring.config.location.
The Spring-boot documentation is very specific about the order that properties are resolved for a Spring-boot executable JAR, in descending order of precedence:
Command line arguments.
Java System properties (System.getProperties()).
OS environment variables.
JNDI attributes from java:comp/env
A RandomValuePropertySource that only has properties in random.*.
Application properties outside of your packaged jar (application.properties including YAML and profile variants).
Application properties packaged inside your jar (application.properties including YAML and profile variants).
#PropertySource annotations on your #Configuration classes.
Default properties (specified using SpringApplication.setDefaultProperties).
Take note of lines 6 and 7 - properties outside over properties inside your jar.
What's not stated, as far as I can see, and which may be the source of my confusion/issue, is what happens when you're not using a JAR but an exploded directory (and therefore PropertiesLauncher.)
If the behaviour of an exploded directory were consistent with what's stated for a JAR, I'd expect that the values of properties declared in /local/appname/dev/overrides/application.properties would override any of the same name declared in classpath:application-dev.properties, but this doesn't seem to be the case.
Also noted from the Spring-boot documentation (appendix C.4 on PropertiesLauncher) is mention of the loader.home property, which is described as '... [the] Location of additional properties file, e.g. /opt/app (defaults to ${user.dir})'.
So I tried using loader.home instead of spring.config.location, but to no avail.
(Update: I also tried using loader.config.location and I have two notes: it seems to want a file rather than a directory (so its behaviour is not analogous with spring.config.location), and when I did supply a file path rather than the parent directory, it still didn't help.)
Can anyone spot what I'm doing wrong, or what incorrect assumption(s) I'm making?
Thanks, Dave, your suggestion was 100% correct.
If I rename the properties file in /local/appname/dev/overrides to application-dev.properties then the property values from that file do override the ones in classpath:application-dev.properties.
I was sure I had tried this combination yesterday, but I think what must have stopped it working was when I was playing around with specifying the spring.config.location and got that wrong so it wasn't looking for the override file in the right place.

Override log4j.properties

My java application references a 3rd-party jar file which uses log4j logging. The problem is that this jar contains its own log4j.properties file which causes access denied exceptions on my machine, but I don't have control over the jar file to change its contents.
I have tried adding my own log4j.properties file in my application's classpath, but it doesn't seem to have an effect. If I try to use PropertyConfigurator to import my own settings programmatically, log4j seems to load the jar file's properties file first (causing an exception).
How can I short-circuit log4j to ignore a 3rd-party jar file's log4j.properties file and use my own?
There are several way to override log4j.properties, one of them is:
Use log4j.xml please see the extension
Another approach is:
Setting the log4j.defaultInitOverride system property to any other value
then "false" will cause log4j to skip the default initialization procedure (this procedure).
Set the resource string variable to the value of the log4j.configuration system property. The preferred way to specify the default initialization file is through the log4j.configuration system property. In case the system property log4j.configuration is not defined, then set the string variable resource to its default value "log4j.properties".
Attempt to convert the resource variable to a URL.
If the resource variable cannot be converted to a URL, for example due to a MalformedURLException, then search for the resource from the classpath by calling org.apache.log4j.helpers.Loader.getResource(resource, Logger.class) which returns a URL. Note that the string "log4j.properties" constitutes a malformed URL. See Loader.getResource(java.lang.String) for the list of searched locations.
If no URL could not be found, abort default initialization. Otherwise, configure log4j from the URL. The PropertyConfigurator will be used to parse the URL to configure log4j unless the URL ends with the ".xml" extension, in which case the DOMConfigurator will be used. You can optionaly specify a custom configurator. The value of the log4j.configuratorClass system property is taken as the fully qualified class name of your custom configurator. The custom configurator you specify must implement the Configurator interface.
Ref: http://logging.apache.org/log4j/1.2/manual.html
If none of these works
Add this following statement in your app configuration
BasicConfigurator.configure();
it worked for me
Try adding an environment variable called LOG4J_CONFIGURATION_FILE while you start the application.

Categories

Resources