I have an application contained in A.JAR. This jar has several dependencies so they are specified in the manifest as "lib/B.JAR lib/C.JAR lib/D.JAR". I have my installation directory with A.JAR, and under it I have the lib directory with the three others.
I go to my installation directory and run "java -jar A.JAR" to run the application, and it starts running. However, it looks for log4j.properties for setting up log4j. Now as far as I know, log4j.properties needs to be in the classpath.
Now let's suppose I want to run several instances of A.JAR, but with various log4j properties. So I setup 4 installation directories (inst1, inst2,...) and I've put A.JAR, a customized log4j.properties and the lib directory in each of them.
Is this the right way to go (forget about the copying itself, I can do this with symlinks)? Maybe there's a way for telling log4j to look for the properties in a specific place using some define (-D) in runtime?
If what I've described is a good setup, how can I actually run it? Java doesn't "catch" the log4j.properties as part of its classpath. running "java -classpath . -jar A.JAR" wasn't helpful as well.
You can use the log4j.configuration system property to define the properties files you want log4j to use.
A simple example for a file in some directory would be:
java -Dlog4j.configuration=file:/c:/foobar.properties YOUR CLASS PATH -jar JAR FILE
For more information check the documentation. Especially check the Default Initialization Procedure section.
Related
I have built a jar file which has a log4j.properties file in it (mvn package put it there by default from the resources directory). But when I run this jar file, I want to pass a different logging config, so I add -Dlog4j.configuration=file:{path to file}. The issue that bugs me is that the order matters here as follows:
When I run java -jar {path to jar} -Dlog4j.configuration=file:{path to file} then it reads the log file packaged in the jar.
When I run java -Dlog4j.configuration=file:{path to file} -jar {path to jar}, then it reads the config from the file I pass in the parameters.
I have rough understanding how classpaths work in java and that if I were to load several java classes with the same name, it would make a difference. But this way I am passing a config parameter with a -D prefix, so the way I expect this to work is for some code in log4j library to check whether -Dlog4j.configuration is set and if so, then load the config from there, otherwise try to find it on the classpath.
Any ideas on what I am missing?
If you provide anything after naming the JAR file, it is treated as an argument to your main method. For Log4J you actually have to define a property, and this needs to be done before you specify -jar.
I'm trying to get my application classpath.
I have a jar (named application.jar) and it have in its Manifest.mf other jar files, like Class-Path: a.jar b.jar.
Why when I use System.getProperty("java.class.path") my jars a.jar and b.jar are not listed?
It possibly has to do with the fact that the java.class.path is a system property that is set from the classpath environment variable ($CLASSPATH or -classpath). These are ignored with the -jar option is used.
As per the java -jar documentation, when that jar option is used to run an application, only the manifest Class-Path is considered and other settings are ignored.
From http://docs.oracle.com/javase/1.5.0/docs/tooldocs/windows/java.html:
-jar
Execute a program encapsulated in a JAR file. The first argument is the name of a JAR file instead of a startup class name. In order for this option to work, the manifest of the JAR file must contain a line of the form Main-Class: classname. Here, classname identifies the class having the public static void main(String[] args) method that serves as your application's starting point. See the Jar tool reference page and the Jar trail of the Java Tutorial for information about working with Jar files and Jar-file manifests.
When you use this option, the JAR file is the source of all user classes, and other user class path settings are ignored.
That's excactly the question I came along as well. Even if when using java -cp ..;myTest.jar test2.Needer I get only "..;myTest.jar" as a result for java.class.path property.
Note: Even when using the -cp parameter the given class-path in the MANIFEST.MF is searched! (Couldn't find this information on google and tested myself)
So i don't think that is has something to do with the -jar parameter. In Link you can find
Expansion of wildcards is done early, prior to the invocation of a program's main method, rather than late, during the class-loading process itself.
Interestingly i found out during my tests: The classpath in MANFIFEST.MF is searched recursivly. So if there is an given test.jar File in the classpath in MANIFEST.MF of myTest.jar, the class-path in the MANIFEST.MF of the test.jar will be looked up as well (when using java -cp "myTest.jar" test2.Needer).
As a result, when the java.class.path property would support showing the the classpath of the MANIFEST.MF, it should also show the classpathes of all subsequently depending .jar files. Since the classpath is only searched until classes are found, this wouldn t refer nicely to the lazy loading mechanism.
TL;DR: I think that this has nothing to do with the -jar Parameter (-cp is concerned as well). In my explanation, the support for showing the classpath from the MANIFEST.MF would only come with additional, senseless recursive search costs (because there needn't to be an actual dependency, respectivly what is used from the .jar). And since this sensless search would delay the program start (since the recursive search could be really deep), it is not implemented.
I've been trying to get some config files added into a JAR manifests class-path. Things like Spring, Log4j files etc... when I run the jar, it picks up other jars on the classpath so it can run the application starter class (which is in another jar) but it only looks for the XML files in the directory the jar is located, even though I can see it's path on the manifest.
Any ideas on how I can fix this?
Try to run it with verbose class loading switch on java command line to make sure classes in jars are actually being loaded.
There is a line length limit of 72 bytes in MANIFEST.MF - make sure you don't have a long lines there.
http://download.oracle.com/javase/1.3/docs/guide/jar/jar.html#Notes%20on%20Manifest%20and%20Signature%20Files
I have a java desktop app (main project) and another project with a series of packages in NetBeans. Some of the packages use spring for JDBC and IOC.
I am getting the following error when running in debug:
Caused by: java.io.FileNotFoundException: class path resource [config.xml] cannot be opened because it does not exist
Where is the config file supposed to go? Where exactly is the class path? Is it in dist, build, in the root of the project that calls spring, or the main project (the desktop app)?
confused ..
Your classpath is defined when you run your app using the java command. You can specify it using:
java -cp $path my.Main
where $path is your classpath. It is a :-separated (; on windows) list of JAR files and/or directories containing compiled .class files.
If you run your program like:
java -cp configdir my.Main
And put your spring config in configdir (the fully-qualified path) then that should be discovered.
NetBeans: whilst I'm not a netbeans user, it probably offers a number of ways for you to complete the task you want:
In your run configuration (i.e. where you define what class is being run, what the command-line parameters are etc), you will probably be able to add items to the classpath. These might be directories or individual files
In your compiler settings, you can probably tell NetBeans to automatically copy files of a certain type (like properties files, XML config files) from your source locations to where NetBeans puts your class files.
If you put your config.xml file in the directory where NetBeans is compiling your .class files to
Put it in the root folder of you application
if you created your application in a folder called Spring then you should put your file in that folder
Disregard the answer by oxbow_lakes. NetBeans modifies CLASSPATH, so what it is outside the IDE is no measure of what it is inside the IDE.
I've looked through many of the existing threads about this error, but still no luck. I'm not even trying to package a jar or use any third-party packaging tools. I'm simply running from within Eclipse (works great) and then trying to run the exact same app from the command line, in the same location it's built to (getting this error). My goal is to be able to zip up the bin folder and send it off to be run by someone else via a command line script. Some details:
It's a command-line app and I'm using the commons-lang-2.4.jar for string utilities. That is the file that cannot be located (specificaly "java.lang.NoClassDefFoundError: org/apache/commons/lang/StringEscapeUtils")
I have that jar in my lib folder and have added it to my build path in Eclipse via right-click "Build Path -> Add to Build Path"
The .classpath file looks correct and contains the reference to the jar, but I assume that file is only used by Eclipse (contains this line: <classpathentry kind="lib" path="lib/commons-lang-2.4.jar"/>)
Could this be related to the Eclipse working directory setting? I have some internal template files that I created that are under src/templates, and the only way I can seem to get those to be seen is by setting the project working directory to AppName/src. Maybe I should be putting those somewhere else?
Let me know if any additional info would help. Surely this is something simple, but I've wasted too much time on it at this point. This is reminding me why I originally left Java back in '05 or so...
A NoClassDefFoundError basically means that the class was there in the classpath during compiletime, but it is missing in the classpath during runtime.
In your case, when executing using java.exe from commandline, you need to specify the classpath in the -cp or -classpath argument. Or if it is a JAR file, then you need to specify it in the class-path entry of its MANIFEST.MF file.
The value of the argument/entry can be either absolute or relative file system paths to a folder containing all .class files or to an individual .jar file. You can separate paths using a semicolon ;. When a path contains spaces, you need to wrap the particular path with doublequotes ". Example:
java -cp .;c:/path/to/file.jar;"c:/spacy path/to/classes" mypackage.MyClass
To save the effort of typing and editing the argument in commandline everytime, use a .bat file.
Edit: I should have realized that you're using an Unix based operating system. The above examples are Windows-targeted. In the case of Unix like platforms you can follow the same rules, but you need to separate the paths using a colon : and instead of an eventual batch file, use a .sh file.
java -cp .:/path/to/file.jar:"/spacy path/to/classes" mypackage.MyClass
Are you specifying the classpath to java on the command line?
$ java -cp lib/commons-lang-2.4.jar your.main.Class
The classpath setting you are setting in Eclispe are only for the IDE and do not affect how you application is run outside the IDE. Even if you use the Eclipse Functionality to export your application as an executable jar file there is no out of the box way to package all the jars your application depends on.
If you have packaged you application into a jar file called myapp.jar then running a command like below will run the application with the jar you depend on, if you have more than one just add them separted by ; on Windows or : on Unix:
java -jar myapp.jar -cp .;c:/pathtolibs/commons-lang-2.4.jar
If you are just running the classes directly then either run the folder containing your .class files will also need to be on the path (though I assume it already is since you are able to run the program and get errors).
Consider File -> Export -> Runnable jar to create a jar file which can be invoked directly with
java -jar yourProgram.jar
There are several variants depending on your needs.
Eclipse does not move any of the jars in your classpath into the bin folder of your project. You need to copy the util jar into the bin folder. If you move it to the root of the bin folder, you might be able to get away without any classpath entries but it's not the recommended solution. See #BalusC's answer for good coverage of that.
Eclipse doesn't build executable java classes by default. Don't ask me why, but it probably has something to do with using their own tools.jar (somewhere in plugins/org.eclipse.core ?) so that Eclipse can run without a JDK.
You can usually go to your project bin directory and do:
java -cp . MyClass
But if you have external jars, Eclipse handles those internally in another weird way, so you'll need to add those too.
make sure your jar commons-lang-2.4.jar in classpath and not redudance.
I ever add jar file to my classpath, and have 2 file jar in my classpath. After I delete it, work smooth