my program consist of
"javax.mail.jar"
and a simple myProgram.java (Contain Main class) ("package:com.test.myprogram")
and anotherProgram.java (contain Main class) ("package:com.test.myprogram")
I have converted it to "myprogram.jar" file
how do I run "myProgram.java" in shell? using "myprogram.jar"
If your application is in (say) "myprogram.jar" and it depends on "javax.mail.jar", then you would run it like this:
$ java -cp myprogram.jar:javax.mail.jar com.test.myprogram.Main
(On Windows, you need to use ; instead of : as the classpath separator.)
However, it doesn't make a lot of sense to have "myProgram.java" and "anotherProgram.java" BOTH declare a Main class ... by which I assume you mean a class called Main. The problem is that since both versions of the Main class are in the same package, compiling one source file will overwrite the Main class produced when you compile the other source file.
java -classpath yourjarfilename.jar yourpackagename.classname
Related
Trying to compile and run my java program from the commandline that is set up a bit weird. The file structure is as follows:
[ROOT]/
|
|____libs/
| |____myExtraJar.jar
|
|____src/
|____main/
|____com/
|____example/
|____myClass.java
The package is defined at the top of the java file as
package com.example;
I am able to compile the program fine (I think) while in the root folder, using
javac -classpath "/libs/myExtraJar.jar" src/main/com/example/*.java
I don't get any compilation errors (such the ones that occur if I leave off the classpath) and I can see that .class files are being created in the com/example/ folder. However, I can't find any way to run the compiled program. Running
java src/main/com/example/myClass
results in the message
Error: Could not find or load main class src.main.com.example.myClass
Any help would be appreciated.
You need to specify the classpath when you run it, and you also need to use the fully-qualified classname. Like,
java -cp "libs/myExtraJar.jar:src/main" com.example.myClass
Elliot is right. More precisely, you need to add the build directory to your classpath. It is the directory containing your *.class files, and is sometimes named target/.
$ java -cp "target:lib/myExtraJar.jar" com.example.myClass
Moreover, src/main/com/example/myClass should be com.example.myClass, which is the fully-qualified class name. See http://www.manpagez.com/man/1/java/ for details of the java command.
I am relatively new to Java but have a fair understanding about how the class path works with respect to providing a list of folder and jars that make classes available to other classes.
I have compiled a JAR (lets say example.jar) that has a main function where execution normally begins. Sometimes I want execution to begin in a different class (lets say myAlternateClass.java), with its own main. I can achieve this by doing using the -cp argument when executing the jar, for example;
java -cp example.jar myAlternateClass
This works as I require but I am unsure of what exactly is happening here.
I'm not 100% sure on exactly what you're looking for, but I'll give it a shot.
There are two ways to use a jar file. If the jar file has a Main-Class specified in its META-INF/MANIFEST.MF file, then you can load java with the jar file and execution will start in the main method of that class.
java -jar example.jar
On the other hand, a jar file can simply be loaded onto the classpath, which makes all of the classes within it available for use. This is the example you are giving:
java -cp example.jar org.somewhere.MySecondClass
The -cp example.jar puts all of the classes within the jar on the class path and the second argument org.somewhere.MySecondClass gives the class at which execution should begin. This second argument would have to be within the jar since specifying a classpath overrides the default (which is just the current directory). In this case, java ignores any Main-Class specified in the MANIFEST.MF file of the jar (if one even is specified).
Multiple jar files as well as directories of java files not in a jar can be specified by putting colons between them. So,
java -jar example.jar:. MyClass
could launch MyClass from the current directory, but place example.jar on the classpath so that MyClass could create instances of whatever classes are available within example.jar.
I have a package with some classes inside D:\ProjectGsc\. The package root folder is called gsc and contains three subdirectories namely util,core and modules. Inside each of them are some files and inside core there is a file named gsc.class. Apart from those there is also a folder res inside the gsc folder that contains some images that are used by the JFrames and JDialogs inside my package's classes. I manage to compile everything using -classpath \projectgsc and, as the code has been debugged, everything is compiled smoothly. But I cannot run it at all. I try to java gsc -classpath \projectgsc while I am inside D:\ProjetctGsc\gsc\core\ but it gives me exception in thread main (syntax of main is correct for sure) java.lang.NoClassDefFoundError: gsc (wrong name: gsc/core/gsc). Is it because of the name of my class being gsc inside package gsc.core?
Thanks in advance! (Btw SO does not allow me to name the question "Classpath problem when running" so this is the best title I could come up with, feel free to edit it)
Yes, to run a class called gsc (which violates Java naming conventions, btw) in a package gsc.core (ick - package name containing the class name; confusing!) you'd write
java -classpath d:\ProjectGsc gsc.core.gsc
But you'd have to compile it so that you had a directory structure of
d:\ProjectGsc
\gsc
\core
\gsc.class
You'll get this automatically if you use the -d option to javac:
javac -d d:\ProjectGsc *.java
(Adjust accordingly, of course.)
You may well find that if you're new to Java, using an IDE which handles all of this for you would make your life easier.
Okay, I'm very new to linux and command line, and fairly new to java. I got an internship building a java program. I finally got it done on my machine (windows) and now I have to migrate it to a linux machine to test and then have it run as an executable. I have done much reading and researching on linux and understanding classpaths but it is still all very hard to fully comprehend. It's just not clicking for me yet. Can anyone explain the purpose of classpath in a simplified way using examples? One of the most confusing aspects to me is actually defining the physical path to the jar. Do I start all the way from usr or do I only need to begin from the jvm folder? If it matters, my java program is not located in the jvm folder. Can anyone shed some light for me?
EDIT: thank you guys very much for your help, I can't say that I'm fully in the clear but my understanding of my situation is a lot better.
Say you have multiple jar files a.jar,b.jar and c.jar. To add them to classpath while compiling you need to do
$javac -cp .:a.jar:b.jar:c.jar HelloWorld.java
To run do
$java -cp .:a.jar:b.jar:c.jar HelloWorld
You use the -classpath argument. You can use either a relative or absolute path. What that means is you can use a path relative to your current directory, OR you can use an absolute path that starts at the root /.
Example:
bash$ java -classpath path/to/jar/file MyMainClass
In this example the main function is located in MyMainClass and would be included somewhere in the jar file.
For compiling you need to use javac
Example:
bash$ javac -classpath path/to/jar/file MyMainClass.java
You can also specify the classpath via the environment variable, follow this example:
bash$ export CLASSPATH="path/to/jar/file:path/tojar/file2"
bash$ javac MyMainClass.java
For any normally complex java project you should look for the ant script named build.xml
The classpath is the place(s) where the java compiler (command: javac) and the JVM (command:java) look in order to find classes which your application reference.
What does it mean for an application to reference another class ? In simple words it means to use that class somewhere in its code:
Example:
public class MyClass{
private AnotherClass referenceToAnotherClass;
.....
}
When you try to compile this (javac) the compiler will need the AnotherClass class. The same when you try to run your application: the JVM will need the AnotherClass class.
In order to to find this class the javac and the JVM look in a particular (set of) place(s). Those places are specified by the classpath which on linux is a colon separated list of directories (directories where the javac/JVM should look in order to locate the AnotherClass when they need it).
So in order to compile your class and then to run it, you should make sure that the classpath contains the directory containing the AnotherClass class. Then you invoke it like this:
javac -classpath "dir1;dir2;path/to/AnotherClass;...;dirN" MyClass.java //to compile it
java -classpath "dir1;dir2;path/to/AnotherClass;...;dirN" MyClass //to run it
Usually classes come in the form of "bundles" called jar files/libraries. In this case you have to make sure that the jar containing the AnotherClass class is on your classpaht:
javac -classpath "dir1;dir2;path/to/jar/containing/AnotherClass;...;dirN" MyClass.java //to compile it
java -classpath ".;dir1;dir2;path/to/jar/containing/AnotherClass;...;dirN" MyClass //to run it
In the examples above you can see how to compile a class (MyClass.java) located in the working directory and then run the compiled class (Note the "." at the begining of the classpath which stands for current directory). This directory has to be added to the classpath too. Otherwise, the JVM won't be able to find it.
If you have your class in a jar file, as you specified in the question, then you have to make sure that jar is in the classpath too , together with the rest of the needed directories.
Example:
java -classpath ".;dir1;dir2;path/to/jar/containing/AnotherClass;path/to/MyClass/jar...;dirN" MyClass //to run it
or more general (assuming some package hierarchy):
java -classpath ".;dir1;dir2;path/to/jar/containing/AnotherClass;path/to/MyClass/jar...;dirN" package.subpackage.MyClass //to run it
In order to avoid setting the classpath everytime you want to run an application you can define an environment variable called CLASSPATH.
In linux, in command prompt:
export CLASSPATH="dir1;dir2;path/to/jar/containing/AnotherClass;...;dirN"
or edit the ~/.bashrc and add this line somewhere at the end;
However, the class path is subject to frequent changes so, you might want to have the classpath set to a core set of dirs, which you need frequently and then extends the classpath each time you need for that session only. Like this:
export CLASSPATH=$CLASSPATH:"new directories according to your current needs"
For linux users, you should know the following:
$CLASSPATH is specifically what Java uses to look through multiple directories to find all the different classes it needs for your script (unless you explicitly tell it otherwise with the -cp override). Using -cp (--classpath) requires that you keep track of all the directories manually and copy-paste that line every time you run the program (not preferable IMO).
The colon (":") character separates the different directories. There is only one $CLASSPATH and it has all the directories in it. So, when you run "export CLASSPATH=...." you want to include the current value "$CLASSPATH" in order to append to it. For example:
export CLASSPATH=.
export CLASSPATH=$CLASSPATH:/usr/share/java/mysql-connector-java-5.1.12.jar
In the first line above, you start CLASSPATH out with just a simple 'dot' which is the path to your current working directory. With that, whenever you run java it will look in the current working directory (the one you're in) for classes. In the second line above, $CLASSPATH grabs the value that you previously entered (.) and appends the path to a mysql dirver. Now, java will look for the driver AND for your classes.
echo $CLASSPATH
is super handy, and what it returns should read like a colon-separated list of all the directories you want java looking in for what it needs to run your script.
Tomcat does not use CLASSPATH. Read what to do about that here: https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html
Step 1.
vi ~/.bashrc
Step 2. Append this line on the last:
export CLASSPATH=$CLASSPATH:/home/abc/lib/*; (Assuming the jars are stored in /home/abc/lib)
Step 3.
source ~/.bashrc
After these steps direct complile and run your programs(e.g. javac xyz.java)
I have created an executable jar file that contains two main classes. All libraries are included in the jar and the main Main-Class works fine when executing like this:
java -jar MyApplication.jar
But when I try to run the other main class like this:
java -cp MyApplication.jar my.other.mainClass
It does not include the classpath of the manifest.mf and it can not find the libraries that are in the jar file.
Is there a simple way so that the other main class can use the classpath from the manifest.mf? or should I create two separate executable jars?
You could write a class that invokes the main method of whatever class is passed as its first argument using Reflection - and configure this as the Main-class in your jar. This way you can invoke multiple main methods from the same jar with java -jar file.jar my.other.mainClass
Is there a simple way so that the other main class can use the classpath from the manifest.mf? or should I create two separate executable jars?
The JAR manifest classpath is only used if you use -jar option, and conversely the command line argument is only interpreted as a classname if -jar is NOT used. You cannot mix the two approaches.
However, this doesn't mean you have to create a second JAR file. For instance, you could write a simple shell script to launch the JVM using the classpath copied from the manifest and the secondary entry point classname.
Are you sure your problem is with libraries within the jar? What version of java are you using?
I suggest you try the following:
java -cp MyApplication.jar <add external libraries here> my.other.mainClass
So you only need to add paths to classes that are not already in the jar. You can use wild cards to shorten the list.
Here is another interesting option, Enable your unrunnable JARs to run with the java -jar command. It describes how to select a main class in the jar file and make another runnable copy.