Why is an interpreted language considered more portable? [closed] - java

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.

Related

What JRE talks with

I have little to no knowledge of Java as a whole. I also tried to find that information by myself, without success though. This is why I decided to ask it here despite the negative attitude I am expecting afterwards. So here it is:
Does the JVM have access to the memory registries, or it uses(calls) the underlying system(the operation system or BIOS ) interfaces?
I am asking this question for basic knowledge of what JVM depends on.
- On the operation system?
- On the hardware platform (processor)?
- Or may be on both?
I am considering this issue, because I have a kit with processor Allwinner A20 running Linux Debian. I want to run a code (java code if possible) that manipulates the processor's GPIOs.
I have read that Java has ports to many platforms. What do they mean by platform - operation system or hardware(CPUs)?
This lack of clarity is not uncommon and dates back to the early days of Java, nearly 20 years ago now.
The term Java can refer to either of two distinct though tightly related things:
a language, object-oriented in nature, compilers for which produce not CPU-specific machine code but an abstract machine code
a program, or "runtime", that is hardware- and OS-specific, whose job it is to execute the abstract machine code on a particular hardware/OS platform combination
Since JRE was mentioned- the "JRE" artifact for a particular hardware/OS platform is largely just the second thing, while the "JDK" artifact for a particular hardware/OS platform is both things;
Java-the-language very deliberately does not have any direct facilities for utilizing OS/hardware specific resources. Everything is abstracted by classes, and while many hardware/OS objects- like Threads and Files- have abstract representations in Java-the-language's object oriented class library, many others- process IDs, for instance- do not.
Java-the-runtime is an extremely sophisticated piece of machinery that can turn abstract machine instructions produced by Java-the-language's compiler into executable code, execution of which can rival native, hand-tuned implementations in performance, at the cost of some efficiency for automated memory management- and can do so on different OS/hardware platforms from the same source code written in Java-the-language.
Although Java-the-language does not have facilities to talk directly to hardware- that is, to the interface to the hardware exposed by the operating system- Java-the-runtime has the ability to load hardware/OS specific native libraries that are authored in accordance with specific requirements and which can expose an object-oriented interface to the specific hardware/OS facility to programs written in Java-the-language.
There is of course more subtlety in this world- there are fundamental differences between the two dominant providers- Oracle, formerly Sun, which produces a toolchain for desktop and server platforms, and Google which produces a toolchain for Android-based hardware.
The same source code has some degree of compatibility between the two toolchains, though the abstract machine code produced from that source code by one toolchain is not compatible with the other.
That said, it is the case that if you have a specific piece of hardware, and you want to talk to it from Java-the-language, you need:
an operating system that runs on the hardware
a Java-the-runtime for that specific operating system/hardware platform- whether based on Oracle/Sun's work, or Google's
a native library that adheres to the expectations Java-the-runtime has, that provides a suitable interface to the hardware for Java-the-language

Is there more overhead in Java than in C# because of its crossplatform ability?

Someone told me there was more overhead for Java because you can essentially run it on most operating systems and that C# doesn't have that overhead so then it can execute at near C++ speeds.
So is there more overhead in Java, or does each OS has it's own overhead for it's JVM implementation?
C#, Java (and I'll toss it in there too - JavaScript) are languages. Languages are not fast or slow, they just are specifications for how we humans write things that are to eventually be handled by a computer.
The JVM is the Java Virtual Machine. But there are several different versions of it. There's HotSpot (the original), OpenJDK, And then one can look at JRockit from BEA, Apache Harmony and a bunch more.
For C# there is the CLR, but there's also Mono's runtime. There are also others that have been abandoned over time.
JavaScript (because I'm tossing that in there) has an entire army of runtimes. Some of those runtimes are faster than others.
It is the runtime that is faster or slower than another - even possibly for the same language. But that one is 'cross platform' and another is not is not enough of an indication to say that one is faster than the other. There are a great many other things at work and benchmarks can be constructed that show one combination being faster than another for each one.
Going even further, one can look at languages that span multiple runtimes. You've got Python with CPython as its default implementation - but there's Jython that runs in the JVM and IronPython that runs in the CLR. Similar examples can be found with Ruby, IronRuby, and JRuby or Clojure which can be compiled to JavaScript via ClojureScript and then run on one of the JavaScript runtimes rather than a JVM.
Again, its not the language that is fast or slow - but rather how its implemented in its runtime.
The Java language and the Java Virtual Machine (JVM) are completely separate entities. Oracle has done an excellent job of separating the two, so that other languages (like Scala or even Ruby) can run on the JVM.
The Java language itself is definitely written with the intent of targeting the JVM, but, so far as I know, there is no actual requirement that it must. So far as I know it's completely possible to write a Java compiler that generates native code, rather than Java bytecode. (This is all completely hypothetical. I've never heard of anyone actually doing that - there would be very little point. Current implementations of the JVM tend to be almost as fast as native code, and any benefit gained by this would be greatly outweighed by the loss of portability it would entail.)
The situation is further complicated by the fact that C# doesn't exactly have a VM, as discussed here. So the best comparison you can make is "does this implementation of the JVM run this Java code faster than that implementation of the .NET framework runs that C# code?"
In the end, unless there is a remarkable speed difference for very similar code, the comparison just isn't that compelling because there are too many variables. Use a different JVM, or a different Java compiler, or a different .NET implementation, or a different C# compiler, or run the same code on a different machine, and the numbers change.

The reason for JVM existence

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.

Which are the advantages of developing in Java a server-side application compared to other languages? [closed]

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 2 years ago.
Improve this question
Our company is starting the development of a client-server application and a discussion is going on about which technologies should be used.
For the client (GUI) side we tend to QT and C++. For the server side, we have been advised to use Java and indeed it looks like it is one of the languages being used most for server development.
Can anyone elaborate on the advantages offered by Java for server side development and why adopting it should make our life as developers easier and/or allow us to reach better results than if we used, let´s say, .NET or even C++?
Thanks in advance.
Some advantages:
Run compiled code across platforms.
Managed memory (garbage collection).
Hude wealth of excellent open-source libaries.
Large developer market.
Easy migration for C++ developers.
Some disadvantages:
Aging language — has not kept up with language advances IMO (e.g. adding functional facilities).
Future uncertain after Oracle aquistion (will become clearer with time).
Low level programming difficult.
You may want to look also at other languages which run on the JVM, such as Scala and Groovy, at .NET (it can run on Linux et al using Mono) and even the D language, which provides a C++ like, compiled to native, language with modern features such as garbage collection (optional), code contracts, lambdas etc. These languages provide many of the benefits of Java over C/C++ but have also taken the progression a bit further or in different directions.
Apart from platform independence, the main advantage of server-side Java development is the wide selection of mature libraries and standardized frameworks. However, the main focus here is on web development.
For a C++ client, Java could still be beneficial if you use REST as protocol between client and server (JAX-RS is pretty nice). Otherwise, it depends very much on your application domain and whether there are Java libraries that could help you in that regard.
Let's put it this way... it's not which server-side language is better and what not, it is what's available in your company that you can leverage of and make good use of it. When you work in a big corporation, sometimes you cannot just introduce "yet another language"... it doesn't work that way. :)
Further, every language has its pros and cons. You can almost argue the pros/cons in both way depending on how biased or open-minded you are. You can choose RoR and all that bleeding age technologies, but if your team members are not comfortable in dealing a brand new language, how exactly are you going to maintain the project in long run? I mean, if your team is familiar with PHP, I don't see anything wrong using that compared to Java, .NET, etc.
Your customers don't care the underlying implementation as long as it works.
Java advantages:
- mature
- good to excellent backward compatibility
- wide range of available frameworks for almost any problem
- robust - garbage collection, APIs as java.util.concurrent
- great tools to manage code quality, good IDEs etc.
- very good performance
- support for scripting
disadvantages:
- sometimes too many frameworks for the same thing
- not all the frameworks have as good quality of code as you need
- looks easier than really it is
You have many options in server side. Since you have the control over server side you can basically use anything. Using .NET forces you to use Windows Server so i will prefer a framework that can run on any operating system and is portable.
Java was the right answer 5-10 years ago. Because it had portability, and can work on any system. But these days developers look for languages/frameworks that are easier to use, maintain and code. I will vote on Python these days for server side development because of this, its fast it easier to read and maintain code wise, and it has many open source projects/libraries that you can use, even Google is favoring python over Java(GAE had python support first, then support for Java came). You can use django on python for web development and twisted for writing a server that uses TCP to communicate.
There are several issues you need taken in accout to select the language:
which are the languages which know your team best / good enougth
which are the languages which know the team thet must maintain the server
are there the right frameworks with an quality that makes you want to use them
will the code be maintainable as long as the server is in production
how fast will be the development -- the importent thing here is not the time you spend to type the code - more important is the time that you need until the product works stable enougth to use it for production without reasonable bugs
communication with other systems - if every system you need to communicate with is an .net - that it would be wise to build the new system in .net too
are there any constraints (must use this server, open source policy of your company, ...)
cost of licences, ...
...
At least the descicion to use a specific language for an project with a reasonable size, is always the question of cost. But not only the cost to build the system, also the cost to maintain it. - The points mentioned above are all cost related: for example: if you do not knwo the language you are slower (-> $), if the system can not be maintained, it must be rebuiled (-> $), if there are not the right libs, you need to implemnt it by your own (-> $), if the language you picked make it easy for bugs to hide, you need a long time until the system can go in production (-> $)
In MHO, the advantages of Java are: the wide spread knowlege (this is for .net too), a huge amount of realy mature open source framworks (this is the point for Java against .net), and the usage of a strong typed system and a compiler wich result in less bugs is a long term advantage of Java and .net over every not strong typed scripting language)
One must have for all languages you use on a Server is an Garbage collection!

What is portability? How is java more portable than other languages? [closed]

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.

Categories