I've recently been experimenting with Processing (https://processing.org/).
It's a sort of IDE used to make GUI design in Java easier. Since I'm not a fan of swing or AWT, I found it quite fun to use.
Something interesting to note though. When I "export" the Application for windows, it creates both a 32-bit and 64-bit version.
I'm a little confused as I thought after Java source code is compiled to Java bytecode, it can be run anywhere as long as that place as a JVM. (Write once, run anywhere).
So why are both a 32 bit and 64 bit version of the app created? Shouldn't the bytecode be platform independent and only be translated using Just-In-Time compilation to whichever architecture the JVM is on, during runtime? At least, I know that's how .NET does it with the CLR.
I'm going to attempt to answer my own question by saying since the applications created are .exe files, the translation to native architecture happened ALREADY, since windows was specified as a target-platform...I guess to increase efficiency?
Otherwise, I'm confused. The only time I've seen a compilation happen twice is when I was programming C++, and needed to compile twice for 32-bit and 64-bit.
Thank you!
Processing is built on top of JOGL which is (basically) a Java wrapper of OpenGL, which is a device-specific graphics library.
Also, Processing (can) include a whole JVM with its exported applications, so end users don't have to worry about downloading Java. The JVM itself is OS-dependent, so the exported application is as well.
You can confirm this by taking a look at the files that Processing creates. Specifically, notice these files:
jogl-rt-natives-windows-amd64.jar
jogl-all-natives-windows-amd64.jar
These .jar files contain the native files required by JOGL.
Related
When I used C++ programs, I needed Turbo C complier; and when I have a Java program, I need to have JVM. Still C++ isn't platform independent, but Java is!
If any Java program require a JVM running in order to execute, why does Java is said to be Platform Independent?
Java is operating-system independent because it runs on the Java platform (the JVM): The mantra is "write once, run anywhere" because you write your code using the JDK API, compile that once, and it runs on any operating system that has a JVM available. You write your code, wrap it up in a jar, and that jar runs wherever you want to use it, within reasonable bounds. The job of the JDK and JVM are to abstract away the differences in environments.
In contrast, particularly back when Java was created, writing C or C++ for multiple operating systems was a big pain and usually required additional toolkits (of course, the JDK and JVM are a toolkit of sorts), and even today still requires at least recompiling for the target system.
There's nothing magic about Java's OS-independence. It would be entirely possible to build the same thing for C or C++: Compile to an intermediary form, provide a runtime that knows how to interpret or recompile that intermediary form for different environments and provide a library that abstracts away environmental differences. Java just...did that, with its own spin on the language. Later, so did the .Net platform.
No software is really "independent". Eventually, your program has to call the underlying OS in order to make some basic operations, like allocating memory, create new threads etc.
The way to achieve an executable which is "cross platform" is to create specific executable for each OS. Common practice is to write different code for each OS, and then "hide" it in a cross platform interface and compile the relevant code to the relevant OS. For example, std::thread is "cross-platform" to the user who uses this class, but behind the scenes it will call different functions based on the OS which was specified on compile time (such as CreateThread on Windows, but pthread_create on *nix OS's).
So basically, the JVM is a C/C++ executable that was written with different set of functions for each OS, and was compiled separately for each OS. A JVM executable which works on Linux, will not work on Windows, and vice-versa.
That JVM compiles .class files to machine code based on the OS and CPU it currently operating on, so that's why Java programs can "run anywhere".
But basically, it's a lie. It's like saying a human being can live on Mars....
if he lives inside a sealed spaceship with proper temperature, water, food, air and sunlight supply
So Java program can run anywhere.... if the JVM already is installed and running on the computer.
Firstly, I'd like to link to this question which has a lot of good information.
https://softwareengineering.stackexchange.com/questions/85175/what-is-the-exact-meaning-of-platform-independence
In the question above are comments about what it means to be "Platform independent," but the one thing I wanted to mention, but is summed up nicely here is
You're right, platform independence means that the same program works on any platform (operating system) without needing any modification.
The code we write is known as "Write once, run anywhere" or as someone else said "run once, test everywhere."
Our Java code SHOULD run everywhere, but sometimes there are little native bugs that cause issues i.e., someone was having issues with printing on Mac OSX with JavaFX-8 Printing, while it works fine on Windows. There was also a bug report on this to fix this "Mac specific Java issue."
So.... For the most part, the underlying JavaSE code SHOULD work across all platforms.....
** however, if you do have an Application running on multiple computers and work with the File System, you will have to do checks to understand which OS you are working with i.e., (System.getProperty("os.name").contains("Windows")); **
more info on that here https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html
There is also another thing to note.
Certain components do not work cross platform, i.e., JavaSE vs JavaEE. JSP/JSF is what is used in JavaEE, on the web, that is specific for running code on a server, and in a webpage, but cannot be used in the Desktop (to my knowledge).
However, JavaSE has GUIs such as Swing, and JavaFX, which also cannot work on the web, either in the Client, or in the Server.
Android has it's own set of commands and things it can/cannot do, and other "Platforms" have specifics to it as well.
Overall, the underlying Java Architecture is what is used across all platforms, where certain "Java Specifics" are used in certain platforms i.e., JSP.
So what does Java do differently?
In the case of Java the application runs in a Java Virtual Machine which itself isn't platform independent. This has to be the interface between the actual machine (operating system) and the Java code you've written.
I am not really knowledgeable that much of the JVM, but it seems that each JVM is specifically tailored to each "Platform" (Which is why there are soo many versions to install), and does a lot of heavy lifting in the background, whereas C you might have to do this all yourself (not really sure how it works), for each OS.
Want a JVM for Windows? Np... Linux? Np.... That new car you just bought with all that fancy tech in it? JVM for that.... Or how about that new parking meter where you just parked your car? Yeah, there's one for that too...
For example, here is an Answer from this site on how Java is converted to Dalvik for Android.
https://stackoverflow.com/a/24570735/3599960
Hope this helps and makes sense.
C or C++ program gets compiled into native-code which is close to the metal where metal is the OS (earlier it could be hardware also in DOS era). There is no further re-compilation necessary to run the executable on target platform. But, a developer must build executables for all platforms he/she indents the program should run on.
It doesn't just mean different OSes, but bit-ness of particular OS. For example a 64-bit binary (EXE) cannot run on a 32-bit OS (vice-versa is possible, mostly, however). Here Java/.NET and other platform virtualization engine are boon for the developers - they just build once (for example "AnyCPU" for C# module), and don't need to give multiple binaries (EXE files). The runtime installed on given OS would re-compiler (JIT - Just In Time compilation).
I'm not sure about Java, but a.NET program can be compiled into specific platform. It is also possible by the .NET engine to JIT compile the intermediate (or byte-code in Java) into native format just once (and keep the EXE for direct run). The advantage is that .NET JIT compiler can take advantage of current hardware and latest CPU instructions, which C++ program cannot (it won't have JIT/re-compilation).
I'm confused about the advantage of an interpreted language like java, over a compiled language.
The standard explanation for the advantage of an interpreted language, such as java, over a compiled language is that the same .class file can run on different types of machine architectures. How doe this save you any work?
For each different machine architecture, wouldn't you need a different compiler to interpret the same .class file into the machine language? So if you need a different compiler for each different machine architecture to interpret the same .class file into machine code, how does this save you any work?
Why not just makes a compiled language where the .java source file is compiled into machine language right away. Sure this would require a different compiler to compile from the java source file to machine language for each machine architecture, but how is this any more work than having to have a different compiler for each machine compile from a .class file to machine language?
I mean this is the same as with a compiled language -- you need a compiler for each machine architecture whether it's compiling a java source file into machine code or a class file into machine code.
thanks.
First, the claim that "Java is interpreted", while it has some basis in truth, is pretty misleading, and it's probably best if you simply delete that notion from your head.
Java is compiled from source code to an intermediate representation (classfiles, bytecode) at build time. When a class is first loaded, most JVM implementations (including Oracle HotSpot, and IBM J9) will go through a short-lived interpretation phase, but if the class is going to be used with any frequency, a dynamic compiler (JIT) will run and compile to native code. (Some JVMs, like JRockit, go directly to native with no interpreter.)
I think "Why isn't Java compiled directly to native code" is the real question here. The obvious answer, as others have suggested, is portability. But its more subtle than that: dynamic compilation yields higher quality code than static compilation. When the code is compiled dynamically, the JIT knows things that no static compiler could know: characteristics of the current hardware (CPU version, stepping level, cache line size, etc), as well as properties of the current run (thanks to profiling data gathered during interpretation.) The quality of your decisions is dependent on the quality of your information; a dynamic compiler has more and better information available to it than a static compiler ever could, and so can produce better code.
Further, dynamic compilers have the possibility to perform optimizations that no static compiler could dream of. For example, dynamic compilers can do speculative optimizations, and back them out if they turn out to be ineffective or if their assumptions later become incorrect. (See "Dynamic Deoptimization" here: http://www.ibm.com/developerworks/library/j-jtp12214/).
For each different machine architecture, wouldn't you need a different
compiler to interpret the same .class file into the machine language?
So if you need a different compiler for each different machine
architecture to interpret the same .class file into machine code, how
does this save you any work?
The above statement is your core misunderstanding.
Application developers write Java code that is compiled to byte code that can run on any compliant Java Virtual Machine.
The Java Virtual Machine interprets (and possibly compiles) this bytecode and executes the application. These JVMs are developed for the major architectures and operating systems, such as Windows/Mac/Linux on Intel. The JVM developers are a relatively small group of engineers, such as those from Oracle and Sun.
From the application developers' point of view, he or she only has to compile once because the byte code (in the .class file) can be executed on compliant JVMs. Application developers do not need to worry about the underlying architecture or OS; they only need to target the architecture of the JVM. The JVM developers are the ones who deal with the underlying layer.
I like answer of sowrd299. My two cents:
you have technically endless different target architectures
and therefore compiling your code for all targets at the same time and packing it together would result an infinite big executable
therefore compiling Java against a virtual machine byte code is a better solution: since it has the footprint of only one target architecture
while developers can separately add JVMs for all new and old architectures, allowing total new stuffs (such as a Raspberry PI) run your java code compiled in the previous century.
On the other hand, the "compile for multiple targets in advance" is not a totally insane thing. Afaik Windows Universal Apps works this way: it is the same application in the same exe file, but actually the exe contains the code compiled for a 80x86 as well as for an ARM target. This way one application looks to be portable amongst windows mobile and desktop solutions without any further interpreting.
First, Java is a compiled language as well an interpreted language, because you have to compile from .java to .class.
To get the meat of your question, the advantage Java gains by being (somewhat) interpreted is you only need to compile each program once, and it can run on any computer, because the Java Runtime Environment (JRE), which is compiled in advance to match the local OS and architecture, can bridge that gap without (or with minimal) further compiling.
In an uninterpreted language, however, you must compile each program for each OS and each Architecture you want it to run on, which entails much more effort and total compile time than just compiling the JRE once for each OS and architecture and only compiling each individual program once.
It would be impractical to have a language that compiles for the local architecture each and every time it runs, because compiling is a rather intensive process. Python does compile each time it runs (though, like Java, it compiles for a Runtime Environment, not the local architecture) and it is one of the slowest languages out there.
Hopefully that helped clear things up.
Java is platform independent , because it use a platform dependent JVM to launch a Java program. JVM understands bytes codes and executes program. I know old way of doing this was interpreter. But now JVM's is using JIT. But I didn't understand JIT concept clearly. I think, a jVM can translate byte codes to an exe (for Windows) and after this I can run this translated program without JVM. But I can see generated exe in .net JIT but I cannot see generated exe in Java.
How can I do this (create a native exe file from Java)?
What will be performance of JVM produced exe vs the same C application?
How Java will handle static linking and dynamic linking?
Some thoughts:
You can't generate an exe using just core Java, and the JVM certainly doesn't do this. It still runs the byte code in the JVM. The actual exe that runs here is java.exe.
It's hard to say if an exe would be significantly faster since the JIT generates pretty darn fast code.
Java doesn't create dll's if that's what you mean, but it can interact with well-formed dll's (not .Net dll's) via JNI and JNA. If you wanted to interact with .Net libraries, I think you would need to go another route such as sockets or COM interface.
Also as an aside, there do exists programs that create exe's from java classes, but most create files that still require a JVM, and the good ones that don't I believe are not free.
Does not make much sense to do so.
Sometimes faster, sometimes slower.
No idea.
I think, a jVM can translate byte codes to an exe (for Windows) and after this I can run this translated program without JVM.
This is not correct.
In reality the Hotspot JIT compilers work by compiling individual methods to native code within the running JRE. They typically only bother to compile methods after they have been called a few times to gather stats on typical execution paths. No "exe" is ever produced by the Hotspot JIT compilers.
1) How can I do this (create a native exe file from Java)?
There are third party applications that will do this. However, by doing this you lose a lot of the advantages of JIT compilation, such as optimizing for the execution patterns of the current program run.
2) What will be performance of JVM produced exe vs the same C application?
That depends on the application.
3) How Java will handle static linking and dynamic linking?
Java doesn't handle this. It depends on the 3rd party application that you use to create the executable.
I would recommend not going down this path. If it is critical that you distribute your code as ".exe" files, you probably shouldn't be using Java.
How can I do this (create a native exe file from Java)?
There is a common mis conception that this will be better in some way. However, I haven't seen a good situation where it is. There are products like Excelsior JET which can compile a binary. GCC can compile a binary for Java 1.4 but this is not a current project AFAIK.
What will be performance of JVM produced exe vs the same C application?
You can't compare the two. If you want an Object Orientated Program, you can't easily write this in C and it will almost certainly be much slower to write if not run. If you want to write a C style program, write it in C.
How Java will handle static linking and dynamic linking?
The JVM does dynamic late linking. If fact it can link and re-link code multiple times as you load and unload class loaders.
I'm reading Herbert Schildt's book "Java: The Complete Reference" and there he writes that Java is portable AND architecture-neutral. What is the difference between this two concepts? I couldn't understand it from the text.
Take a look at this white paper on Java.
Basically they're saying that in addition to running on multiple environments (because of being interpreted within the JVM), it also runs the same regardless of environment. The former is what makes it portable, the latter is what makes it architecture-neutral. For example, the size of an int does not vary based on platform; it's established by the JVM.
A portable C program:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
printf("Hello, World!");
return (EXIT_SUCCESS);
}
You can take that C program and compile it on any machine with a C compiler and have it work (assuming it supports printf... I am guessing some things out there may not).
If you compile it on Windows and try to run that binary on a Mac it won't work.
The same sort of program written in Java will also compile on any machine with a Java compiler installed, but the resulting .class file will also run on any machine with a Java VM. That is the architectural neutral part.
So, portable is a source code idea, while architectural neutral is an executable idea.
Looking around I found another book that describes the difference between the two.
For architecture neutral the compiler will generate an architecture-neutral object file meaning that compiled Java code (bytecode) can run on many processors given the presence of a Java runtime.
For portable it means there are are no implementation-dependent aspects of the specification. For instance in C++ an int can be 16-bit, or 32 bit depending on who is implementing the specification where as in Java an int is always 32 bit.
I got my information from a different book (Core Java 2: Fundamentals) so it may differ from his meaning. Here is a link: Core Java 2: Fundamentals
With architecture-neutral, the book means that the byte code is independent of the underlying platform that the program is running on. For example, it doesn't matter if your operating system is 32-bit or 64-bit, the Java byte code is exactly the same. You don't have to recompile your Java source code for 32-bit or 64-bit. (So, "architecture" refers to the CPU architecture).
"Portable" means that a program written to run on one operating system works on another operating system without changing anything. With Java, you don't even have to recompile the source code; a *.class file compiled on Windows, for example, works on Linux, Mac OS X or any other OS for which you have a Java virtual machine available.
Note that you have to take care with some things to make your Java code truly portable. If you for example hard-code Windows-style file paths (C:\Users\Myself...) in your Java application, it is not going to work on other operating systems.
I suspect that he means that code can run on many platforms without recompilation.
It is also possible to write code that deals with the underlying system without rewrites or conditions.
E.g. Serialized objects from a 32 bit Windows system can be read on a 64bit Linux system.
there are 3 related features in java.
platform independent -> this means that the java program can be run on any OS without considering its vendor. It is implemented by using the MAGIC CODE called "BYTE CODE". The JVM then either interprets this at runtime or uses JIT (Just in Time) compilation to compile it to machine code for the architecture that is being run on (e.g. i386).
architecture neutral -> it means the java program can be run on any processor irrespective of its vendor and architecture. so it avoids rebuilding problem.
portable -> a programming language/technology is said to be purely portable if it satisfies the above two features.
.class file is portable because it can run on any OS . The reason is , .class file generated by JVM is same for all OS. On the other hand JVM is differ as OS , but it generate same .class file for all OS, so JVM is architectural neutral.
What is difference between Architecture Neutral and Portable?
Architecture Neutral: Java is an Architecture neutral programming language because, java allows its application to compile on one hardware architecture and to execute on another hardware architecture.
Portable: Java is a portable programming language because, java is able to execute its application and all the operating system and all the hardware system.
In Terms of Java
Java Architecture Neutral - Here we are talking about the Operating System Architecture i.e the java Generate the Intermediate Byte-code(binary code) (handle by the JVM) and allow the java code to run on any O.S for which you have a Java virtual machine available( irrespective of its O.S architecture to handle memory allocation ,Cashing, register handling , bit code processing 32 bit or 64 bit while interpreting the code like each interpreter execute the code line by line - this is handle by jvm with respect to Hardware and O.S configuration) .
Portable (Generic meaning like transferable, Platform Independent, or even in terms of the Source code is fix for all i.e Simply means support to many)
Java Portable means java machine code write in one machine and will run on any machine that has proper JVM with respect to O.S.
Is there any way to compile from Java to standalone (or library) machine code without requiring a JVM?
There used to be a tool called GCJ that was part of GCC, but it's been removed. Now, all the links in the GCC site re-direct to their non-GCJ equivalents.
NB: the comments all refered to my original answer saying you can compile Java to native code with GCJ.
Yes!
Oracle has been working on the GraalVm, which supports Native Images. Check here: https://www.graalvm.org/
Native Image
The native image feature with the GraalVM SDK helps improve the startup time of Java applications and gives them a smaller footprint. Effectively, it's converting bytecode that runs on the JVM (on any platform) to native code for a specific OS/platform — which is where the performance comes from. It's using aggressive ahead-of-time (AOT) optimizations to achieve good performance.
See more:
Summary
https://www.graalvm.org/docs/getting-started/#native-images
Demos: Native images for faster startup
https://www.graalvm.org/docs/examples/native-list-dir/
Detailed: 'Ahead-of-time Compilation'
https://www.graalvm.org/docs/reference-manual/aot-compilation/
The Micronaut platform uses GraalVM to make native microservices:
https://guides.micronaut.io/latest/micronaut-creating-first-graal-app.html
Excelsior JET is a commercial Java to native code compiler. However, it was discontinued in May 2019.
Yes, the JIT in the JVM does exactly that for you.
In fact it can produce faster code than compiling the code in advance as it can generate code optimised for the specific platform based on how the code is used at runtime.
The JVM is always involved even if a very high percentage is compiled to native code as you could load and run byte code dynamically.
Another possibility would be RoboVM.
However, it only seems to work on Linux, iOS and Mac OS X.
As of today, the project still seems somewhat alive contrary to some posts online claiming the project to be dead.