Java executable jar classpath confusion - java

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.

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.

How to include JAR files on a batch file [duplicate]

This question already has an answer here:
Including Jar while executing Java from Bat file
(1 answer)
Closed 4 years ago.
This might be similar to THIS but I can't find a solution written there
Problem is, I am running a java app thru a batch file which needs some jar files to be included. And I can't find a way to do it
File locations:
(java class)
D:\workspace\src\MyClass.java
(jars needed)
D:\workspace\src\lib\opencsv-4.1.jar
D:\workspace\src\lib\common-lang3.jar
Current code on bat file:
#echo off
set CLASSPATH=.
set CLASSPATH=%CLASSPATH%;D:workspace\src
set CLASSPATH=%CLASSPATH%;\lib\opencsv-4.1.jar
set CLASSPATH=%CLASSPATH%;\lib\common-lang3.jar
set ARGS=one two
javac D:workspace\src\MyClass.java
java -cp %CLASSPATH% MyClass %ARGS%
pause
Please help on how to properly include these jar files to be able to run the program. Thanks
Please help on how to properly include these jar files to be able to run the program
Don't start from here. You should:
Deploy your application as a JAR file, naming the main class in the META-INF/MANIFEST.MF file's Main-class entry.
Name the external JAR files in the META-INF/MANIFEST.MF file, in the Class-Path entry. Note that this only allows you to use relative pathnames to the other JAR files, so you essentially have to distribute them with the application JAR file.
Use the java -jar option.
In which case you barely need the batch file at all.
Your relative and absolute path in your script file is not valid...
Especially the relative path in your script...The java file location must be either relative path or absolute path.
You don't need to use the '-cp' flag since you set the CLASSPATH variable.
So, if your jars path is a lib directory under workspace in a D volume.
The script looks like as follows;
#echo off
set CLASSPATH=.
set CLASSPATH=%CLASSPATH%;D:\workspace\src
set CLASSPATH=%CLASSPATH%;D:\workspace\lib\opencsv-4.1.jar
set CLASSPATH=%CLASSPATH%;D:\workspace\lib\common-lang3.jar
set ARGS=one two
cd D:\workspace\src\
javac MyClass.java
java MyClass %ARGS%
pause

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.

log4j likes its properties in a jar file?

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.

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