85

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?

Aryan Beezadhur
  • 4,503
  • 4
  • 21
  • 42
katie1245
  • 1,127
  • 8
  • 10
  • 32
    Part of the problem here is your terminology. A Java program is a set of .java source files or their compiled result: a set of .class files. A Java *process* is indeed a JVM process. – user207421 Oct 28 '20 at 03:17
  • I'm not sure but I think that programs other than java.exe can load the JVM as a DLL and run Java programs that way? If that's the case, java.exe is not the only program that can execute Java classes. – Nayuki Oct 28 '20 at 14:02
  • 1
    @Nayuki Yes, that's true. Some Java programs do that. That way it looks more like a native program, for example when someone looks for the program in the task manager. And you can give the exe an icon. Or have the exe download and install the JVM if necessary. – user42723 Oct 28 '20 at 18:59
  • 10
    Code is data, data is code. – hobbs Oct 29 '20 at 03:33
  • 5
    @hobbs: Except that under modern OS, code has the Execute and Read-Only bits set in the page table. Data usually is writeable, but certainly not executable. – MSalters Oct 29 '20 at 11:02
  • 2
    Somewhat dependent on context. On the IBM iSeries Java programs were (optionally) compiled into "native code" and executed like any other program. In this scenario the JVM was just the "run-time library" for the program. And even absent this compilation the Java program was "recognized" by the OS and did not need to have Java.exe explicitly invoked. – Hot Licks Oct 29 '20 at 22:20
  • Instead of the MS Word analogy, I would think of it like a bash script being considered a "program" but is actually merely data being fed into bash. The script itself has the executable and read-only bits set, but the OS sees the process as bash. To muddle it more, think of a .NET program which is a PE exe in windows but is really just a set of instructions for the .NET framework. Or maybe an older VB program where everything is really being done in msvbvm60.dll. Your "pure" Windows exe app in C++ is its own process in Windows, but when run in Linux, it is just data fed into Wine. – bamm Oct 30 '20 at 17:47
  • 1
    @MSalters I'm not talking about R^X, I'm talking about a more philosophical point about general-purpose computers. If you have some data that controls the operation of the machine, *that data is a program*. Doesn't matter if it's a binary that runs on the CPU directly, a shell script, a Java class, or a Minecraft world — it's just layers of abstraction. And almost every program is operated on as data by other programs at some point... even if you write machine code by hand, many modern machines translate from their ISA into a different internal representation that actually gets run! – hobbs Oct 31 '20 at 07:07
  • [Referenced on meta](https://meta.stackexchange.com/questions/356775). – Peter Mortensen Nov 18 '20 at 19:23
  • Related: *[What is the difference between Java components (JRE, JDK, JVM, JIT, and javac)?](https://stackoverflow.com/questions/42851098)* – Peter Mortensen Dec 08 '20 at 17:01

10 Answers10

107

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
CryptoFool
  • 21,719
  • 5
  • 26
  • 44
  • 8
    Java has a compiler and produces bytecodes. I'm not sure this is helpful. The situation is not fundamentally different from a C program running in a virtual machine or in a container. Would you say that a VM is like Word and C programs running in the VM are like Word Documents? – JimmyJames Oct 28 '20 at 13:14
  • You hit the point, but I think you should replace JRE with JVM. – Tobias Oct 28 '20 at 14:26
  • 1
    Thanks @Tobias. I was running with the terminology from the question, but you're absolutely right. – CryptoFool Oct 28 '20 at 14:51
  • 25
    And definitely don't be surprised if the line between compiled and interpreted languages is fuzzier than you would like. The line used to be clear, but we've moved things closer and closer to the muddled middle as of late. – Cort Ammon Oct 28 '20 at 15:28
  • 4
    @CortAmmon - Yes, you're right. At a more detailed level, the application of the two words "compiled" and "interpreted" is indeed a fuzzy thing at times. In fact, Java is both, right? It's compiled to bytecode, but then that bytecode is interpreted by another program at runtime. I think it can be of value to use the terms at the most basic level...if the OS runs your program directly, it's "compiled". If it runs some other program that then reads your "program" as data, it's "interpreted". Granted, that's an oversimplification. – CryptoFool Oct 28 '20 at 16:14
  • @Steve It's even fuzzier than that in Java: source is compiled into bytecode with the Java compiler (e.g. `javac`), but that bytecode (in `.class` files) is generally compiled into native code with the Just-In-Time compiler when it's loaded and executed by the JVM. – Bruno Oct 28 '20 at 18:17
  • @Bruno And because bytecode is a machine language, it's difficult to distinguish from other types of VMs or emulators. And, you can compile Java to native binaries. Even Python which seems obviously interpreted compiles bytecode. It seems to me that 'interpreted' has become little more than a mental construct. – JimmyJames Oct 28 '20 at 18:31
  • @JimmyJames Not sure there's many processors running bytecode natively (there were projects many years ago, but not sure how far they've gone). Not sure about compiling Java to native binaries either. It can work for a very limited subset of appliations, but a lot of stuff relies on reflection or instrumentation/hotswapping: dynamic classloading is very much part of the core way Java applications are run. – Bruno Oct 28 '20 at 18:38
  • All comments above are valid points, I'd like to add that some JVMs just in time compile (the term translate could also be used here) some of the bytecode to native machine instructions, which greatly increases performance of "number crunching" code. – op414 Oct 28 '20 at 18:42
  • @Bruno I don't think I mentioned native bytecode processors. That was an interesting idea that when absolutely nowhere. I think Azul had one for a while. As for native compilation, see my answer. There's a link to GraalVM which is a pretty recent project but I do think it limits what you can do. It's definitely possible though. – JimmyJames Oct 28 '20 at 18:59
  • @Bruno Here are the [limitations](https://www.graalvm.org/reference-manual/native-image/Limitations/). You can do dynamic classloading but everything has to be available at compile time. I would argue that's the case for most Java applications. In 2 decades of Java development, I have never needed (or wanted) to load a new class at runtime that was unknown to me at compile time. – JimmyJames Oct 28 '20 at 19:05
  • @JimmyJames ah, that's what I understood with "machine language". AFAIK GraalVM Native Image only has partial reflection support, I'm also not sure how well it can cope with load-time-weaving AOP, even dynamic proxy classes would need to be generated in advance. By using this, you're cutting yourself out of some features of Java (but then again, it's been more module for a few years anyway). – Bruno Oct 28 '20 at 19:06
  • @JimmyJames In 2 decades of Java development, I have :-) I've used AspectJ quite a bit in the past, and nowadays frameworks like Spring and MyBatis, which do rely quite a lot of reflection (and MyBatis+Spring integration relies on proxies). It's also handy to load plugins dynamically (which I do). Not to mention the whole webapp dynamic classloading... I guess it all depends on the application... – Bruno Oct 28 '20 at 19:10
  • 2
    @Bruno As I read the link above, that's all fine. You just need to have them available at compile time. How often do you load a completely new class into an existing application without rebuilding it? Maybe you have a special scenario but it seems like an unnecessary complication to me. There could be a good use case but I doubt it's common. – JimmyJames Oct 28 '20 at 19:14
  • 1
    @JimmyJames Spring does do that -- via CGLIB. It will actually, at runtime, create new classes from whole cloth and load them. I have no idea to what extent GraalVM can handle that. – Chris Bouchard Oct 28 '20 at 21:17
  • 5
    You can go even a little farther with this. Most CPU instructions now are implemented as microcode, so even if you write in assembly, you're really just writing bytecode that will be interpreted by an interpreter (that happens to be stored inside the CPU!) And CPUs can even update the microcode interpreter, as was recently done to mitigate Spectre/Meltdown bugs. – fluffysheap Oct 28 '20 at 21:52
  • This is correct, but I felt a lack of digging into implementation details so I posted some of them as [a separate answer](https://stackoverflow.com/a/64582679/8990329) – Some Name Oct 28 '20 at 23:41
  • 1
    Note that what you describe in your answer is only one possible way of implementing Java. It is a popular way, sure, but not the only way. Nothing in the Java Language Specification requires using JVM byte code. It is perfectly legal to compile Java to native machine code, .NET MSIL byte code, WebAssembly, ECMAScript, C, etc. You can even compile Java to PHP if you want. Or you can not compile it all, and directly interpret it. All of that would be legal as per the JLS, and some of that has been done. (Native compilation, compiling to JavaScript, and interpretation.) – Jörg W Mittag Oct 29 '20 at 06:20
  • @JörgWMittag - Of course. I'm speaking to the garden variety, what most of us know and love/hate, JVM environment. I think it's pretty safe to assume that's the make and model of Java the OP was asking about. - And I also know full well that Java doesn't say it all either in terms of dialect. In fact, I've tried to stick with Kotlin long enough to feel I'm working in the 21st century, but the practicalities of work keep pulling me back to plain ol' Java...and one of my best friends is a Scala fanatic. – CryptoFool Oct 29 '20 at 07:35
  • @ChrisBouchard I believe it will handle it fine when running as a VM. My reading implies you would not be able to do that in a natively compiled application. The bytecodes for any class that would need to be available at compile time. – JimmyJames Oct 29 '20 at 12:56
  • Re: "Programmers wont like this..." Not sure why you say that, I thought it was a pretty good analogy :) – Charlie Armstrong Oct 29 '20 at 16:22
  • @JimmyJames: I *would* in fact absolutely say that a VM is like Word and programs running in it are like Word documents. Consider an interpreter as in inbetween case. There is no fundamental difference between data and code, and for security reasons alone we'd all be well advised to keep that in mind. – Michael Borgwardt Oct 30 '20 at 08:23
  • 1
    @MichaelBorgwardt Sure but, if we disregard macros, Word documents are not Turing-complete. If we really take this analogy seriously, we have to say Windows is like Word and and Word is like a Word document. It's just not really useful IMO. I think your point is similar to mine: the difference between programs running on the OS, JVMs, CLRs, VMs, emulators, containers, are more similar than different. Implying Java applications running on a JVM are some how less real than a natively compiled program is fundamentally wrong. – JimmyJames Oct 30 '20 at 14:57
  • 1
    @JimmyJames: Agreed – Michael Borgwardt Nov 01 '20 at 12:06
  • Compilation is a property of a runtime and not a language. You can observe this by the fact early versions of Java were fully interpreted, then they added HotSpot an JIT compiler and certain Java environments like in Android are fully compiled AoT (with compilers like ART) – Benjamin Gruenbaum Nov 03 '20 at 18:46
  • 1
    Of course. I may have used the term "Java" somewhat loosely. You can see though, that the target of both the question and my answer are clearly discussing the language in the context of the JVM/JRE. So the runtime is what we're talking about here really. If I implied that Java itself had certain properties, then I might have been talking about only the 99% case (leaving Android out of the picture maybe) where Java is run on the JVM. One really good thing is that with Android, you're often not talking about Java but rather Kotlin, which is a much better language. – CryptoFool Nov 03 '20 at 19:02
42

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
19

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
JimmyJames
  • 1,356
  • 1
  • 12
  • 24
12

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.

Michael Welch
  • 1,754
  • 2
  • 19
  • 32
10

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Asteroids With Wings
  • 17,071
  • 2
  • 21
  • 35
10

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 ;)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Some Name
  • 8,555
  • 5
  • 27
  • 77
6

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

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Chass Long
  • 539
  • 4
  • 16
  • isnt JRE java runtime environment? – CodingNinja Oct 28 '20 at 02:50
  • 1
    Offt, thank you for the correction I really didn't notice – Chass Long Oct 28 '20 at 02:52
  • 5
    "when a java compiles it results in a .jre". That's not really correct. Java compiles a `.java` file to produce a `.class` file. Class files, along with other resource files, are often collected into `.jar` files, and either of these can be read by the JRE. The JRE interprets the contents of `.class` files. – CryptoFool Oct 28 '20 at 03:01
6

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jay
  • 26,876
  • 10
  • 61
  • 112
  • Nice answer. I would add that even the machine-code instructions do not exactly define how it is to be run; CPU microcode & branch predictions can be seen as further interpretation steps. – tucuxi Oct 29 '20 at 14:31
  • @tucuxi True enough. Another level of complexity. – Jay Oct 29 '20 at 17:09
  • @tucuxi While that is technically true, such things are largely hidden from the programmer. What we think of as machine code (and the next step up: assembly) are effectively the fundamental building blocks the CPU provides. If I ask the CPU to multiply the value of the "accumulator" by another value and store, it what matters is that a multiply operation occurred not exactly how it was done. --- CPU microcode, if I understand correctly, simply builds up those fundamental blocks from smaller sub instructions that the cpu can do independently. That is not unlike "acceleration" in a car. – Jeremy Harton Nov 06 '20 at 06:09
  • @JeremyHarton until, sometimes, the way the CPU works internally suddenly matters a lot for performance reasons. There are many [questions](https://stackoverflow.com/questions/9314534) & [answers](https://stackoverflow.com/a/19471823/15472) on this site with great examples – tucuxi Nov 06 '20 at 08:28
  • @JeremyHarton Sure. As a programmer, I can to a large extent ignore questions of whether my code is interpreted or compiled. With modern Java, sometimes the code is compiled and sometimes it's interpreted. In the Good Old Days there were BASIC interpreters and BASIC compilers that operated on the same source code. I say "to a large extent" because there are performance implications that the serious programmer should consider, but at the level of "does it work", it shouldn't matter. – Jay Nov 06 '20 at 15:59
5

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Gnudiff
  • 4,297
  • 1
  • 24
  • 25
4

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".

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
meriton
  • 68,356
  • 14
  • 108
  • 175