What is the mechanism of java and javac? - java

I just picked up my Ubuntu machine after a long time for some java related work and found that I have java already installed but not javac.
I made a Test.java file with a main method and a simple print statement. I wrote this in my terminal:
java Test.java
I expected that without javac this shouldn't compile and run but it printed the output on my console. I then installed a JDK to enable the javac and ran this:
javac Test.java
This created a Test.class file. Still to run the Test class I need to type java Test.java and on typing java Test it throws java.lang.NoClassDefFoundError.
Can someone please explain to me what's happening in the background of these commands?
Edit:
Here are the contents of my Test.java:
package Learning;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Hello World!");
}
}

What you experience here is a new feature, added for Java 11:
In Java SE 11, you get the option to launch a single source code file directly, without intermediate compilation. Just for your convenience, so that newbies like you don't have to run javac + java (of course, leaving them confused why that is).
Quoted from here. For more details, see the corresponding JEP 330.
So: if you have a single self-contained .java file ... then the java binary recognizes that, compiles it, and directly runs it (when using Java 11 or newer).
But keep in mind: it is just that, a way to quickly run a single class. It isn't meant to replace the "real" way of doing things.
In general, you still use javac first, and then java. Or, more real world: you use a built system where you describe what to build, and then the build system invokes javac for you behind the covers.

GhostCat's answer is good, but here are a few additions taken from a longer post about this same behavior.
Can someone please explain to me what's happening in the background of these commands?
What you ran into – where you can use "java" (not "javac") to
compile and run a program in one command – JEP 330: Launch Single-File Source-Code Programs –
was designed to make it easier for "early stages of learning Java, and when writing small utility programs".
It's definitely
not meant to replace anything – use it if convenient, but nothing changes with the normal steps of "compile to .class file" and "run JVM using .class files or JARs".
There's some good info in the JEP 330 link, but also in the java command itself, namely that one option (among four total) is to provide a single filename (which is what you did)
To launch a single source-file program:
java [options] source-file [args ...]
Further, there's a nice summary in Using Source-File Mode to Launch Single-File Source-Code Programs:
In source-file mode, the effect is as though the source file is compiled into memory, and the first class found in the source file is executed. Any arguments placed after the name of the source file in the original command line are passed to the compiled class when it is executed.

Related

What is JAVA exec()uting?

I'm on Linux and I have a Java application (JAR archive) which is using exec() to do it's stuff. I need to find out which commands is that application exec()uting... I tried strace and jstack but without any results. Suppose that the app is calling exec("ls"), can I find that ls command just by grepping output of above programs?
So the question is:
Is there a simple way to watch what is Java application executing with exec() ?
Edit for better situation overview:
Suppose that in Java app i have a button with onclick listener which calls static function from another class.In that function is exec("ls"); called.
When I click that button I see this in strace:
futex(0x7f14a6f799d0, FUTEX_WAIT, 4968, NULLDownload button clicked !
Trying SCP FROM...
<unfinished ...>
Trying SCP FROM.. is just my sout in that button handler right before calling exec().
Another edit:
Thank you guys, but I'm talking from OS point of view... Suppose that I'm sysadmin and I downloaded JAR. I want to know (from outside) what is that JAR doing - I'm only interested in programs started from exec()
So I tried strace but it shows nothing about calling that command from exec... Maybe it is logging too much low level calls for this...
Then i tried jstack -m but I can't find anything looking like that command from exec. I tried grepping string but with no luck.
Ok, what I'm going to propose is a veeeeeeeeeery rudimentary way of doing things, but it might be what you are looking for.
As you probably know, a .jar file is just a ZIP archive comprised of Java .class files. If you just need to get a peek at which commands are going to be executed, and if you know the class that is supposed to execute them, you can just extract the class files from the jar file with gzip and then use strings on them to look for commands.
For example, here's the most simple class I could think of that uses exec():
import java.io.IOException;
public class Main {
public static void main(String[] args) {
try {
Runtime.getRuntime().exec("/bin/ls");
} catch (IOException ignored) {}
}
}
If you do strings Main.class you should get something like this:
[...]$ strings Main.class
<init>
Code
LineNumberTable
LocalVariableTable
this
LMain;
main
([Ljava/lang/String;)V
args
[Ljava/lang/String;
StackMapTable
SourceFile
Main.java
/bin/ls
java/io/IOException
Main
java/lang/Object
java/lang/Runtime
getRuntime
()Ljava/lang/Runtime;
exec
'(Ljava/lang/String;)Ljava/lang/Process;
As you can see, /bin/ls can be identified as a string. This should work in most cases, unless your Java program is constructing commands in a weird way, like using a char array to create command strings during runtime just to obscure the commands being executed (in which case I'd be highly suspicious of such a program).
However, if you want to see the commands executing in real time, I'm afraid you'll need to resort to some monitoring utility, since most commands would be too short-lived to even appear on top and the like.
EDIT: Regarding strace: I had a look at Java's native C code for UNIX systems and it seems that it actually uses the execvpe() system call to run all commands launched with Runtime.exec():
execvpe(argv[0], argv, envv);
So, in theory, you should be able to run strace -e execvpe <java command...> to list every command executed (as well as every other call to execvpe() -- you'll need to filter a bit more, that's true).

Is it possible to compile and run java without using any shell?

This question just popped to my mind.
To compile java, we need to use the $JAVA_HOME/bin/javac file and pass to it the java files that needs to be compiled.
I was wondering if it is possible to execute javac file without using the bash/shell.
Or use any other programming languages to execute the javac file directly?
Yes, it is possible.
#include <unistd.h>
int main(void)
{
execl( "/path/javac","javac", "/path/to/program.java", NULL );
return 0;
}
That C program will execute the compiler and compile program.java without using a shell. Just run it also without using a shell and you have run the compiler without a shell.
It is not a very useful program, it always compiles the same single file. But it is possible to modify it to read a file with a list of files to compile. Which is actually what IDEs do. And that is another way of running javac without a shell.
As for running the compiled java program the same principle applies. Create a program which runs the java interpreter.
It is not possible to use javac without, on some level, executing it as a shell command, because by its nature it is a command line program. This means that it can be executed from any programming language that can execute native shell commands.
What most people do after learning how javac works by executing it manually from a shell is configure their IDE to execute javac with the correct arguments when developing, and configure a build technology such as maven or ant to execute javac to produce their deployable application package.

How do I run a Java program on Terminal (Mac)?

I am new to Java (as of today!) and am trying to run a very simple program in terminal. Normally, when I run a python (still pretty new) program in Terminal I would simple type in "python name.py" in to terminal and it would run. When I type "Java name.java" it does absolutely nothing.
I opened TextWrangler and selected "Run in Terminal" and it returned this error:
"This file doesn't appear to contain a valid 'shebang' line (application error code: 13304)"
My program is named "hello.java" and it contains the code below.
What am I doing wrong?
System.out.println("Hello!");
Open the terminal, go to the directory where the file is located and do this:
javac -classpath . name.java // compile the code
java name // run the program
Of course, both javac and java must be available in the operating system's PATH variable, but in a Mac that's already configured.
Type
javac helloworld.java
java helloworld
The first line calls the compiler and compiles it in the current directory
then the next line runs it
"Run in terminal" attempts to run the software as an interpreted script. On UNIX-like systems (meaning almost everything except Windows), a shebang line is used to indicate, what interpreter is to be used. It consists of the characters #! followed by the command to invoke the interpreter (e.g. #!/usr/bin/python or #!/usr/bin/ruby). However, Java is not (only) interpreted.
java only runs compiled Java bytecode, so it does not work on source files
Instead, head over to the terminal yourself, compile the code with javac and run the resulting bytecode (the .class files) with java:
javac the_file_name.java
java the_class_name
where the_file_name.java is the file containing main(...) and the_class_name is the name of the class containing main(...) (this should usually be the same as the_file_name)

How to load .java file to compiler?

Ok, I am beginner in JAVA. I have just started. I downloaded Java SE Development Kit 6u21 and wrote a program, saved it in .java and try to run it, but I can not do it. What's wrong? Thank you.
You will need to compile it first using javac:
javac YourClass.java
And then run:
java YourClass
If you really want to do it manually, you have to use the javac compiler in command line like this :
javac package/of/your/project/YourClass.java
and then
java package.of.your.project.YourClass
Your class YourClass must have a public static void main(String... args) method.
If your class isn't in a package, then javac YourClass.java and java YourClass are sufficient.
You should really consider to use an IDE which will handle this for you.
Resources :
javac documentation
java documentation
On the same topic :
Compiling multiple packages using the command line in Java
Compiling/running a java program in a different directory.
I suggest you read and follow this tutorial by Oracle: "Hello World!" for Microsoft Windows. Once you have successfully done so, you should have JDK installed and know how to run your program.
If you are still getting "'javac' is not recognized as an internal or external command, operable program or batch file", try reading these: How do I set or change the PATH system variable? and PATH and CLASSPATH.

How do I compile and run a program in Java on my Mac?

How do I compile and run a program in Java on my mac?
I'm new.
Also I downloaded a program that was suggested to me on here called text wrangler if that has any bearing on the situation.
Compiling and running a Java application on Mac OSX, or any major operating system, is very easy. Apple includes a fully-functional Java runtime and development environment out-of-the-box with OSX, so all you have to do is write a Java program and use the built-in tools to compile and run it.
Writing Your First Program
The first step is writing a simple Java program. Open up a text editor (the built-in TextEdit app works fine), type in the following code, and save the file as "HelloWorld.java" in your home directory.
public class HelloWorld {
public static void main(String args[]) {
System.out.println("Hello World!");
}
}
For example, if your username is David, save it as "/Users/David/HelloWorld.java". This simple program declares a single class called HelloWorld, with a single method called main. The main method is special in Java, because it is the method the Java runtime will attempt to call when you tell it to execute your program. Think of it as a starting point for your program. The System.out.println() method will print a line of text to the screen, "Hello World!" in this example.
Using the Compiler
Now that you have written a simple Java program, you need to compile it. Run the Terminal app, which is located in "Applications/Utilities/Terminal.app". Type the following commands into the terminal:
cd ~
javac HelloWorld.java
You just compiled your first Java application, albeit a simple one, on OSX. The process of compiling will produce a single file, called "HelloWorld.class". This file contains Java byte codes, which are the instructions that the Java Virtual Machine understands.
Running Your Program
To run the program, type the following command in the terminal.
java HelloWorld
This command will start a Java Virtual Machine and attempt to load the class called HelloWorld. Once it loads that class, it will execute the main method I mentioned earlier. You should see "Hello World!" printed in the terminal window. That's all there is to it.
As a side note, TextWrangler is just a text editor for OSX and has no bearing on this situation. You can use it as your text editor in this example, but it is certainly not necessary.
I will give you steps to writing and compiling code.
Use this example:
public class Paycheck {
public static void main(String args[]) {
double amountInAccount;
amountInAccount = 128.57;
System.out.print("You earned $");
System.out.print(amountInAccount);
System.out.println(" at work today.");
}
}
Save the code as Paycheck.java
Go to terminal and type cd Desktop
Type javac Paycheck.java
Type java Paycheck
Enjoy your program!
Download and install Eclipse, and you're good to go.
http://www.eclipse.org/downloads/
Apple provides its own version of Java, so make sure it's up-to-date.
http://developer.apple.com/java/download/
Eclipse is an integrated development environment. It has many features, but the ones that are relevant for you at this stage is:
The source code editor
With syntax highlighting, colors and other visual cues
Easy cross-referencing to the documentation to facilitate learning
Compiler
Run the code with one click
Get notified of errors/mistakes as you go
As you gain more experience, you'll start to appreciate the rest of its rich set of features.
You need to make sure that a mac compatible version of java exists on your computer. Do java -version from terminal to check that. If not, download the apple jdk from the apple website. (Sun doesn't make one for apple themselves, IIRC.)
From there, follow the same command line instructions from compiling your program that you would use for java on any other platform.
Other solutions are good enough to answer your query. However, if you are looking for just one command to do that for you -
Create a file name "run", in directory where your Java files are. And save this in your file -
javac "$1.java"
if [ $? -eq 0 ]; then
echo "--------Run output-------"
java "$1"
fi
give this file run permission by running -
chmod 777
Now you can run any of your files by merely running -
./run <yourfilename> (don't add .java in filename)

Categories

Resources