Are Java programs just instances of the JRE?

Java

Java Problem Overview


When you run a .exe console application in Windows (such as one written in C++), Windows creates a console window for you.

So in essence, the program doesn't run on top of anything other than Windows itself.

When you invoke java Main.class inside the cmd.exe console, is it really its own standalone program? It feels more like java is the program running and Main.class is just an argument given.

All of this is to ask, are all Java programs simply console java [argument] programs? Another way to ask, are all Java programs just JRE programs/instances that are reading a particular class file?

Java Solutions


Solution 1 - Java

To put a simpler spin on this, the answer is: Yes (although you really mean the JVM rather than the JRE). The program that the OS is running is the JVM (Java virtual machine), and the Java application is data being read by that program. The JVM is like Microsoft Word, and Java programs are like Word documents.

This question is hitting upon the essential difference between compiled and interpreted languages, as described well here.

To use the analogy further to explain what the JVM and JRE are...The JVM is like the Microsoft Word program itself, and the JRE is like the MS Word program plus all the other stuff, like templates, sample documents, fonts, etc. that is installed along with it to support what it does.

Solution 2 - Java

> All of this is to ask, are all Java programs simply console java [argument] programs?

Not that specifically, no, because not all Java programs are run via the java tool, but keep reading.

> Another way to ask, are all Java programs just JRE programs/instances that are reading a particular class file?

Java programs are usually run by a Java virtual machine (JVM), such as the one in the Java Runtime Environment, yes. That is, in most situations, the Java program (the collection of class bytecode and other resources that makes up the program, sometimes in a .jar/.war/.ear/etc. file) is loaded and run by an instance of the JVM, which is launched by the java tool or a servlet container (or, back in the day, an applet container) or some other environment that knows how to spawn a JVM instance.

Usually, it goes like this:

  1. .java files are compiled to Java bytecode, typically output as .class files. Java bytecode is a high-level machine language that isn't dependent on a specific CPU architecture or operating system.

  2. Sometimes, .class files (and other resources) are bundled together into containers (.jar files, .war files, .ear files, etc.).

  3. When it's time to run the program, you use the java tool or a servlet container or some other kind of process that knows how to run Java bytecode. These are CPU- and OS-specific and incorporate or load a JVM.

  4. Code in the tool (java or servlet container or other) loads the bytecode (from the .class file or similar) and passes it to the JVM to be instantiated and executed. Depending on the JVM, that might involve just interpreting the bytecode, or compiling it to CPU- and OS-specific machine code ("just-in-time" [JIT] compilation) and executing that, or a combination of the two. Sun's HotSpot JVM, for instance, does at least two levels of JIT compilation depending on whether a specific segment of code is used enough to bother to compile it and, if so, enough to justify aggressively optimizing it.

There are compilers that compile Java source code or Java bytecode to machine code for specific CPU architectures and OSes, outputting an all-in-one executable, but the above is the usual scenario.

Solution 3 - Java

I think it helps here to step back and look at the bigger picture here. When you run a Java program the way you describe, it's running in a virtual machine. A specific one that happens to have the name 'java'.

There are other VMs that run Java, however. One of the newer VMs is GraalVM. I'm not sure it's completely correct to call it a JVM because it can (supposedly) also run other languages such as Python, Ruby, C, and C++. So if you run a C++ program in GraalVM, is that C++ program now 'just' a GraalVM application? I don't think so. To further muddy the waters, GraalVM can compile Java programs to native binaries.

As kind of an aside, there's nothing special about Java with regard to having a runtime environment. C# (.NET) has the CLR which was definitely and absolutely in no way based on the ideas of the JVM, of course. CPython has a runtime called 'python'.

If I am running Windows in a virtual machine running on Linux, and I am running program written in C++ in it, is Windows now just a program running on Linux? If we say yes, what does that make the C++ application? Is it a standalone program? What about a C++ application running in a container on a virtual machine running running on a server in the cloud. Is that program any less 'real' running in that configuration than it is when running on your desktop?

TLDR: Virtualization is ubiquitous in computing. There are definitely aspects of the standard JVM that are distinct from other virtualization technologies, but these are fairly minor distinctions in the grand scheme of things.

Solution 4 - Java

Java programs are compiled to an intermediate language called Java bytecode. These can sort of be said to be interpreted by the Java runtime (the Java virtual machine actually), but I believe it's a little more complicated than that.

I'm sure some code is just-in-time (JIT) compiled at runtime, which means the JRE actually compiles some of the bytecode to actual machine code. The particulars of when it does this and for what reasons are beyond my knowledge, but it's often done for performance reasons. I see another answer provides a link to JIT information for you.

As you'll noticed at that Wikipedia link, some compilers like the GNU Java compiler can compile directly to machine code.

You'll also notice that it says some special processors can run bytecode natively, in which case no JVM is necessary.

Oh, one other note: When the program runs (within a JVM) it is indeed an "instance of the JVM". If you check your list of processes you'll see that your program is an instance of the application java. So if you look in Task Manager on Windows or Activity Monitor on Mac or list of process IDs on Linux you'll see a java process running for each one of the Java programs you started.

Solution 5 - Java

> When you invoke java Main.class inside the cmd.exe console, is it really its own standalone program?

No.

> It feels more like java is the program running and Main.class is just an argument given.

It is.

This is no different from any other command-line invocation: program name first, arguments subsequent.

Java is not generally fully "compiled" ahead of time; it's sort of half compiled, and the result is executed by the Java Virtual Machine when you want to run your program. The JVM is invoked using the executable called java.

The file Main.class is not, in itself, an executable that your operating system can run.

Solution 6 - Java

Disclaimer: I don't have a Windows machine, so here is the state of affairs on Linux.

Everything is extremely simple. Here is the way to understand what's going on:

I.

$ which java
/usr/bin/java -> /etc/alternatives/java*

(This is for a Debian flavor of Linux, like Ubuntu. Others are similar.)

II.

    $gdb /etc/alternatives/java
    (gdb) list main
    93          __initenv = _environ;
    94
    95      #else /* JAVAW */
    96      JNIEXPORT int
    97      main(int argc, char **argv)
    98      {
    99          int margc;
    100         char** margv;
    101         int jargc;
    102         char** jargv;

Here you see a simple C main function accepting command line parameters as you passed them (the arguments are a subject to a complicated transformation though). The function is the first one that gets called every time you invoke your Java program.

It serves as a proxy that loads libjvm.so containing the HotSpot code and calls the specific CreateJavaVM function to pass the control into the HotSpot VM code which first initializes all the VM subsystems (JIT compiler, GC, generate interpreter templates, install signal handlers, etc...) and then calls public static void main Java function of yours.

In short, you invoke a regular natively-compiled binary that knows how to execute Java programs you specified as arguments ;)

Solution 7 - Java

Yes, to an extent the every single Java program has to be compiled by the JDK (Java Development Kit) and run by the JRE (Java Runtime Environment) which is a Java development tool.

When a Java compiles, it results in a .jre or .class which can't be run directly straight to a computer processor in any way (there are ways to change .jar to .exe), but it will have to run through the JVM (Java virtual machine) through the JIT (just-in-time) compiler.

With this chart here, then to an extent, yes, Java programs classes "belongs" to the JRE. But it is definitely more complicated than that.

I suggest you read more about the JIT here.

Enter image description here

Solution 8 - Java

Sure. This is the beauty of modern computers: code is data.

In the early days of computers back in the 1940s, "programming" a computer meant hooking up wires, reconfiguring physical hardware. A ground-breaking advance was the von Neuman machine, where a program is stored as data, and the computer then reads that data and takes different action based on the content of that data.

Today all programs are manipulated as data. When you write a program in, say, C#, that's just a bunch of text strings. Then you run a "compiler" to read those text strings and spit out machine language, probably in a language that can be understood by the processor where you ran the compiler. But not necessarily: there are "cross compilers", where you compile a program on machine X to run on machine Y. (This is especially useful when a new computer is invented. Otherwise, what language would we use to write a compiler for new computer Y, when there are not yet any compilers that run on Y?)

You surely regularly copy program files from one computer to another or from one folder to another on the same computer. You get directory listings that include program files. Etc. You treat them as data.

So today there are basically three types of languages: compiled languages, interpreted languages, and virtual machine languages.

With a compiled language, the program you type in is translated to machine code that can be run directly.

With an interpreted language, like some BASICs, an interpreter reads your source code and figures out what to do with it on the fly.

With a virtual machine language, like Java, your program is translated into "byte code". This byte code is then read and processed by the "virtual machine". Basically, byte code is like machine language for an imaginary computer: there isn't (necessarily) a computer that can execute the byte code directly, but we write an interpreter that processes it and gives the same results as if there was such a "real" machine language.

One advantage of byte code, and one of the primary selling points of Java when it was first introduced, is that once you implement a virtual machine on a computer, it can then run any program written in that language. You don't even need to recompile. You just run it. So if tomorrow someone invents a Fwacbar 2020 computer with some totally new instruction set that is nothing like Pentium or any existing CPU, and they write a Java Virtual Machine for that computer, they can run any Java program on it.

The people who wrote the Java program don't need to recompile for the new computer. They don't have to make their source code available to anyone. They don't even have to know that the new computer exists. Their Java program will just work on the new computer. (Assuming the JVM doesn't have bugs, of course, but you could say that of anything.)

The Java people marketed with the slogan "write once, run anywhere". I once wrote a Java program on Windows and also tested it on Linux. But someone with a Mac bought a copy and he was able to run it on his Mac with just a little help from me on getting it installed properly.

Solution 9 - Java

In addition to other answers, it would perhaps be useful to formulate it this way:

There are very few programs (on PC) that run pure machine instructions only, and only depend on hardware. Mostly they are bootloaders, which (eventually) start some kind of operating system.

The operating system generally allows you compile your programs to machine instructions and use them, but it requires your program's machine code to comply with particular template (EXE, ELF, etc. binary file format), which the particular operating system recognizes, and in return for staying with that template, the operating system actually "knows" how to run it, and provides a lot of its resources and libraries that your programs can call and use (networking, filesystem access, etc.).

Without an operating system, no userland program would launch. That is the reason machine instruction compiled programs are generally usable only on their target operating system.

Bytecode compiling systems lets you go halfway. Part of the work of translating your program to machine code is done during compilation. But the result is not in a format that is supported by the usual operating systems (Windows, Linux, etc.). It is a bytecode, that requires additional environment on top of operating system, to actually run your code. Java is one of those languages.

The bonus of bytecode is that it generally can be used without change on any machine that has the appropriate bytecode environment. Sort of "compile once, run everywhere" system, but there are also caveats.

And finally we have your interpreted languages, which require you to launch the whole language interpreter every time you launch the program, and for the interpreter to do all the work every time. The source code of your program is usually available for inspection and change at any moment, and changes can be done without (sometimes slow) recompilation process. Also, interpreted language programs frequently don't have to be modified when used on different architecture machines.

As you might imagine, the more environment is needed for launching the program every time, the slower the program's response might be. However, for modern computers and modern interpreters, the difference in many cases is not that dramatic as it used to be. Still, for many resource intensive programs, compilation to executable machine code (OS level) is still preferred or sometimes the only way for program to be able to work acceptably.

Also, as some answers and comments have noted, the lines have blurred between these three modes, some interpreters do bytecode, some machines have been developed which can understand bytecode directly. Nevertheless, it is still useful to know what do you generally need to have to run what kind of code.

Solution 10 - Java

This is a matter of perspective:

  • From the perspective of the shell, java.exe is the program, and Main.class an argument.

  • From the perspective of the operating system, the process starts by running java.exe, reads the main class, generates new native code, adds it to itself, and spends most of its time executing that generated code (so from that perspective, the Java program is not "on top" but rather "side by side" with the JVM).

  • From the perspective of the Java programmer, Main.class is the program, and the JRE is a runtime environment needed to execute that code on a particular platform.

It is worth noting that there is significant flexibility in how that JRE is loaded:

  • You can run java.exe to load the JVM into a new process.
  • Any process can load jvm.dll to embed a JVM (and Java programs) into its own process. For instance, LibreOffice Base loads jvm.dll (or jvm.so, depending on platform) to host the java program HSQLDB. From the perspective of the operating system, that process will contain code from LibreOffice Base, the JVM, and the runtime-generated code for HSQLDB.

In summary, whether a Java program is "just java.exe" depends on your perspective, and how the Java program is launched. Since the same program can be launched in many different ways, and be considered from a variety of perspectives, a "Java program" is not, in general, a synonym for "shell command", "native executable" or "process".

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionkatie1245View Question on Stackoverflow
Solution 1 - JavaCryptoFoolView Answer on Stackoverflow
Solution 2 - JavaT.J. CrowderView Answer on Stackoverflow
Solution 3 - JavaJimmyJamesView Answer on Stackoverflow
Solution 4 - JavaMichael WelchView Answer on Stackoverflow
Solution 5 - JavaAsteroids With WingsView Answer on Stackoverflow
Solution 6 - JavaSome NameView Answer on Stackoverflow
Solution 7 - JavaChass LongView Answer on Stackoverflow
Solution 8 - JavaJayView Answer on Stackoverflow
Solution 9 - JavaGnudiffView Answer on Stackoverflow
Solution 10 - JavameritonView Answer on Stackoverflow