log4j likes its properties in a jar file? - java

I have a Java application which I'm executing on Linux direct from an executable jar file
java -cp .:./lib -Duser.timezone=GMT -Dlog4j.debug -jar programName.jar
The program uses a number of other jar files which are all in one directory and 4 properties files all of which are in another directory (the current directory). Both directories are included in the CLASSPATH.
Simple enough right.
It would be, except that Log4j fails to find log4j.properties. The only way I have managed to make it find log4j.properties is to include it in programName.jar
This is not what I want, I want to have it using log4j.properties residing in the same directory as all the other properties files, they are in the CLASSPATH and are found as you would expect.
The other jar files being used are:
jdom-2.0.5.jar
log4j-1.2.17.jar
ojdbc7.jar
quartz-2.2.1.jar
slf4j-api-1.7.7.jar
slf4j-log4j12-1.7.7.jar
I'm wondering if slf4j-log4j12-1.7.7.jar does some configuration which prevents log4j from scanning the CLASSPATH when looking for the properties file. My code does not include any instructions which aim to specify the location of the properties file.
I've not yet tried executing the program without the -jar option, I will try that next.
Does this ring any bells so far ?

Add an argument to jvm (log4j.configuration). e.g.:
java -cp .:./lib -Dlog4j.configuration=file:log4j.properties -Duser.timezone=GMT ...
You may want to see this answer for more options.

Related

Changing log level for an executable JAR

I have built a maven Java project and deployed my JAR as an executable one on linux. I placed my log4j.xml under /src/main/resources directory during the build and hence it is now part of the final deployed JAR. I have configured log4j.xml with RollingFileAppender. So far, everything is working fine and I am able to see the logs generated.
However, wondering how to change the log level or any of the configuration within log4j.xml which is now part of the deployed JAR?
The other approaches I tried is having the log4j.xml outside in a separate directory and passed it as a configuration option to the JAR file using the below command
java -Xms512m -Xmx1024m -Dlog4j.configuration=/etc/myapp/log4j.xml -jar mylar.jar /etc/input.properties
java -Xms512m -Xmx1024m -Dlog4j.configurationFile=/etc/myapp/log4j.xml -jar mylar.jar /etc/input.properties
However, it is not working. No logs are being generated. So wondering whether I am doing this correctly or there is a better approach to implement.
from the quick look at your arguments, can you try passing the log4j path like below. (you are missing file: in the beginning of the path )
java -Dlog4j.configuration=file:/etc/cfg/log4j.properties -jar ./MyProject.jar ...
here is a similar answer present.

slf4j over log4j configuration after deployment

I have built a java application and I've been using slf4j/log4j for logging. I would now like to provide the user with the possibility of changing logging levels without needing to re build the .jar file.
I've read around that to do this your properties file needs to be inside of the classpath of the application. I've tried using the Class-Path header in the MANIFEST.MF file to achieve this, however it is not working.
These are the two examples I've tried.
Class-Path:./config/
Class-Path:C:/users/user/directory/tools/config/
However none of these seem to be added to the classpath as I've tried printing its contents once the application starts running.
As suggested by this question, I ended up adding a parameter to the java execution command. Bear in mind that if you execute through bash commands, as I do, you need to add the full path to the directory.
java -Dlog4j.configuration=file:/path/to/log4j.properties -jar myApp.jar
I don't like this since it makes it extremely dependent on path configuration but it will suffice.
Please find below a list of possible solutions.
1) java -jar myApp.jar will search for the log4j.properties in following order
root of myApp.jar
the directories specified in the header Class-Path: of the myApp.jar
2) java -Dlog4j.configuration=file://path/to/file//log4j.properties -jar myApp.jar will use the properties file specified by -Dlog4j.configuration=...
3) java -Xbootclasspath/a:../config -jar myApp.jar will search for the log4j.properties in following order
directory ../config/
root of myApp.jar
the directories specified in the manifest header Class-Path: of the myApp.jar
I believe solution 1) should solve your problem like following
make sure there is no log4j.configuration in the root of myApp.jar
the manifest header contina for example Class-Path: config/
and the directory structure of your installation is
./myApp.jar
./config/
edit A possibe solution to avoid the hardcoded path, but use a defined location for the log4j.properties file could be as below.
assume following structure of your application
c:\somewhere\myApp.jar
c:\somewhere\config\log4j.properties
c:\somewhere\run_myapp.cmd
run_myapp.cmd
#echo off
... do your necessary preparation here
java -Dlog4j.configuration=file:%~dp0log4j_2.properties -jar myApp.jar
This will use always the config\log4j.properties relative to your myApp.jar.
%~pd - expands to drive letter and path of run_myapp.cmd
With this solution your users need to store the properties file at the given place but don't need to change the run_myapp.cmd script.

Java executable jar classpath confusion

I have read the answer about executable jars and adding the current path to the classpath here.
I added the plugins to pom.xml, I checked and this line is in fact added to MANIFEST.MF:
Class-Path: .
Now according to log4j2 documentation, it will look in the current classpath for a log4j2.xml file.
My understanding is, that if I place log4j2.xml in the same directory as the jar, and execute the jar while I am in that directory, then it will find the log4j2.xml.
However, it only finds it when I add a
-Dlog4j.configurationFile=/path/to/file
to the java command.
What am I missing?
Frankly, it just seems easier to forget about the classpath stuff and just add a bunch of -D terms to the java command line.
I think the . is evaluated as current directory relative to the java process current working directory (when processes are started by the OS, they are given a working directory). You can see the working directory of the JVM that runs your program by examinating the system property user.dir from withing your program.
# current directory is /home/rick
$pwd
/home/rick
# the code archive is not in the current wd
$ls /home/rick/myapps
app.jar
# the conf file is
$ls .
log4j2.xml
# This will work as expected
$java -jar /home/rick/myapps/app.jar
Strictly speaking, the JAR doesn't even need to be on your filesystem: for example, it could be downloaded from the network and extracted in memory.

Running Java Program linking to thirdpary library (java -jar) issue ( Multiple methods tried )

This issue is related to running a Java program (jar) dependent on thirdparty jar library even after setting classpath and trying so many other methods by reading articles in Internet.
I want to use a thirdparty Pack1.jar (it is not a part of jvm) as dependency of my programme.
I do not know where the Pack1.jar file could be in the deployment machine and I want the deployer to specify the path for the thirdparty libraries
I have tried the following alternatives in vain
Setting the java.class.path programatically
String class_path = args[0];
System.setProperty("java.class.path",class_path);
Here I am assuming that deployer would supply the classpath as first argument while running the program
Setting the CLASSPATH env_var to locate the thirdparty directory
While running, using the classpath option
java -classpath /path/to/Pack1.jar -jar Pack2.jar
I think this would not work because documentation says that classpath is ignored when program is run with "java -jar"
Setting the java.ext.dirs programatically.
Setting the java.library.path programatically.
I do not want to specify the Class-Path in manifest because that takes only relative path and I do not know where the thirdparty library would be kept in deployment machine
But I am unable to get the jar running.
How can I fix this problem any help please.
Go for option 3. Put both jars on the classpath like this:
java -classpath '/path/to/Pack1.jar:/path/to/Pack2.jar' com.packagename.yourclassname
Note, that this is for Linux. on Windows, you would separate classpath elements with semicolons:
java -classpath "/path/to/Pack1.jar;/path/to/Pack2.jar" com.packagename.yourclassname
http://en.wikipedia.org/wiki/Classpath_%28Java%29
You can use Pack2.jar without running it using -jar--put it on the classpath and call the entry point listed in its manifest file.
I usually wrap that up in a launcher script to avoid those kinds of problems, and allow jar paths to be set using an argument.
Name the secondary JAR(s) in the Class-path entry of the Manifest.MF of the main JAR file, and use java -jar.
Your objection to this technique doesn't make sense. If you supply and deploy the secondary JAR files, as you should, you have the same degree of control over their location as you do over that of the major JAR file. It doesn't matter where else the user may have copies of them.

Java - Difficulty installing program from 3 separate .jar files (involves CLASSPATH)

I'm having a little trouble running some Java code, which requires three .jar files to be used. I'm at a lost as to what to do with them--I've tried setting the CLASSPATH (and following the instructions for how to do so in the readme files), but to no avail.
I was wondering if someone could walk me through it? I'd imagine three .jar files would be an easy install for someone who knows what they're doing.
If it helps, I'm using Ubuntu pretty much right out of the box (but I do have JDK and Eclipse installed!)
Runtime library: http://cogcomp.cs.illinois.edu/download/software/20
Additional .jar needed: http://cogcomp.cs.illinois.edu/download/software/23
Program I ultimately need to run: http://cogcomp.cs.illinois.edu/download/software/26
If you're willing to help, I can't thank you enough--you deserve a million kudos!
G
Those are all JAR files. When you execute a JAR file by doubleclicking or using java -jar, the CLASSPATH environment variable and the -cp and -classpath arguments are ignored. The classpath should be defninied in META-INF/MANIFEST.MF file of the JAR. In this particular case, only the second and third JAR have a Class-Path entry in the manifest file:
Class-Path: LBJ2Library.jar
Which is the first JAR. The classpath is telling that it is expecting the LBJ2Library.jar to be in the same folder as the JAR you'd like to execute (either the second or third one).
So, just drop them all in the same folder and execute by java -jar LBJPOS.jar.
If you are using java -jar to run your jar files, then the CLASSPATH variable is ignored. If you are using java -jar, you have two options:
Combine the three jars into one jar.
Run the main class directory and don't use -jar.
Use of the CLASSPATH environment variable is generally discouraged nowadays. This is how it's done (on Linux):
java -cp library1.jar:library2.jar:mainapp.jar <fully qualified name of main class>
You need to set the CLASSPATH .place all the 3 jars in a folder , name it as lib
See below to set classpath
set CLASSPATH=%CLASSPATH%:lib;

Categories