Can you see anything wrong with the below code? It's a bat file and I'm trying to set some dependency classes before executing my jar (jdbc oracle driver).
set CLASSPATH=lib\dbdriver.zip;%CLASSPATH%
java -jar sql2java.jar test.properties
pause
I always get class not found exception (the class is in the zip I'm trying to add in the classpath).
I even tried this by executing as admin, but to no avail
set CLASSPATH=lib\dbdriver.zip;%CLASSPATH%
java -jar %~dp0sql2java.jar %~dp0test.properties
pause
The class is inside the zip file (path \oracle\jdbc\OracleDriver) and I'm trying to retrieve it with
jdbc.driver=oracle.jdbc.driver.OracleDriver
Check this doc about java (Java application launcher).
For the -jar option it says -
Executes a program encapsulated in a JAR file. The first argument is the name of a JAR file instead of a startup class name. For this option to work, the manifest of the JAR file must contain a line in the form Main-Class: classname. Here, classname identifies the class with the public static void main(String[] args) method that serves as your application's starting point.
When you use this option, the JAR file is the source of all user classes, and other user class path settings are ignored.
So you either need to package everything in your jar (sql2java.jar) or don't use the -jar option with java launcher command.
You can use java -jar to execute it and define a classpath for the application within the jar's manifest file. See the Java Tutorial on jars for how to set a classpath for the application at http://docs.oracle.com/javase/tutorial/deployment/jar/downman.html
It says:
For example, in a typical situation an applet is bundled in a JAR file
whose manifest references a different JAR file (or several different
JAR files) that serves as utilities for the purposes of that applet.
You specify classes to include in the Class-Path header field in the
manifest file of an applet or application. The Class-Path header takes
the following form:
Class-Path: jar1-name jar2-name directory-name/jar3-name
By using the Class-Path header in the manifest, you can avoid having
to specify a long -classpath flag when invoking Java to run the your
application.
Related
can someone tell me please what are the difference between Rsrc-class-Path and Class-Path sections of a runnable-jar's mannifest file?
Now I take them as granted as generated by Eclipse, but I'd like to understand how it works.
What I think based on how Eclipse generates code seems that the first is about jars my app needs, the second is always .. But I have no clues what folder . refers to.
The Class-Path attribute. This is a standard attribute defined by the JAR file specification. It contains a list of relative URLs for that will be included on the runtime classpath when you run the JAR using java -jar ....
This provides a way to add external JARs (and directories) to the runtime classpath. The entries must be relative, and are resolved relative to the directory containing the main JAR. (For security reasons ...)
The Rsrc-class-Path attribute is non-standard. This is used by Eclipse's "jars-in-jar" launcher. A typical manifest looks like this:
Manifest-Version: 1.0
Rsrc-Main-Class: com.abc.Master
Main-Class: com.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader
Rsrc-Class-Path: ./ lib/xyz.jar
where com.abc.Master is your apps (real) main class, and lib/xyz.jar is a relative URL for a JAR file that is nested within this JAR.. You will also see that the JAR contains the ".class" file for JarRsrcLoader.
This is what happens with you run java -jar this.JAR arg1 arg2.
The JVM is created
The JVM jar loader opens the JAR, reads and parses the MANIFEST.MF above.
It loads the JarRsrcLoader class given by Main-Class/
It calls the above classes main method, passing it ["arg1", "arg2"]
The JarRsrcLoader examines the manifest, and extracts the Rsrc-Class-Path and Rsrc-Main-Class.
Then JarRsrcLoader creates a special classloader that knows how read JARs embedded within the current JAR. The classpath for this classloader is "./" follows by "lib/xyz.jar", where these URLs are resolved within the outer JAR file.
Then JarRsrcLoader loads the class com.abc.Master using the special class loader.
Then JarRsrcLoader calls the main method for com.abc.Master, passing the same string array containing the arguments.
Finally, the application runs.
In short, Rsrc-Class-Path is an attribute that the JarRsrcLoader class understands, and uses to construct the actual application classpath.
In this context, the Class-Path: . attribute serves no real purpose. Everything needed to run JarRsrcLoader will be in the JAR.
As a final note, the SpringBoot loading mechanism is similar, but it uses a different non-standard attribute for the application's main class, and puts the application's resources (e.g. JARs) into a particular directory ("/boot-inf") within the main JAR.
I know that we can invoke a class in a jar file providing the Main-class attribute in the Manifest file. But how can we invoke multiple files in a jar in that way. Or can we invoke a class in a jar file without specifying in the Manifest file using bash.
The Main-Class property in a manifest file makes that JAR file a runnable JAR. You then can invoke that JAR with the command:
java -jar <jar-file>
But you also can directly invoke the main class with the traditional way:
java -cp <jar-file> your.pkg.MainClass
Notice, that you must include your JAR file in the class path, so that Java can find the classes inside it. An additional note: If you don't have a Class-Path property in the JAR's manifest file but your classes depend on other classes in other JARs, you must include all those JARs in the class path:
java -cp <jar-file>;<lib1>;<lib2>;... your.pkg.MainClass
Note, in Linux systems the path separator is a colon, not semicolon.
Another option, besides what #Seelenvirtuose suggested, would be to make the Main class a sort of Front Controller and pass the name of a class you want to invoke as an argument
java -jar app.jar SomeClass
And based on this argument dispatch the request to the corresponding class.
Under Linux I am trying to run a jar file as follows:
java -jar plantuml.jar -testdot
while having CLASSPATH set to any of the following (the file is located at /home/user/plantuml.jar):
export CLASSPATH=/home/user
export CLASSPATH=/home/user/
export CLASSPATH=/home/user/plantuml.jar
In either case, no matter how I define CLASSPATH, the java command gives an error Unable to access jarfile plantuml.jar. What am I doing wrong here?
You have to supply the complete path after the parameter -jar. So for your example you have to call
java -jar /home/user/plantuml.jar -testdot
The $CLASSPATH is only evaluated to find additional files (classes/resources) but not the jar file defined in the command line.
export CLASSPATH="/path/to/class_or_jar1":"/path/to/class_or_jar2":"${CLASSPATH}"
Maybe you are missing name of the main class or path to the jar. Have you tried execute it:
java -jar full_path/plantuml.jar package.YourClass -testdot
Is your program depending on other classes? If yes you might want to add -cp parameter.
The classpath is used to find classes when you refer to them by name. It's essentially a list of paths (directories AND jar/zip files) where the JVM needs to look for classes, or other resources when using methods like ClassLoader.getResourceAsStream().
The value passed to the -jar option on the command line is the file-path to the JAR file.
So, it won't find a jar file if you are only referring to the jar file by name. The JAR file path in the CLASSPATH is supposed to be a path element that 'contains' other resources.
What you need to do here, is either
Provide the full path to the jar file when trying to execute the jar
Set the classpath to the jar file's path, and run the java command giving the name of the main class you want to execute.
Is there a way to pass an external jar file when running a .jar application?
I'm trying to run my jar like this:
java -jar myJar.jar -cp externalJar.jar
The jar file executes fine but I want to look for classes in the external file. I can't include the other classes into my jar, because I want to be able to put any jar file in the same folder as my Jar file and look for classes in there.
The only way to do this right now is by running my app like this:
java -cp myJar.jar;externalJar.jar MainClass
I do not want to explicitly enter the path to my MainClass to run it's main method.
It really seems that the -cp option is completely ignored when you use the -jar option. At least this is what you can read on the manpage of java about the -jar option:
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.
Note that JAR files that can be run with the "java -jar" option can
have their execute permissions set so they can be run without using
"java -jar". Refer to Java Archive (JAR) Files.
I found this in this blogpost here: http://happygiraffe.net/blog/2009/04/30/java-jar-blats-your-classpath/
Did you try adding a specific folder to the classpath during startup and then add your jar file to the folder at later point ?
In Linux, how to execute Java jar file with external jar files?
Either use the -cp flag:
java -cp /path/to/somefolder/*.jar:/path/to/otherfolder/*.jar com.YourMainClass
Or add a Class-Path: header to your jar's manifest (see Jigar's answer)
Note to others who answered with java -jar <etc>: The -jar flag deactivates the standard -cp flag and CLASSPATH environment variable, because it retrieves the classpath from the JAR manifest. Any answer that combines -jar and either -cp or $CLASSPATH will not work.
This information is well-hidden, but I finally found a reference:
-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.
Source: java - the Java application launcher
java -jar /path/to/externalJarFile.jar
Update
You can add the required library in manifest with Class-Path: header
For example :
Class-Path: MyUtils.jar
See
Adding Classes to the JAR File's Classpath