Compiling Java programs in command line - java

Do I have to run set Class and Set ClassPath in Commandline every time for compiling Java programs with these commands
set class ="C:\Program Files\Java\jdk1.8.0_121\bin";
set classpath="C:\Program Files\Java\jre1.8.0_121\lib\rt.jar";
C:\>Javac Test1.java
C:\>Java Test1
even I added up folder up to bin in environment variable for setting up the environment variable.If I do not run SET CLASS and SET CLASSPATH, I get an error Error: Could not find or load main class Test1
Please answer thanks.

What i would do is :
1) Add jdk path to PATH.
2) Create a folder with all my classes in , the cd to that folder "javac" every class and then "java" the one containing the "main" method.

You also need the path where your compiled class files are in your classpath!
You only included the tools.jar - but not your class file(s).
When compiling, you should only point to those JVM classes, but when running your application, your classes need to be found too!

Related

Class in jar not found at runtime, but was used to compile

After I build this project from an ant file, I recieve a jar that contains all of the classes I built. When I try to run this jar, I get the following error:
Exception in thread "main" java.lang.NoClassDefFoundError: javax/media/j3d/SceneGraphObject
This error indicates that a one of the jars, specifically the j3dcore.jar from java3d, I am using can not be found. However, this jar is on the classpath when compiling through the ant build into the class files.
Why can this class not be found at runtime, but it is found at compile time? Do I have to manually change my classpath in my shell when running the jar as well as change it in the ant build?
If I add the jars to my classpath using java -cp j3d/*.jar -jar idv.jar
I get the error Error: Could not find or load main class j3d.j3dutils.jar
Do I have to manually change my classpath in my shell when running the jar as well as change it in the ant build?
Yes, absolutely. Making a class available at compile-time doesn't embed the class into your output or anything like that. It just makes it available to the compiler (to find out what methods are present etc).
If I add the jars to my classpath using java -cp j3d/*.jar -jar idv.jar
Yes, it would - because that's being expanded into:
java -cp j3d/foo.jar j3d/bar.jar ... -jar idv.jar
It's not clear to me whether -cp is meant to work at all with -jar, given this documentation:
When you use this option, the JAR file is the source of all user classes, and other user class path settings are ignored.
One option is to set the classpath within the manifest of the jar file itself. For example:
Class-Path: j3d/foo.jar j3d/bar.jar
Another would be to ignore the -jar command-line option for now, and use:
java -cp j3d/*:idv.jar your.class.name.Here
Note the * rather than *.jar, as documented:
As a special convenience, a class path element containing a basename of * is considered equivalent to specifying a list of all the files in the directory with the extension .jar or .JAR (a java program cannot tell the difference between the two invocations).

How to add multiple jar files in classpath in linux

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)

Again "wrong name" error when executing java program

With reference to this post
Receiving "wrong name" NoClassDefFoundError when executing a Java program from the command-line
I did not understand how to solve the problem
Actually in my java source code there' s line :
package es_2011;
when I compile the program through JCreator everything works perfectly.
It creates a folder named es_2011 where to put .class files.
Also the executing operation goes smoothly, the program runs ok.
Now I'd like to use the command line only.
So I placed my java file in the directory where javac.exe is but whenever I try to compile I get the same error
The command I use is: javac ProgAudioJ.java
The path (where javac.exe is ) is : C:\Program files\Java\jdk1.6.0_22\bin
Is someone willing to help me understand in terms of exactly tell me what I have to do?
thanks very much...MAX
The setup used for the looks like this (under windows)
C:\classDir -> is the project
C:\classDir\testpackage -> is the only package used (the package "testpackage")
C:\classDir\testpackage\Main.class -> is the class with the main method inside (important: it is the .class and not .java)
The Main.class looks like following:
package testpackage;
public class Main {
public static void main(String[] args) {
System.out.println("Program started! ;-)");
}
}
go with your command prompt to:
c:\classDir> java testpackage.Main
the result:
Program started! ;-)
According to your problems that it starts in your IDE but not from the console:
- checked if you realy use the path to the .class files?
- with the console go to the directory of you .class files, not the project (e.g. in Eclipse it is the bin directory
- enter the full qualified class name (including packages seperated by . -> e.g. testpackage.Main
More infos can be found under:
http://www.oracle.com/technetwork/java/compile-136656.html
Hope it helped
MAX, if the class defines that it's inside the package es_2011, then it should be in a folder with the same name.
So in your case, put the ProgAudioJ.java in the folder es_2011 and then run
javac es_2011\ProgAudioJ.java
latter to run it, you need the command
java es_2011.ProgAudioJ
You should add javac.exe in your path .Edit your path variable and append path to jdk's bin
then put java file in a dir named es_2011 , as the package declaration is es_2011 then compile
c:\es_2011\javac YourJava.java
and now go back to C:
c:\java es_2001.Yourjava
After reading you other Post: "Receiving "wrong name" NoClassDefFoundError when executing a Java program from the command-line" I guess you go to the directory es_2011 where your ProgAudioJ.class file is located and run
java ProgAudioJ
from that folder.
instaend you have to go to the folder above (cd ..) and run
java es_2011.ProgAudioJ
Each package in Java corresponds to a folder on the filesystem. So a package declaration such as com.stackoverflow would mean that the source classes need to be in a folder ./com/stackoverflow. Typically the whole project would have a separate src folder containing com/stackoverflow.
When you compile the Java classes you DO NOT need to put source files in the same directory as javac.exe, you do however need to make sure that javac.exe is in your operating systems PATH variable. This tells the operating system where it should look for executable files when a command is run, on a *nix machine this would usually be /usr/bin or just /bin but on Windows machine the executables normally live within the applications own directories, that is C:\Program Files\something. Assuming that you've installed JDK correctly, the javac.exe should already be in the PATH you can check this by opening the command line and just running javac (just like that). If you get some output then all is well, the system knows where to find javac.exe.
Next you will need to go to your project folder and type javac -d . src/com/stackoverflow/MainSO.java notice that is run from the project folder. This will create a folder called com in your project root and put the compiled classes in com/stackoverflow. The -d flag tells javac where to put the compiled classes, if you leave that out, the compiled classes will be where the sources are.
Then when you want to run the classes you type java com.stackoverflow.MainSO (no .class). Crucially this command will need to be ran in the directory that contains the root of the class hierarchy (that is the com folder containing the compiled classes). You can specify other places for java to look for the classes by providing a classpath to the java command with the -cp flag. By default the classpath will contain the directory the java command was ran in. Should your project have dependencies external .jar files for example you will need to provide every single one of them (with their full filepath) in the classpath (this goes for the compiler as well). The IDEs do this automatically for you.
Hope that helps.

Java command-line problems with .jar libraries

I have a single .java (driver.java) file I'm trying to compile and run from the command-line. It uses the external library called EXT.jar, whose structure is just a folder called EXT with a few dozen classes within it.
So I run:
javac -cp EXT.jar driver.java
This compiles the class just fine.
then when I run:
java -cp EXT.jar driver
I get a java.lang.NoClassDefFoundError.
Oddly enough, if I unpack the JAR (so now I have a folder in the root directory called EXT), the last command works just fine!! Driver will execute!
Is there any way I can make the driver.class look for the need class files from EXT.jar/EXT/*class instead of an actual EXT folder?
Thanks!
You're compiling the class to the local directory. So when you run it, you need to include the current directory in your classpath. E.g.:
java -cp .;EXT.jar driver
Or in linux:
java -cp .:EXT.jar driver
With the way you have it now, you're saying your classpath is only EXT.jar (along with whatever is in the CLASSPATH environment variable) and nothing else (which is why the current directory, where driver.class is located, is excluded)

java gui testing

in the java test I have :
package Tester.GUI.api
public class Test1{-----}
in the ".bat" :
<path to java> -classpath<all jar defined in the classpath separated by ";"> org.junit.runner.JUnitCore Tester.GUI.api.Test1
when I launch th ".bat" I have the following :
JUnit version 4.6
Could not find class: Tester.GUI.api.Test1
Time: 0,203
OK (0 tests)
I have verified jar files , typo but not found the cause
someone could help please?
The -classpath option needs to take a set of directies and/or jar files. Currently those are missing, so your main class (JUnitCore) is being used as the classpath, and Test1 used as the main class. I'm guessing you want JUnitCore as the main class and Test1 as the argument.
Try something like this (substituting the actual names of the jars you're using for jar-file1, jar-file2):
java -classpath <jar-file1.jar>;<jar-file2.jar> org.junit.runner.JUnitCore Tester.GUI.api.Test1
Edit:
Assuming jar files are specified correctly, the error message indicates that the Test1 class isn't on the classpath. If you're using an IDE, you need to find the output directory for compilation (for example, in Eclipse it is <project>/bin by default). Within this directory you will find other directories with the structure Tester/GUI/api. A file called Test1.class will be in the api directory. It is this output directory that needs to be added to the classpath (that is, the one above the Tester/GUI/api structure).
It says that the class that it cannot find is Tester.GUI.api.Test1. What directory are you running the test from, and what directory is your Test1 code in?
If you set the -classpath variable, you may also need to include the current directory in your classpath. So, if your original command was
java -classpath C:\foo.jar;D:\bar1\bar2.jar org.junit.runner.JUnitCore Tester.GUI.api.Test1
you could add the current directory to your classpath by adding ;. to the end of your -classpath option like this:
java -classpath C:\foo.jar;D:\bar1\bar2.jar;. org.junit.runner.JUnitCore Tester.GUI.api.Test1
This will work as long as the Test1 class is in the Tester\GUI\api directory under the current directory.
The tricky thing with setting the classpath in Java is that you don't want to give the directory where your actual .java files are, but instead you want to give the directory under which you can find the directories that are named for the packages in your code.
For example, if I compiled a class Foo in a package bar.baz, then I should have a file named Foo.class in a directory named baz inside another directory named bar. If I want to include Foo in my classpath, and if Foo.class is located at
C:\Users\Joe\Code\bar\baz\Foo.class, then I have to either run
java -classpath C:\Users\Joe\Code [main class goes here]
or else I have to change my directory to C:\Users\Joe\Code and run
java -classpath . [main class goes here]

Categories