How do I get log4j to pick up a properties file.
I'm writing a Java desktop app which I want to use log4j. In my main method if have this:
PropertyConfi开发者_如何转开发gurator.configure("log4j.properties");
The log4j.properties file sits in the same directory when I open the Jar.
Yet I get this error:
log4j:ERROR Could not read configuration file [log4j.properties]. java.io.FileNotFoundException: log4j.properties (The system cannot find the file specified)
What am I doing wrong?
I believe that the configure method expects an absolute path. Anyhow, you may also try to load a Properties object first:
Properties props = new Properties();
props.load(new FileInputStream("log4j.properties"));
PropertyConfigurator.configure(props);
If the properties file is in the jar, then you could do something like this:
Properties props = new Properties();
props.load(getClass().getResourceAsStream("/log4j.properties"));
PropertyConfigurator.configure(props);
The above assumes that the log4j.properties is in the root folder of the jar file.
When you use PropertyConfigurator.configure(String configFilename), they are the following operation in the log4j library.
Properties props = new Properties();
FileInputStream istream = null;
try {
istream = new FileInputStream(configFileName);
props.load(istream);
istream.close();
}
catch (Exception e) {
...
It fails in reading because it looks for "Log4j.properties" from the current directory where the application is executed.
How about the way that it changes the reading part of the property file as follows, and puts "log4j.properties" on the directory to which the CLASSPATH is set.
ClassLoader loader = Thread.currentThread().getContextClassLoader();
URL url = loader.getResource("log4j.properties");
PropertyConfigurator.configure(url);
Another method of putting "Log4j.properties" in the jar file exists.
jar xvf [YourApplication].jar log4j.properties
just set -Dlog4j.configuration=file:log4j.properties worked for me.
log4j then looks for the file log4j.properties in the current working directory of the application.
Remember that log4j.configuration is a URL specification, so add 'file:' in front of your log4j.properties filename if you want to refer to a regular file on the filesystem, i.e. a file not on the classpath!
Initially I specified -Dlog4j.configuration=log4j.properties. However that only works if log4j.properties is on the classpath. When I copied log4j.properties to main/resources in my project and rebuild so that it was copied to the target directory (maven project) this worked as well (or you could package your log4j.properties in your project jars, but that would not allow the user to edit the logger configuration!).
This is an edit of the answer from @kgiannakakis:
The original code is wrong because it does not correctly close the InputStream after Properties.load(InputStream)
is called. From the Javadocs: The specified stream remains open after this method returns.
================================
I believe that the configure method expects an absolute path. Anyhow, you may also try to load a Properties object first:
Properties props = new Properties();
InputStream is = new FileInputStream("log4j.properties");
try {
props.load(is);
}
finally {
try {
is.close();
}
catch (Exception e) {
// ignore this exception
}
}
PropertyConfigurator.configure(props);
If the properties file is in the jar, then you could do something like this:
Properties props = new Properties();
InputStream is = getClass().getResourceAsStream("/log4j.properties");
try {
props.load(is);
}
finally {
try {
is.close();
}
catch (Exception e) {
// ignore this exception
}
}
PropertyConfigurator.configure(props);
The above assumes that the log4j.properties is in the root folder of the jar file.
I have this code in my application today
File log4jfile = new File("./conf/log4j.properties");
PropertyConfigurator.configure(log4jfile.getAbsolutePath());
The relative path is from the working directory of the JVM (where the JVM starts).
import org.apache.log4j.PropertyConfigurator;
Import this, then:
Properties props = new Properties();
InputStream is = Main.class.getResourceAsStream("/log4j.properties");
try {
props.load(is);
} catch (Exception e) {
// ignore this exception
log.error("Unable to load log4j properties file.",e);
}
PropertyConfigurator.configure(props);
My java files directory like this:
src/main/java/com/abc/xyz
And log4j directory like this:
src/main/resources
I believe the log4j.properties directory it needs to be in the java classpath. In your case adding the CWD to the classpath should work.
Since JVM arguments are eventually passed to your java program as system variables, you can use this code at the beginning of your execution point to edit the property and have log4j read the property you just set in system properties
try {
System.setProperty("log4j.configuration", new File(System.getProperty("user.dir")+File.separator+"conf"+File.separator+"log4j.properties").toURI().toURL().toString());
} catch (MalformedURLException e) {
e.printStackTrace();
}
If your log4j.properties location is like path/to/configfiles/log4j.properties. Then simply use,
PropertyConfigurator.configure("path/to/configfiles/log4j.properties");
Also, if the path is src/main/resources/log4j.properties then even this code is not required since it is the default location.
You can enable log4j internal logging by defining the 'log4j.debug' variable.
精彩评论