I'm trying out log4j in a simple test app. I create a new Java project in eclipse and add the log4j JAR (v1.2.16) to my build path. I then create a simple class that prints Hello World. Then I use the log4j Logger class to log a info message. When I run the app, I see the log message, using what I assume is the default appender and layout. Great. What I'm having trouble with is adding my own configuration. This is what I've done:
Created a log4j.properties file with a custom appender and log level and placed it into the src folder (which upon compilation gets copied to the bin folder). Run the app - no change.
I try adding PropertyConfigurator.configure("log4j.properties"). Run the app - no change. No errors, but no change.
What do I have to do to get log4j to load my configuration file?
Look in the manual under the heading Default Initialization Procedure, where you'll find the following:
The exact default initialization algorithm is defined as follows:
Setting the log4j.defaultInitOverride system property to any other value than "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.
Argh. I discovered the problem was that eclipse had imported the wrong Logger class. It had imported java.util.logging.Logger which of course has it's own configuration that is different from log4j. Oh well, hope somebody else does this and gets it solved by reading this question.
You can enable log4j internal debugging by setting the log4j.debug system property. Among other things, this will cause log4j to show how it is configuring itself.
You can try explicitly setting the URL to the configuration file with the log4j.configuration system property.
See also: this question.
The problem may be in the classpath, if the classpath was defined.
The reason it wasn't loading (in my case): There was a conflicting log4j.properties file in one of my jars, and it was overloading the one in my classpath.
In short, if your log4j.properties file isn't loading, there might be another one somewhere else overriding it.
Just thought I'd throw this in too, in case anyone else runs into this. I just spent the last 5 hours trying to figure out why my default log4j.properties wouldn't load.
log4j.properties should be in your classpath. The "src folder" which is copied to the "bin folder" (I assume you are speaking of a Eclipse setup here), normally belongs to your classpath, so it should be found (are you placing it at the top of the "src" folder, right?)
I know this is a couple of months old, but I feel the need to point out that the scr folder isn't "copied" to the bin folder, nor is it part of your runtime classpath....(build path is not runtime classpath!). Eclipse compiles the source files in the src folder to the bin (or whatever you like) folder. It's the bin folder that is part of your runtime classpath.
Just wanted to point this out as these threads are often read by very junior programmers as well, and I'm always frustrated that most of them don't grasp the finesse of the Java classpath, and hence make avoidable mistakes against it.
Just throwing it out there to anyone who is struggling to get log4j.properties filed loaded.
I fixed mine by adding the following line:
-Dlog4j.defaultInitOverride=TRUE
Turns out using that JVM parameter, it possible to tell Log4j not to use the Default Initialization Procedure and create your own.
I struggled with mine. I did from clean JAR build to entire REPO pull, nothing work. Combination of that and clean up of class file made it work.
Related
I hope someone can help me here, becouse I'm fighting with a problem for some time. In my main class I use this command:
System.out.println(getClass().getClassLoader().getResource("org"));
The problem I've got is that it returns:
file:/E:/Tmp/ExamplePr/PROJEKT/proj/build/classes/java/main/org
instead of:
file:/E:/Tmp/ExamplePr/PROJEKT/proj/build/resources/java/main/org
The problem is that it goes into classes directory instead of resources dir. As a result I can't have access to my .fxml files I need. I'm using gradle for build and currently working with JavaFX. I've tried something like:
System.out.println(getClass().getClassLoader().getResource("/resources/java/main/org"));
But I just got null :(
Do you know any method to force him to use absolute path or to look for resources in resource filder or even use something like to use "../" from linux to go up. I dodn;t find any of this
The root of your resources tree is defined by the classloader (as described in the JavaDoc). You can define the root by explicitely setting it in your classpath or preferably by using a build tool like maven and following the conventions set and used by the tool. For maven projects the root would usually be at main/java/resources.
getResource will always return the first match in the class path. So if you specify E:/Tmp/ExamplePr/PROJEKT/proj/build/resources/java/main before E:/Tmp/ExamplePr/PROJEKT/proj/build/classes/java/main in your classpath, you will get what you want.
That said, the resources are usually meant to be copied with the classes, and sometimes both are packed in a jar file, so you shouldn't worry about it.
With JavaFX use FXMLLoader;
FXMLLoader.load(new URL(getClass().getResource("/fxml/myfxml.fxml").toExternalForm()));
Make sure to pass the platform appropriate separator and use a relative path.
I want to set the log4j configuration file path/other folder paths that can be used across other class files, without hard-coding the folder path.
Rightnow, I have set the variables as Environment variable. But It can only be modified if I launch Eclipse. How do I set this variable in such away that anyone (doesn't want to launch Eclipse) can modify it, from outside. Also, it will be used in test configurations. So it's better to not hard-code it and have all the file paths etc. easy to refactor.
final static String log4jpath = System.getenv("LOG4J_PATH");
Paraphrasing a comment:
[How to get value from] outside of the Java program such as a separate file, that contains all other filepaths?
That is called a configuration file.
It is often a properties file, similar to a Log4j configuration file, but it can be any types of file, e.g. XML, JSON, YAML, ...
To identify a single such file, you can use:
An environment variable (like you are right now)
A system property (more common)
A specifically named file in the current directory
...
The entries in that file will identify all the values you really want.
For example, Spring, which is a populate Java framework, will look for configuration values in many places. See 24. Externalized Configuration for full detail, but here is a summary of the most common ones:
Command line arguments, e.g. java -jar MyApp.jar --foo=bar
Java System properties, e.g. set using -Dfoo=bar on the command-line
OS environment variables, e.g. SET foo=bar (Windows) or export foo=bar (Linux)
Application properties outside of your packaged jar, i.e. relative to current directory.
Name and location can be overridden on command-line.
config/application.properties
config/application.yaml
application.properties
application.yaml
Soni, If you want to put the log4j configuration file in one place so that everybody can access. Follow the steps.
Create a project with some name and inside src/main/resources folder keep the log4j configuration file.
Create a jar file which must contain this log4j configuration file.
Use this created jar file wherever it is required. Log4j will automatically use the configuration for desired logging. If you want, you can distribute this jar file to anybody who wants to use it.
The above option is if you do not want to change the configuration file.
Now if there is a situation where someone wants to modify the configuration file.
In this case, simply put the configuration in any project classpath, means inside resource folder. As long as log4j jar files are there in the classpath and configuration files. It will log everything.
However, if you want, you can extend the functionality of Log4j by passing configuration as an object. You can refer below the link to access pro grammatically.
https://howtodoinjava.com/log4j/how-to-programmatically-configure-appenders-in-log4j/
I have added all file and folder paths inside the properties file (example config.properties) and then used it inside the testsetup method by InputStream input = new FileInputStream("Path to//config.properties");
Properties prop = new Properties();
prop.load(input);
System.setProperty("log4j2.configurationFile", prop.getProperty("log4j.path"));
this way, all files/folder paths can be modifies from outside and there's no need to set environment variable from inside the project.
I have a maven project and want to read file in it form its class path. The code that i am using is
InputStream is = getClass().getResourceAsStream ("filename.json");
But every time i am getting null inputstreams. I am not sure why ?
The file is places under /src/main/resources. The same folder which contains log4j.xml and it is being picked up decently.
Please note, I am trying to run this file from Eclipse i.e., run or debug mode. No vm arguments or whatsoever.
The Class.getResourceAsStream(String) method looks for the given resource within the same namespace (i.e. package) that the given class is in unless you give it an absolute path (see the API documentation); If it can't find the resource on the classpath in this namespace, it returns null. Since your class is likely inside e.g. com.myproject.resourcemanagement, your resource file has to analogously be under src/main/resources/com/myproject/resourcemanagement, similary to how your class source files are organised (under src/main/java/com/myproject/resourcemanagement).
I have some code that references a filename. On the server, this reference is relative to my war directory. When I'm running tests, though, the relative root doesn't seem to be set - only absolute paths, starting at the root of my local HD, actually find the files.
I'm testing in the context of an AppEngine LocalServiceTestHelper, which returns my war directory in its getAppDir method, but still the code can't understand the relative path.
How can I set the root for relative filenames in JUnit tests?
There are a number of options. In any case, I'd encapsulate the file access (or at least the file path resolution) in a separate class. That way, you could:
Mock that class in your tests to provide the correct file (path)
Pass an environment variable to your test class to resolve the correct file (path)
Provide a fallback implementation if the file is not found (as it is the case in your tests)
etc...
For my unit tests, I created a utility class called SupportFilePathResolver (see the code). It finds the file by looking in the classpath. This works nicely if the files you care about are in the classpath. If not in the classpath, then this won't help you.
I am using java -classpath $CLASSPATH ..., where $CLASSPATH has been set to /file1path/file1:/file2path/file2 and so on. Despite this, Java complains that file1 is not found. I tried to set -Dfile1=file:///fullpath/file1, but it still says it cannot find the file. Is there any reason why this might happen other than that I am not seeing a simpler problem like a typo or something (which I have checked for many times)?
More specifically, this.getClass().getClassLoader().getResourceAsStream(configurationFileName) is returning null.
The file that is not being found is a configuration file (.properties), not a JAR file.
You set a classpath to point to a directory containing something or an archive containing resources. I don't believe you can add a resource directly to the classpath.
Try setting your classpath to /file1path instead of /file1path/file1
The classpath should specify the directory where your package hierarchy rooted.
package org.djna, file system : C:/myhome/javastuff/org/djna/Myclass.java
classpath is set to c:/myhome/javastuff
If you are trying to open files from your application using getResourceAsStream() or some such the the details of the path depend on whether or not the filename has a leading /. Read the docs caefully and all will become clear.