I have a main project, which depends on multiple projects (in eclipse).
At the end of the project, I will generate a runnable jar and a log4j.properties. This properties file is an external file, so my client can modify it at will (email address etc).
runnable.jar + log4j.properties.
At the same time, those projects which the main project depends on, have their own log4j properties files.
I want to centralize the setting in log4j.properties into one external file. How to do that?
If you add a JVM parameter -Dlog4j.configuration="file://anywhere/anyfile", all your components will use the same configuration. You can combine all your log4j configuration in this one big file. Is this what you mean by centralizing?
You will have to copy the relevant settings of the log4j.properties from the other projects into your file. But I guess the real question is: Why would you want to do that? Normally you would not care about logging those other projects in detail. A general root level should cover them just fine. And if you do care, you should care in a way that is different from their default.
Related
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
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.
There are 2 log4j.properties files in my classpath. I need both of them - One of them is required for a library that I am using and another is the one used by my code. When I run my jar file, it is able to read the properties used by the library, but it is not reading my own properties file. How can I make it read my log4j without having to use PropertytConfigurator in all my source files? Is there any way I can configure it so that it used both the properties files together?
To answer your first question, you can point it to your own file by giving it a unique name and adding the following system property when you launch your application.
-Dlog4j.configuration=path_to_my_properties_file
I don't think it is possible to use 2 different files without doing anything programatically.
Two log4j.properties files will surely create a mess (as you've experienced).
I'd suggest removing the library's version (why is it a requirement?), and combining both .properties files into one.
All logging goes into a single property file. Within that file you can differentiate between your own classes and the library's logging configuration.
I am developing a framework that needs a lot of stuff to get working. I have several folders inside of my Eclipse project that are needed
[root]
- config
- src
- lib
- serialized
Also there are important files like the log4j.properties and the META-INF dir inside the src directory.
I wonder if there is a way to distribute one JAR containing all essential files so my gui will just have to import one jar. I guess that I have to exclude the config folder in order to make the framework configurable.
I also wonder, if there is a way to move for example the log4j.properties to the config dir so that I have one config folder containg all needed configurations?
Thanks for help and advise on this matter!
Marco
Yes, but not really. You can take all your dependencies, unpack them and simply merge them into a bigger jar. This is what the maven jar plugin does if you make a jar with dependencies. The only problem is that this might result in conflicting files (suppose two of your dependencies contain a log4j.properties). This is one of the problems when doing the above with some of the spring libraries for instance.
I think someone actually wrote a classloader that allows you to bundle the whole jar inside of your jar and use it as is. I'm not sure how mature that is though and can't at the moment recall the name.
I think you're better off distributing all your dependencies separately. Setting up the classpath is a bit of a pain but surely java programmers are used to it by now. You can add dependencies to the Class-Path header in your manifest file, in simple cases. Bigger libraries have to rely on the classpath being set up for them though.
As to the second part of your question, probably dropping the conf/ directory under META-INF is enough for its contents to be picked up. I'm not sure about this. I'm fairly sure it will always be picked up if you put its contents at the top level of the jar. In any case, this is a distribution problem. You can easily have a conf/ directory inside your source tree and have your build scripts (whatever you might be using) copy the files in it to wherever is most convenient.
As to your users configuring. Try to establish some conventions so they have to configure as little as possible. For things that must be configured, it's best to have a basic default configuration and then allow the user to override and add options through his/her own configuration file.
In terms of the resources, it is possible except that if you do that you are not going to be able to load resources (non class files) from the filesystem (via a file path).
It's likely that you're currently loading these resources from the file system. Once in the jar you need to load them as class path resources via the class.getResourceAsStream or similar.
As for the dependent jars you may have, it's common practice for these to be placed as extra jars on the classpath. I know it's complicates things but developers are used to doing this. The nature of the java landscape is that this is inevitable. What the spring framework for example does is supply a bundled zip file with the core jar and the jar dependencies included.
Is your library going to be used in an EE context or an SE context? If it is an EE context then you really don't have to worry about configuration and class path issues as the container takes care of that. In an SE context it is a lot more tricky as that work has to be done manually.