I am developing an application and wonder what can cause the app to be platform dependent. For example, using Windows path in the app make it app that runs only in Windows.
There are plenty of things that can get you there:
using JNI to make native calls to OS specific features (like: reading/writing values to the windows registry)
relying on libraries ... that do make such native calls for you
The more subtle version of the same, especially in the context of GUI programming:
relying on specific (non standard) fonts
relying on OS specific plafs
As you have written in the question:
"external" identifiers that only work in a platform specific way, like: filepaths
The good news here: all of that is rather explicit. You have to write your code in a certain way to become platform dependent.
What is much harder, but luckily less common: writing valid Java code ... that in the end, relies on specific implementation details of the underlying JVM. For example threads are mapped to the threads that your OS provides. So, theoretically, there is a chance to write java code that behaves differently on different platforms.
Also note that there are in fact various different JVM implementations that matter in todays business world. Which can again result in different behavior at runtime.
Long story short: don't worry too much. When you follow standard best practices (for example: by avoiding fully hardcoded absolute path names), then your "medium sized" project should not have platform issues. But as soon as you are talking about really large, complex applications, things can be different, in many subtle ways.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 months ago.
Improve this question
Java is often cited as being more portable than other, say compiled, languages as the executable can be run on any platform with a JVM. But code written in C can be run on any platform with a C compiler.
So, naively, there are two alternatives: make lots of different compilers for lots of different platforms and transfer source code over a network for say an applet, which is compiled client-side; or make lots of different virtual machines to run on lots of different platforms and transfer the same, executable program or applets over networks.
Why is the latter better? I can see how server-side compilation is desirable, but I feel there is more to it than this. I can appreciate that it was less work for Sun Microsystems to create JVMs for many platforms than compilers for many platforms, but this surely wasn't the major motivation.
But code written in C can be run on any platform with a C compiler.
Not in the same way. You either need to compile it on that machine with that specific compiler, or need a compiler that is capable of cross-compiling. Either way, you have a bigger workload.
Still, there is some C Code that is quite portable. A simple program that just calculates basic arithmetic is quite portable, even in C, if you are willing to compile it to different platforms.
The second big important difference is the platform. As soon as you do I/O or use syscalls, your code becomes platform-specific, just because you need to directly interface with the host system. An interpreted language offers a unified platform. If my programs runs on the JVM, it just runs on it, no matter which system is host to the JVM. If I use "native" calls to the host OS, I have to use the proper ones for each OS - but with Java, my "OS" is the JVM.
Btw, there is so called "portable" C/C++ code, but it also hinges on similar concepts as the JVM. If you use Qt and similar libraries that offer uniform APIs on multiple platforms, then you can create quite portable C/C++ programs.
The perhaps most authoritative answer to why Java was designed to be interpreted may be found in the whitepaper that announced the Java language back in 1995:
1.2.3 Architecture Neutral and Portable
Java technology is designed to support applications that will be deployed into heterogeneous network environments. In such environments, applications must be capable of executing on a variety of hardware architectures. Within this variety of hardware platforms, applications must execute atop a variety of operating systems and interoperate with multiple programming language interfaces. To accommodate the diversity of operating environments, the Java Compiler TM product generates bytecodes--an architecture neutral intermediate format designed to transport code efficiently to multiple hardware and software platforms. The interpreted nature of Java technology solves both the binary distribution problem and the version problem; the same Java programming language byte codes will run on any platform.
Architecture neutrality is just one part of a truly portable system. Java technology takes portability a stage further by being strict in its definition of the basic language. Java technology puts a stake in the ground and specifies the sizes of its basic data types and the behavior of its arithmetic operators. Your programs are the same on every platform--there are no data type incompatibilities across hardware and software architectures.
and
1.2.5 Interpreted, Threaded, and Dynamic
The Java interpreter can execute Java bytecodes directly on any machine to which the interpreter and run-time system have been ported. In an interpreted platform such as Java technology-based system, the link phase of a program is simple, incremental, and lightweight. You benefit from much faster development cycles--prototyping, experimentation, and rapid development are the normal case, versus the traditional heavyweight compile, link, and test cycles.
It is also worth mentioning that the Java API goes far beyond standard libraries for C or C++.
Note that this perspective is somewhat dated. While largely still accurate, a modern take on the trade-off between a priori and runtime compilation whould include the additional optimization oppurtunities afforded by execution time statistics, and probably avoid the use of the word "interpreted" altogether - at least if we are somewhat serious about performance.
I am new to java. I know that the Java virtual machine is an abstract machine which helps to run the Java programs. So I would like to know if the JVM is included with all Java software, such as Eclipse?
Usually not. Java is used by so many programs that including it with every piece of Java software would use a lot more hard drive space than necessary, and a whole new JVM instance would have to be loaded for each one. Also, every piece of software would have to be updated whenever some security flaw is discovered. Hence, it's often installed just once, often shortly after setting up a new computer or OS installation.
Occasionally, a software package may be developed without assuming the presence of Java on a system; hence, it may include its own. Sometimes it may also need a customized JVM of some kind.
The main reason this is done is simply because Java is used by hundreds of millions, if not billions of devices. If a virtual machine or runtime is not so widespread, I can either convince my users to install it (usually an uphill battle if they're not themselves developers) or just bundle it myself.
If you're familiar with the notion of static and dynamic libraries, the same issues crop up there as well.
You may already know that,
the JVM is not one piece of software. Owners have their implementation, but other can make theirs if it satisfies various practical and contractual claims.
and the abstract specification is a Concrete implementations, which exist on many platforms and come from many vendors, are either all software or a combination of hardware and software and runtime instance hosts a single running Java application.
JVM is more to provide a way to strictly define the external behavior (subsystems, memory areas, data types, and instructions) of implementations which are described in an abstract inner architecture.
So To summarize JVM is the combination of hardware and software But not all Java packages are not included as you asked, fairly It doesn't even understand Java source code.
I am educating myself in the theory of programming languages and I wonder, why exactly do we need a Java Virtual Machine or any virtual machine at all for that matter? What are the fundamental reasons?
Is it solely for making it multi-platform? If so, why cannot we just have a platform independent language and different compilers for different platforms?
In their 1996 whitepaper The Java Language Environment, the Java team at Sun states the following design goals for the Java Language:
The design requirements of the Java TM programming language are driven by the nature of the computing environments in which software must be deployed.
The massive growth of the Internet and the World-Wide Web leads us to a completely new way of looking at development and distribution of software. To live in the world of electronic commerce and distribution, Java technology must enable the development of secure, high performance, and highly robust applications on multiple platforms in heterogeneous, distributed networks.
Operating on multiple platforms in heterogeneous networks invalidates the traditional schemes of binary distribution, release, upgrade, patch, and so on. To survive in this jungle, the Java programming language must be architecture neutral, portable, and dynamically adaptable.
The system that emerged to meet these needs is simple, so it can be easily programmed by most developers; familiar, so that current developers can easily learn the Java programming language; object oriented, to take advantage of modern software development methodologies and to fit into distributed client-server applications; multithreaded, for high performance in applications that need to perform multiple concurrent activities, such as multimedia; and interpreted, for maximum portability and dynamic capabilities.
A bit further down, they address the reasons for using an interpreter in greater detail:
The Java interpreter can execute Java bytecodes directly on any machine to which the interpreter and run-time system have been ported. In an interpreted platform such as Java technology-based system, the link phase of a program is simple, incremental, and lightweight. You benefit from much faster development cycles--prototyping, experimentation, and rapid development are the normal case, versus the traditional heavyweight compile, link, and test cycles.
While the Java Compiler is strict in its compile-time static checking, the language and run-time system are dynamic in their linking stages. Classes are linked only as needed. New code modules can be linked in on demand from a variety of sources, even from sources across a network. In the case of the HotJava Browser and similar applications, interactive executable code can be loaded from anywhere, which enables transparent updating of applications. The result is on-line services that constantly evolve; they can remain innovative and fresh, draw more customers, and spur the growth of electronic commerce on the Internet.
why cannot we just have a platform independent language and different compilers for different platforms?
Well. What if I write a Linear Search program (in any language..) on a 16 bit machine, compile it using a 16 - bit compiler and then try running it on a 32 - bit machine. Will it behave in the same way?.
Imagine products that have millions of lines of code. Do you think that nothing in that million line code will break because of change in machine architecture ?
Now,
Virtual Machines : These are basically software written to convert instructions into the "machine understanding / OS understanding language". They sit on top of your OS and make calls to it i.e, make the OS understand what your application wants.
JVM : is a kind of virtual Machine in which is used for Java. When you write and compile a java program, it will be in an " almost -machine independent" state. This is called as byte code. You can take it to another machine and run / interpret it.
Is it for platform portability? Yes. You already know most of the obvious features of JVM and its advantages and others have already given splendid responses.
Here I'll add the human side of the advantage Virtual Machines provide. It is primarily for ease of development and reach.
Consider C as an example of platform independent language with specific compilers for specific Operating Systems. One can code in C on Linux as well as Windows. But, you'll require an additional library header file conio.h to run your same program on a Windows system.
Now, if massive million lined source code programs and application suites were required to be recompiled on every system (with diverse hardware and software) will require them to recompile the same code over and over on each and every compiler. This may leave out some systems as possible targets, if the developers missed compiling for that system.
This actually happens in the game industry where certain games are just not compiled and build for certain systems (like most high end games are not made for Linux). The game studios are forced to compile each time for every target machine they want, like Wii, PS3, PS4, PC, XBOX etc.
It's a waste of time, effort, resources and sanity (specially when you're dealing with super massive heterogeneous file types and source codes, which take massive amounts of time to compile).
In short; It is to reduce menial repetitive recompilation of the same source code for every system, so that we programmers can focus on things worthy of our time. [Or we're just lazy ;)]
Addendum:
According to Larry Wall, the original author of the Perl programming language, there are three great virtues of a programmer; Laziness, Impatience and Hubris. Link
Java virtual machine (JVM) is a platform or a sandbox to run the byte code. Byte code has special instruction sets and operation which can only be identified by JVM.
This is the same case with any virtual machines where it expects specific set of operations.
Virtual machines are an important abstraction used to make language development and implementation easier.
A large number of languages use virtual machines of some kind to allow them to be executed. Dynamic scripting languages such as Ruby and Python are interpreted at runtime on simple virtual machine. The advantage of this is that if the interpreter can be re-compiled to run on an given environment then then language itself can be used on that environment too.
Other languages such as Java can be compiled ahead of time to bytecode which is then either interpreted or just-in-time (JIT) compiled for execution. In this model only the virtual machine itself, and not the compiler, needs to be ported to any given environment to run code there. Java used this to advantage by allowing applications to be embedded in web pages.
Even outside these more dynamic languages virtual machines are used to abstract away from the details of the underlaying hardware. For example the Low-Level Virtual Machine (llvm) compiler is engineered in such a way that it first compiles C, C++, Objective-C or whatever into instructions to run on virtual machine architecture and then translates this to real machine code. This translation can be done straight away, just as a traditional C or C++ compiler would, or at runtime using JIT compilation.
These different types of virtual machines are working at different levels of abstraction. The llvm virtual machine is, as it's name suggests, at a very low level. It abstracts the different peculiarities of CPU architectures such as how to load and store floating point numbers, if things should be passed around on the stack or in registers, and so on. Virtual machines for languages such as Python however are abstracting over operating system APIs and similar things.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 5 years ago.
Improve this question
I wonder how Java is more portable than C, C++ and .NET and any other language. I have read many times about java being portable due to the interpreter and JVM, but the JVM just hides the architectural differences in the hardware, right? We'd still need different JVMs for different machine architectures. What am I missing here? So if someone writes an abstraction layer for C for the most common architectures, let's say the CVM, then any C program will run on those architectures once CVM is installed, isn't it?
What exactly is this portability? Can .NET be called portable?
Portability isn't a black and white, yes or no kind of thing. Portability is how easily one can I take a program and run it on all of the platforms one cares about.
There are a few things that affect this. One is the language itself. The Java language spec generally leaves much less up to "the implementation". For example, "i = i++" is undefined in C and C++, but has a defined meaning in Java. More practically speaking, types like "int" have a specific size in Java (eg: int is always 32-bits), while in C and C++ the size varies depending on platform and compiler. These differences alone don't prevent you from writing portable code in C and C++, but you need to be a lot more diligent.
Another is the libraries. Java has a bunch of standard libraries that C and C++ don't have. For example, threading, networking and GUI libraries. Libraries of these sorts exist for C and C++, but they aren't part of the standard and the corresponding libraries available can vary widely from platform to platform.
Finally, there's the whole question of whether you can just take an executable and drop it on the other platform and have it work there. This generally works with Java, assuming there's a JVM for the target platform. (and there are JVMs for many/most platforms people care about) This is generally not true with C and C++. You're typically going to at least need a recompile, and that's assuming you've already taken care of the previous two points.
Yes, if a "CVM " existed for multiple platforms, that would make C and C++ more portable -- sort of. You'd still need to write your C code either in a portable way (eg: assuming nothing about the size of an int other than what the standard says) or you'd write to the CVM (assuming it has made a uniform decision for all of these sorts of things across all target platforms). You'd also need to forgo the use of non-standard libraries (no networking, threading or GUI) or write to the CVM-specific libraries for those purposes. So then we're not really talking about making C and C++ more portable, but a special CVM-C/C++ that's portable.
Once again, portability isn't a black and white thing. Even with Java there can still be incompatibilities. The GUI libraries (especially AWT) were kind of notorious for having inconsistent behavior, and anything involving threads can behave differently if you get sloppy. In general, however, it's a lot easier to take a non-trivial Java program written on one platform and run it on another than it is to do the same with a program written in C or C++.
As others have already said, portability is somewhat of a fuzzy concept. From a certain perspective, C is actually more portable than Java. C makes very few assumptions about the underlying hardware. It doesn't even assume that there are 8 bits in a byte, or that negative numbers should be represented using two's complement. Theoretically, as long as you have a Von Neumann based machine and a compiler, you're good to go with C.
In fact, a "Hello world" program written in C is going to work on many more platforms than a "Hello world" program written in Java. You could probably get the same "hello world" program to work on a PDP-11 and an iPhone.
However, the reality is that most real-world programs do a lot more than output "Hello world". Java has a reputation for being more portable than C because in practice, it takes a lot more effort to port real-world C programs to different platforms than real-world Java programs.
This is because the C language is really ANSI-C, which is an extremely general-purpose, bare-bones language. It has no support for network programming, threading, or GUI development. Therefore, as soon as you write a program which includes any of those things, you have to fall back on a less-portable extension to C, like Win32 or POSIX or whatever.
But with Java, network programming, threading, and GUI tools are defined by the language and built into each VM implementation.
That said, I think a lot of programmers also underestimate the progress modern C/C++ has made in regard to portability these days. POSIX goes a long way towards providing cross-platform threading, and when it comes to C++, Boost provides networking and threading libraries which are basically just as portable as anything in Java. These libraries have some platform-specific quirks, but so does Java.
Essentially, Java relies on each platform having a VM implementation which will interpret byte code in a predictable way, and C/C++ relies on libraries which incorporate platform specific code using the preprocessor (#ifdefs). Both strategies allow for cross platform threading, networking, and GUI development. It's simply that Java has made faster progress than C/C++ when it comes to portability. The Java language spec had threading, networking and GUI development almost from day one, whereas the Boost networking library only came out around 2005, and it wasn't until 2011 with C++11 that standard portable threading was included in C++.
When you write a Java program, it runs on all platforms that have JVM written for them - Windows, Linux, MacOS, etc.
If you write a C++ program, you'll have to compile it specifically for each platform.
Now, it is said that the motto of Java "write once, run everywhere" is a myth. It's not quite true for desktop apps, which need interaction with many native resources, but each JavaEE application can be run on any platform. Currently I'm working on windows, and other colleagues are working on Linux - without any problem whatsoever.
(Another thing related to portability is JavaEE (enterprise edition). It is said that applications written with JavaEE technologies run in any JavaEE-certified application server. This, however, is not true at least until JavaEE6. (see here))
Portability is a measure for the amount of effort to make a program run on another environment than where it originated.
Now you can debate if a JVM on Linux is a different environment than on Windows (I would argue yes), but the fact remains that in many cases there is zero effort involved if you take care of avoiding a few gotchas.
The CVM you are talking about is very much what the POSIX libraries and the runtime libraries try to provide, however there are big implementation differences which make the hurdles high to cross. Certainly in the case of Microsoft and Apple these are probably intentionally so in order to keep developers from bringing out products on competing platforms.
On the .net front, if you can stick to what mono provides, an open source .Net implementation, you will enjoy roughly the same kind of portability as Java, but since mono is significantly behind the Windows versions, this is not a popular choice. I do not know how popular this is for server based development where I can imagine it is less of an issue.
Java is portable from the perspective of the developer: code written in Java can be executed in any environment without the need to recompile. C is not portable because not only is it tied to a specific OS in many cases, it is also always tied to a specific hardware architecture once it has been compiled. The same is true for C++. .Net is more portable than C/C++, as it also relies on a virtual machine and is therefore not tied to a specific hardware architecture at compile-time, but it is limited to Windows machines (officially).
You are correct, the JVM is platform-specific (it has to be!), but when you say Java is portable, you are talking about it from a developer standpoint and standard Java developers do not write the JVM, they use it :-).
Edit #Raze2Dust To address your question. Yes, you could. In fact, you could make Java platform-specific by writing a compiler that would generate machine code rather than bytecode. But as some of the other comments suggest, why would you do that? You'd have to create an interpreter that maps the compiled code to operations in the same way the JVM works. So the long and short of it is, absolutely, you definitely could, but why would you?
Java provides three distinct types of portability:
Source code portability: A given Java program should produce identical results regardless of the underlying CPU, operating system, or Java compiler.
CPU architecture portability: the current Java compilers produce object code (called byte-code) for a CPU that does not yet exist. For each real CPU on which Java programs are intended to run, a Java interpreter, or virtual machine, "executes" the J-code. This non-existent CPU allows the same object code to run on any CPU for which a Java interpreter exists.
OS/GUI portability: Java solves this problem by providing a set of library functions (contained in Java-supplied libraries such as awt, util, and lang) that talk to an imaginary OS and imaginary GUI. Just like the JVM presents a virtual CPU, the Java libraries present a virtual OS/GUI. Every Java implementation provides libraries implementing this virtual OS/GUI. Java programs that use these libraries to provide needed OS and GUI functionality port fairly easily.
See this link
You ask if one could write a "C VM". Not exactly. "Java" is a big term used by Sun to mean a lot of things, including both the programming language, and the virtual machine. "C" is just a programming language: it's up to the compiler and OS and CPU to decide what format the resulting binary should be.
C is sometimes said to be portable because it doesn't specify the runtime. The people who wrote your compiler were able to pick things that make sense for that platform. The downside is that C is low-level enough, and platforms are different enough, that it's common for C programs to work fine on one system and not at all on another.
If you combine the C language with a specific ABI, you could define a VM for it, analogous to the JVM. There are a few things like this already, for example:
The "Intel Binary Compatibility Specification" is an example of such an ABI (which almost nobody uses today)
"Microsoft Windows" could also be such an ABI (though a huge and underspecified one), for which Wine is one VM that runs programs written for it
"MS-DOS", for which dosemu is one VM
"Linux" is one of the more popular ones today, whose programs can be run by Linux itself, NetBSD, or FreeBSD
"PA-RISC", for which HP's Dynamo was a JIT-like VM
All of these C VMs are in fact a real machine -- nobody, AFAIK, has ever made a C VM that was purely virtual. This isn't surprising, since C was designed to run efficiently on hardware, so you might as well make it run normally on one system. As HP showed, you can still make a JIT to run the code more efficiently, even on the same platform.
You need the JVM for different architectures, but of course your Java programs run on that JVM. So once you have a JVM for an architecture, then your Java programs are available for that architecture.
So I can write a Java program, compile it down to Java bytecode (which is architecture-agnostic), and that means I can run it on any JVM on any architecture. The JVM abstracts away the underlying architecture and my program runs on a virtual machine.
The idea is that the Java language is portable (or more accurately, the compiled byte-code is portable). You are correct that each VM requires a specific implementation for a given hardware profile. However, once that effort has been made, all java bytecode will run on that platform. You write the java/bytecode once, and it runs on any JVM.
.NET is quite similar, but with a far lower emphasis on the principle. The CLR is analogous to the JVM and it has its own bytecode. Mono exists on *nix, but you are correct that it is not "official".
Portability or as written in Wikipedia, Software Portability is the ability to reuse the same software (code) across multiple environments (OSes). The java JVM is a JVM that can be run on any operating systems it was designed for: Windows, Linux, Mac OSes, etc.
On .NET, it is possible to port your software to different platforms. From Wikipedia:
The design of the .NET Framework
allows it to theoretically be platform
agnostic, and thus cross-platform
compatible. That is, a program written
to use the framework should run
without change on any type of system
for which the framework is
implemented.
And because Microsoft never implemented the .NET framework outside of Windows and seeing that .NET is platform agnostic, Mono has made it possible to run .NET applications and compile code to run in Linux.
For languages such as C++, Pascal, etc. you will have to go to each OS and build it on that platform in order to run it on that platform. The EXE file in Windows isn't the same as the .so in linux (the machine code) since both uses different libraries to talk to the kernel and each OS has its own kernel.
WORE - Write Once Run Everywhere
In reality, this is limited to the platforms that have a JVM, but this covers off the majority of platforms you would wish to deploy to. It is almost a half-way between an interpreted language, and a compiled language, gaining the benefits of both.