log4j.properties not picked up from jar - java

I have a jar in the classpath of my server which contains the log4j.properties file on root of the jar for logging of the code. When the code in the jar runs the logging for the code is not occuring. When I analyzed the problem using java -Dlog4j.debug option I got to know that the log4j is loading the log4j.properties file of axis-ant.jar (this also is on my classpath) and using it instead of my jar's property file.
When i subsequently removed the axis-ant.jar from the classpath my jars log4j.properties file was picked immediately and logging for my code occured.
Can somebody please explain why is my log4j.properties fle not being loaded while axis-ant.jar is present?
Surprisingly the same jar with axis-ant.jar present in classpath is running with proper logging successfully in another server.. both the server have the same java 5 version installed and same version of log4j jar

You should have a look at the log4j manual. The section "Default Initialization Procedure" describes how log4j will try to find the initialization file and explains possibilities to match a special configuration (e.g. by setting the system property log4j.configuration).
If you do not want to do any special configuration you have to ensure that your configuration file will be the first one found on the classpath.

The properties file is picked up from the jar based on the order in which the jar is found in classpath by your application server. Now there is no way to conclusively tell the jar from which the properties file is to be loaded.
To get around this problem most projects include your log4j.properties file in the server classpath itself. This way this file is the first properties file to be loaded and this is the one which your logging code gets.

I'm note quite sure but it could be an order problem. Whichever log4j.properties is loaded first/last would win (I'd have to check that).

Possibly because axis-ant.jar comes before in classpath the your own jar. I assume putting your jar before in classpath then axis-ant.jar should help

Related

can ehcache-replicated.xml be placed outside of WEB-INF/classes

I am trying to create an environment where the application build remains same across environments. To support this I've externalized any property files to be read from an external directory e.g.$CATALINA_BASE/conf/app1/config
We use ehcache for caching (for CAS) and for replication between instances I seem to get the errror if the ehcache-replicated.xml is not present in the WEB-INF/classes directory. I've tried updating the setenv.sh of Tomcat so:
CLASSPATH=$CATALINA_BASE/conf/app1/config/ehcache-replicated.xml
export CLASSPATH
I also tried adding to JAVA_ENDORSED_DIRS but none of them seem to work. Any ideas?
A classpath entry is a directory, not a file. So try CLASSPATH=$CATALINA_BASE/conf/app1/config, it might work.
I am saying might because Tomcat is applying class loader isolation. A war won't see the classpath of the application server. So, it depends where you are setting the classpath.
In general, adding the classpath entry in catalina.properties shared.loader works. But that's from the top of my head.

spring boot: log file not generating

Using spring boot, deploying on ubuntu tomcat with war
in application.properties,
logging.path = classpath:/log
does not work on local machine or deployed at all. I did check my target/classes/log folder too.
it used to work with
logging.path = src/log
spring.log would be generated.
what am I doing wrong?
logging.path needs to be a directory, not a classpath.
This should work:
logging.path = /log
See this part of the docs for all the legal combinations:
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-logging.html#boot-features-logging-file-output
You probably shouldn't be trying to log to your classpath in the first place. And it likely doesn't make sense in the context of a deployed application. If you imagine an application packaged as a self-contained executable JAR, your classpath essentially becomes your JRE folder + your JAR. How would you be able to write to a file inside the JAR?
Best bet is to choose a folder somewhere on your file system and log to that. I usually use the same location where I put my JAR file, or use a /var/log/... folder to log to. If it is something only temporary, then I would log it to /tmp, but be careful with that as /tmp can sometimes have cleanup jobs that conflict with your logging settings.

How to read a local properties file from an executable jar?

I developed and tested my program on Eclipse Indigo. No problem finding the properties file when run.
I created a runnable jar using Eclipse export.
The program cannot find the properties file when the program is run from the jar.
The properties file is not in the jar, it is in a subdirectory of the directory where the jar is deployed.
As noted above, this directory is on the classpath in the Eclipse run configuration.
C:/myApp/myApp.jar C:/myApp/properties/myApp.properties
props.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("myApp.properties"));
Do I just need to edit the Jar manifest to put the config directory on the classpath?
properties.load(this.getClass().getResourceAsStream(configFileSrc));
This should work.
In my case, configFileSrc = "/apiconfig/appconfig.properties"
I had to add staticresources dir in the build path.
Thanks
Yes. Make sure you specify the path of the config directory relative to the directory where the jar is located. Since you said above that the config directory is a sub directory of the jar location, this will probably just be
<configDir>
where <configDir> is your configuration directory name.
You will also need to use an absolute resource name for the lookup, by adding a slash to the properties file name:
props.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("/myApp.properties"));
This is because the relative name your specify will have the package path of the class appended to it, which you don't want.
Is there any specific reason you need to use the contextClassLoader? A simpler invocation would be to use the classLoader of the class containing the lookup. And, since the class can delegate to it's classLoader, you can simply say:
props.load(getClass().getResourceAsStream("/myApp.properties"));
Finally - have you considered putting the properties file in the jar itself? If it's not going to change at all, this would be a better option. You wouldn't need to specify the classPath in that case. Note that if you want, you could put it in a sub-directory in the jar , but you would have to change the resource path you looked for, and again use an absolute resource name
Here is some info on absolute and relative resource names:
http://docs.oracle.com/javase/1.5.0/docs/guide/lang/resources.html
Hope this helps!
The real problem here is that you need to make up your mind where your application is going to load the properties from when the application is deployed.
(How it works in Eclipse is kind of irrelevant ... unless you expect your users to install Eclipse to run your app!)
If you want it to load the properties from the JAR file, they need to be in the JAR file.
If you want it to load the properties from the file system, they need to be in the file system. That means you have two subsidiary issues:
Where in the file system will your application look? Bear in mind that this has to work for all of the OS platforms you support, and that different OSes have different conventions for where "configuration settings* should be stored.
Is there a default version of the properties file, and how will you install it?
If you want to load it from the CLASSPATH and not the JAR file, that means you cannot make your application an executable JAR. (Running as java -jar ... will ignore all attempts to set an external classpath.)
If you opt for a non-executable JAR file AND loading the properties from the classpath, you have more problems:
How do you set the classpath?
How do you install the properties file "alongside" the JAR file?
Are there security concerns with a (potentially) user writable directory on the application's classpath?
This is probably the worst option.
Once you have decided how (from where) your application needs to load its properties when deployed, the code for implementing your scheme is relatively straightforward. (Modulo the problems mentioned above.)
You could even combine a couple of options; e.g. look for the properties file in the file system and then fall back to a "default" properties file in the JAR file. Or you could make the file system location of the properties file a command line option or supply it via an environment variable or via -D and the system properties.

log4j for standalone java project

I was thinking to use log4j for my standalone java project.
Is it possible to use it for java project(not a web app).
If its possible then how should I be able to initialize the properties file and where should
I put the properties file(directory structure).
Any help is appreciated.
Yes, it is possible, we do it all the time. You just need a log4j.properties file on your classpath, which in most cases means in the base directory of your jar file. If you wish to have multiple properties files with differing configurations, you can create a properties configurator in some entry point before your first logging statement.
Yes it's possible.
If you're planning to create a jar file.
Make sure that your log4j.properties is found in your classes folder in jar file.
Make sure that your log4j jar is included in your classpath.
Enjoy!
It's definitly possible to use log4j in a standalone project. Just set your classpath to include the log4j jar. As for the properties file, the apache documentation should say where to log4j looks for it (it's probably also configurable).

Java packaging issue

I have an application that I've developed. Currently it is deployed with all its config files (including log4j.properties, as used by some external libs I use) in the same dir as my application.
So, I have a bin dir, containing my app.jar, plus a few properties files, plus a lib dir with all my external jars. The external jars are specified in a classpath specified in the app.jar's manifest file.
Now the powers that be have decreed that the new structure will be a bin dir with just the app.jar, with a lib dir at the same level (i.e. ../lib, relative to bin) for external jars and a ../etc directory for configuration files.
Easy enough, I thought -- I changed all the classpath paths from ./lib/<jarname> to ../lib/<jarname>, and added ../etc to the classpath as well.
Problem is that now any jars that use log4j don't work -- they don't see the log4j.properties file -- because, I suspect, the classpath for app.jar doesn't affect the classpath for the external jars (maybe?), and previously they were finding it simply because it was in '.'.
Any thoughts?
You can put the log4j.properties anywhere as long as it is in the classpath. so, as #skaffman suggested, put the log4j properties file in the etc directory which is already in your classpath.
An alternative to using PropertyConfigurator is to set this syetm property while running your app.
-Dlog4j.configuration=log4j.properties
So, the issue is that Log4J now doesn't find the configuration file (log4j.properties) automatically anymore?
As far as I know, Log4J by default looks in the directories that are in the classpath for the log4j.properties file. Try adding the ../etc directory in the classpath in the manifest file of your JAR.
See also Default Initialization Procedure in the Log4J Manual, it explains how Log4J looks for the configuration file and how you can change this.
log4j.properties has to be somewhere in the default package, which in your case probably means in a JAR file somewhere in the root directory of that jar file.
A better solution would be to stick it in the etc directory, and then explicitly configure log4j to use it from that location. You can do that using PropertyConfigurator - invoke that when your application starts up, by filename, URL, whatever suits you best.

Categories

Resources