Currently when I execute my code I it doesn't create any log file.
the logback.xml is configured fine, however I don't see a way to configure where to find the xml file
Per the Logback manual chapter on Configuration:
Let us begin by discussing the initialization steps that logback follows to try to configure itself:
Logback tries to find a file called logback-test.xml in the classpath.
If no such file is found, logback tries to find a file called logback.groovy in the classpath.
If no such file is found, it checks for the file logback.xml in the classpath.
If no such file is found, service-provider loading facility (introduced in JDK 1.6) is used to resolve the implementation of com.qos.logback.classic.spi.Configurator interface by looking up the file META-INF\services\ch.qos.logback.classic.spi.Configurator in the class path. Its contents should specify the fully qualified class name of the desired Configurator implementation.
If none of the above succeeds, logback configures itself automatically using the BasicConfigurator which will cause logging output to be directed to the console.
The standard approach that this is trying to tell you about would be to have logback.xml be in the classpath for "normal" running, and have a logback-test.xml in the classpath to describe how you want to log when running automated tests. (For example, you may want to log to a file in your regular application, but have your automated unit tests just log to the console.) The exact process of putting a file into the classpath depends on what build system you're using. For example, with the default settings in the popular Maven build system, you would put logback.xml inside src/main/resources, and (if desired) a logback-test.xml inside src/test/resources. If you're having trouble with this step, you may want to search for or ask another question with more details about the build toolchain you're using. Also be sure to read "What is a classpath?"
Another approach, also listed in the Logback manual:
You may specify the location of the default configuration file with a system property named "logback.configurationFile". The value of this property can be a URL, a resource on the class path or a path to a file external to the application.
java -Dlogback.configurationFile=/path/to/config.xml chapters.configuration.MyApp1
Note that the file extension must be ".xml" or ".groovy".
This wouldn't be as common, but sometimes if you need to run in a particular environment with a certain logging configuration, or run some sort of automated test directing output to a different place than your normal tests, it can come in handy to just outright configure the path like that.
Related
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.
is it possible to specify the logging level for java.util.logging using classpath? I don't want to use for that special file or create java class which overrides the default level.
My point is to say something like this -Djava.util.logging.level=ERROR
I can't find it in documentation, but maybe there are some tricks for that.
No, it is not possible. The Java Logging API can be configured either with a configuration class java.util.logging.config.class or with a configuration file. A default logging configuration file is located at "lib/logging.properties", inside the JRE directory.You could change this configuration file (which is not the best idea as it will be used for all the programs running in this JRE) or
you could set a separate configuration file for your application and set JVM property java.util.logging.config.file to point to this file
-Djava.util.logging.config.file=/tmp/logging.properties
See this tutorial for more details on Java Logging configuration.
I have a runnable jar file.
I have a log4j.xml file sitting in the same directory.
My classpath includes "."
env |grep CLASS
CLASSPATH=.;C:\Program Files (x86)\Java\jre6\lib\ext\QTJava.zip
But when I run java -jar myrunnable.jar I get the following message.
log4j:WARN No appenders could be found for logger (org.apache.commons.configuration.PropertiesConfiguration).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Oddly enough, if I wrap that jar in a launch4j executable, it sees the log4j.xml file and uses it.
I did go to the FAQ page mentioned in the error message. It reads as follows:
This occurs when the default configuration files log4j.properties and log4j.xml can not be found and the application performs no explicit configuration. log4j uses Thread.getContextClassLoader().getResource() to locate the default configuration files and does not directly check the file system. Knowing the appropriate location to place log4j.properties or log4j.xml requires understanding the search strategy of the class loader in use.
I am at a bit of a loss in understanding what I need to do in order for my runnable jar to see the log4j.xml short of adding the -Dlog4j.configuration=file:\\\\my\crazy\long\path\to\my\eclipse\workspace\target\directory\log4j.xml to the command line which is a PITA to type out.
If I try something like java -Dlog4j.debug -Dlog4j.configuration=.\\log4j.xml -jar myrunnable.jar
log4j: Trying to find [.\\log4j.xml] using context classloader sun.misc.Launcher $AppClassLoader#265f00f9.
log4j: Trying to find [.\\log4j.xml] using sun.misc.Launcher$AppClassLoader#265f00f9 class loader.
log4j: Trying to find [.\\log4j.xml] using ClassLoader.getSystemResource().
log4j: Could not find resource: [.\\log4j.xml].
same results for different combinations log4j.xml and ./log4j.xml
If it makes a difference, this is windows 7/java 7/64 bit using log4j via the standard slf4j-log4j binding.
Additional notes:
tried java -cp . unsuccessfully
tried java -cp .\\ as well
examined jar file META-INF\MANIFEST.MF and there is no classpath entry
this particular jar was generated by maven using the maven shade plugin.
Solution (sort of)
Per Dave Newton's answer below, I changed my MANIFEST.MF file to include the following line:
Class-Path: ./
With this in place, my log4j.xml file was seen appropriately. I'm using the Maven Shade Plugin to build the jar file, so adding the Class-Path entry was a matter of configuring the ManifestResourceTransformer.
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>my.runnable.Class</mainClass>
<manifestEntries>
<Class-Path>./</Class-Path>
</manifestEntries>
</transformer>
I say "Sort of" resolved because although it does output logging information configured from my desired log4j.xml file, it means hardcoding that path into my jar and anybody using my jar has to have log4j.xml or log4j.properties in the installation directory. I wish there was a better solution that provided the standard and expected results (where the log4j.xml/log4j.properties file could be placed anywhere on your classpath), but with all the searching I've done today it does not seem to be the case.
I think I've run into yet another one of those frustrating issues where Java does not behave intuitively and anything beyond a very simple explanation of why it behaves the way it does involves reading an entire book.
When you use -jar the classpath is ignored.
You could add the config file to your manifest's Class-Path entry, but consider providing the path. It probably needs to be a file resource otherwise it'll probably try to find it on the jar's classpath value.
For Eclipse testing in Maven the easiest thing I've found to do is to put the log4j.xml in src/test/resources. It will be added to the classpath when running unit tests, etc. When we actually install our application at a customer site we place the file in /etc/... and specify it with -Dlog4j.configuration.
My best guess as to why the current directory part isn't working for you is that Eclipse is probably setting the current directory to something other than what you think it is. Try following the instructions here to print the current working directory and check it matches what you think.
UPDATE: Almost forgot. When you specify -jar the classpath options (-cp -classpath) are ignored.
-jar
Execute a program encapsulated in a JAR file. The first argument
is the name of a JAR file instead of a startup class name. In order
for this option to work, the manifest of the JAR file must contain a
line of the form Main-Class: classname. Here, classname identifies the
class having the public static void main(String[] args) method that
serves as your application's starting point. See the Jar tool
reference page and the Jar trail of the Java Tutorial for information
about working with Jar files and Jar-file manifests. When you use this
option, the JAR file is the source of all user classes, and other user
class path settings are ignored.
Observed a rather strange behaviour from apache log4j and thought sharing to get your thoughts.
I have an application which I'm running using an script. So far nothing special about that.
But the CLASSPATH I'm setting using that script, say a directory /home/myName/, have two different log4j properties files. One is simply log4j.properties and other is log4jXYZ.prperties.
The strange thing is when I run this script from different directories, one or the other log4j properties file is being picked-up. My understanding was it should have picked log4j.properties, obviously irrespectively from whereever I run the script.
Do you see some logic which can make a sense of it. Currently I'm at loss.
What I can predict is that log4j is trying any file matching lo4j*.properties expression.I must admit I haven't read all the manual assisting log4j.
Add log4j.debug property, when you run the application (-Dlog4j.debug= for the java command), it should show you the path where it loads the config file from.
I suspect it may load a file with same name from another directory than you think.
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.