From some experienced java coders I want to ask what is difference between using
javac <filename>
java <file_name_without_extention>
And
java <filename>
They're equivalent if your source code is only a single file. The former (with the two commands) is the general way to compile and run Java source code, and it's still the correct way to compile larger projects. The latter is a new feature added in JDK 11 to make it easier to run individual files and very small programs.
From the proposal that suggested the feature
In source-file mode, the effect is as if the source file is compiled
into memory, and the first class found in the source file is executed.
For example, if a file called HelloWorld.java contains a class called
hello.World, then the command
java HelloWorld.java
is informally equivalent to
javac -d <memory> HelloWorld.java
java -cp <memory> hello.World
javac <Filename> - a java command that compiles java source files into bytecodes.
It needs an extension because you are compiling the source file.
java -cp <classpath> <Classname> - a java command that executes the compiled bytecodes.
It does not need an extension because you are merely telling it to search for the Class and its main() signature from the classpath to execute.
Related
Most websites on the internet say:
"use the javac command to compile a .java file. Then run it using the java command"
But today I tried to run a java program without javac and I got a strange result.
Here are the contents of a file called hello.java:
public class Myclass {
public static void main(String[] args){
System.out.println("hello world");
}
}
Then I ran:
$ javac hello.java
Which gives me this error:
hello.java:1: error: class Myclass is public, should be declared in a file named Myclass.java
public class Myclass {
^
1 error
But when I run it without the javac command, it executed without any errors.
$ java hello.java
hello world
Does the java command also compile the program? If yes, why do we need the javac command?
The version of my java is:
openjdk version "12.0.2" 2019-07-16
OpenJDK Runtime Environment (build 12.0.2+10)
OpenJDK 64-Bit Server VM (build 12.0.2+10, mixed mode)
Prior to Java 11, to run your code you have to first compile it, then you can run it. Here's an example:
javac test.java
java test
Since Java 11, you can still do javac + java, or you can run java by itself to compile and auto-run your code. Note that no .class file will be generated. Here's an example:
java test.java
If you run java -help, you'll see the various allowed usages. Here's what it looks like on my machine. The last one is what you ran into: java [options] <sourcefile> [args] which will "execute a single source-file program".
$ java -help
Usage: java [options] <mainclass> [args...]
(to execute a class)
or java [options] -jar <jarfile> [args...]
(to execute a jar file)
or java [options] -m <module>[/<mainclass>] [args...]
java [options] --module <module>[/<mainclass>] [args...]
(to execute the main class in a module)
or java [options] <sourcefile> [args]
(to execute a single source-file program)
UPDATE:
As pointed out by #BillK, OP also asked:
why do we need the javac command?
The reason we need javac is to create .class files so that code can be created, tested, distributed, run, shared, etc. like it is today. The motivation for JEP 330 was to make it easier for "early stages of learning Java, and when writing small utility programs" without changing any other existing uses.
If you are running Java 11, there is a new feature that allows single source file execution. The single source compiler is more promiscuous in terms of class name versus file name, so that is how you are able to run but not successfully compile.
If you are on a previous version of Java, then your current hello.java does not compile, because of compile errors, specifically around the class name. So there's absolutely no way that calling java hello.java compiled your code, because it does not compile.
It seems most entirely likely that you were running some previously compiled code when executing the java command.
To answer why this error is given, the class name for the file must match the file's basename.
You have two options to have this code work for the traditional javac; java sequence:
Rename the class to public class Hello or
Rename hello.java to myclass.java.
The java interpreter for Java 11 does not impose this requirement. The class that contains main can have any name, as long as it is the first class in the file. This was mainly intended to ease the learning process for beginners, and to allow "java scripting" with the shebang (ref.).
Yes, but not in the way you probably mean.
When you use the javac command to compile a .java file to a .class file the output is something called bytecode. Bytecode is a the machine code (native instructions) for a theoretical CPU based on the Java Virtual Machine specification.
This virtual CPU specification is sort of an average of types of CPUs that were common at the time the specification was written. Because of this it is close to lots of different types of CPU making it easier to run the same Java .class files on multiple CPU types.
When Java was first launched the java command would read the .class file and interpret the bytecode instructions one at a time and then map them to the equivalent native instruction for what ever CPU it was actually running on. This worked but wasn't particularly fast. To improve this Just in Time (JIT) compilation was added to the Java Runtime.
With JIT the java command takes the bytecode and compiles it again to the native instructions for the CPU it is running on. Modern Java runtimes tend to start out interpreting the bytecode while JIT compiling in the background and switch to the compiled native instructions when it's ready and will also profile the running application and then recompile the bytecode again with different optimisation to get the best possible performance.
EDIT (to appease the down voters):
So in your specific case (as you are running a JRE newer than v11) the code is compiled (at least) twice
As a single .java file to bytecode
Via the JIT compiler as it interprets the bytecode (though for helloWorld it might not actually get time to run any of the compiled native code)
I am running Java program from command line. I am referring to only 1 external jar file. i have added entire path to that jar in classpath. even then i get no class def found error while running program in command line. Program compiles without any error.
I think you complied and run the Java program like this
javac -cp fullyqualifiedPathToExternalJar yourfilepath/filename.java
java -cp fullyqualifiedPathToExternalJar yourfilepath/filename
This is totally wrong. When you compiled and run in this manner program compile successfully but not run. This because you have to follow the syntax of java command Properly.
for compiling its Ok.
javac -cp fullyqualifiedPathToExternalJar yourfilepath/filename.java
To run the program you have to add your file path to the classpath:
java -cp fullyqualifiedPathToExternalJar;yourfilepath filename.java //in windows
java -cp fullyqualifiedPathToExternalJar:yourfilepath filename.java //in linux
The syntax is
javac example.java
java example
with folderpath
javac /home/admin/example.java
java -cp /home/admin example//only class name
Might be the chances of jar's compatibility issue. check yous inter dependent jar versions.
I have trying to compile java files at the windows command line using commands such as:
java myProg once I have used javac to create class files.
Problems arise when I use packages with a number of source files.
Often but not always I get main not found errors even though a main exists.
I am not quite sure what some of the directives mean and that is why it seems hit or miss.
Question
what does -cp mean exactly? java -cp src\myDirectory.myfile
sometimes I see:
./ infront of source eg .\src\myDirectory.myfile
on other sites I have found
% javac -cp .;stdlib.jar MyProgram.java
% java -cp .;stdlib.jar MyProgram
while compiling a jar library with java source files
what doesthe ".;" mean?
basically how do I compile three java source java files in one package at the windows command line and what does -cp and .; mean?
-cp means class path if I'm not mistaken.
try reading the following java docs
-classpath path
Specifies the path javac uses to look up classes needed to run javac or being referenced by other classes you are compiling. Overrides the default or the CLASSPATH environment variable if it is set. Directories are separated by semi-colons. It is often useful for the directory containing the source files to be on the class path. You should always include the system classes at the end of the path. For example:
javac -classpath .;C:\users\dac\classes;C:\tools\java\classes ...
https://www.cis.upenn.edu/~bcpierce/courses/629/jdkdocs/tooldocs/win32/javac.html
Answering your question directly, -cp means classpath or path.
Details on commandline arguments used while compiling and running a Java application can be found here: javac - Java programming language compiler
Extracting the description of -cp from that page:
-cp path or -classpath path:
Specify where to find user class files, and (optionally) annotation processors and source files. This class path overrides the user class path in the CLASSPATH environment variable. If neither CLASSPATH, -cp nor -classpath is specified, the user class path consists of the current directory. See Setting the Class Path for more details.
. means the current directory.
To compile multiple files in a directory use the following:
javac *.java // compliles all java files in the dir
java MyClass // runs the particular file
There are also a bunch of other related questions that should help you resolve this:
How to run a java program from the command line
How do I run java program with multiple classes from cmd?
Problems running a java program from the command line interface
Can't run multiple-class program from command line using packages
I just installed cygwin and I am wondering how do I compile and run my java code through cygwin?
My java code is at my desktop saved in a file named Java.
Assuming you have Java SDK for Windows installed.
In the simplest case:
Ensure/Add java to PATH in cygwin:
export PATH=$PATH:"/cygdrive/C/Program\ Files/Java/jdk1.8.0_31/bin/"
(don't forget the backslash after Program)
cd to your desktop:
cd /path/to/Desktop
run java compiler:
javac HelloWorld.java
In complex projects you will need to provide a bunch or arguments to javac to make it compile.
What is the difference in calling the -classpath option from javac and from java
for example:
javac -classpath MyJar.jar GetJar.java
java -classpath MyJar.jar:. GetJar
it works as well as:
javac -classpath MyJar.jar GetJar.java
java GetJar
So basically where the first -classpath related to javac needs to be there, on the other hand in the java command line it might be optional. Why? Do you know in which circumstance it would be mandatory. And more in general what is the effect of -classpath called by javac and what is the effect of -classpath called by java.
Thanks in advance.
One is the classpath used for compiling. The other is the classpath used for running. And they do not have to be the same thing. The set of classes needed for the compilation processes are all those referred to by every class being compiled. Whereas your runtime JAR could be invoking a standalone class with an empty main method and no dependencies.
Just remember that at runtime class dependencies are resolved dynamically, aka a class is only loaded when it is needed (this is a generalization, boot and system classes are always loaded).
This document contains answers for your questions
http://docs.oracle.com/javase/1.4.2/docs/tooldocs/windows/javac.html
using -classpath every time is a very time consuming work. Instead, use environment variables (if you are dealing with a package such as Java Mail)
classpath is used for compiling. Javac is the Java Compiler, where it converts your code into byte code.
When it comes to java it is used to run your Java source file/jar.