views:

286

answers:

8

I've heard that the advantage of java is that people can write code, compile it for the JVM, and run it anywhere. Each person just needs a JVM app for their platform.

Of course, it looks similar to the current situation, where everybody has a compiler specific for their platform. So the advantage isn't explained by that. But I think I see the explanation.. the issue must be that in the java situation, you can't or weren't meant to access the real machine directly in an OS specific way.

I suppose it'd mean that in other languages, the code itself has to be amended depending on what computer it is running on.

Can anybody provide short examples of this like a Hello World program that demonstrates this? No doubt it'd be in non-java e.g. C

Since it's not something that'd -normally- happen in a Hello World program or most i've seen since the books I used on java, they were unfortunately "how to program" style books, and all the stuff in them didn't demonstrate it(perhaps 'cos they couldn't or didn't want to use java to demonstrate it!). Though they trumpeted it as a big advantage. I'd like to see examples of it.

+1  A: 

Guess you are talking of porting issues. Indeed JVM is what is spoken of in popular literature, that Java eliminates the need for code porting is a shade more subtle.

You don't have to look too far. A small industry of Windows to UNIX code porting developers [and vice versa] exist for this precise reason. Want examples? How about things like those near, far pointers in C? Or using __declspec(dllexport) to create a Windows specific dll while gcc will have none of this and you need -shared option?

One of the most difficult scenario was with doing C++ based GUI in particular before QT came into existence. Loads of GUI is still done on .NET, legacy code is on MFC and for Linux/UNIX a lot of legacy code is in XWindows. Java is a godsend in such cases -- most stuff will work without re-inventing the wheel across platforms.

Fanatic23
I know logically what a pointer is, and logically what compilers do and how computers work, but since I don't know c, i'm not familiar with near/far pointers. What are they? Do they involve the programmer directly specifying a memory location? why would they do that? I know for example that to declare a variable wouldn't normally need it, the compiler would deal with it.
barlop
@barlop Look into this link: http://wiki.answers.com/Q/What_are_near_far_and_huge_pointers_in_CAt the very least, they go to show how difficult (not to mention tricky) porting may be at times.
Fanatic23
near/far pointers are no longer used since at least 15 years... (note that I'm criticizing the particular example, not the concept)
Matteo Italia
near/far refers to the size of the pointers used which in turn determined how big a data area pointers could refer to (and which memory segment that area was placed in). Essentially 8086 architecture concepts in code.
Thorbjørn Ravn Andersen
+3  A: 

... where everybody has a compiler specific for their platform. So the advantage isn't explained by that.

Porting code written in for example C or C++ is almost always much more involved than simply recompiling the code. It's certainly not something that an average, non-developer computer user can do easily. Code written in compiled languages is very often written against the API of a specific operating system (the Win32 API, for example) and so it cannot be compiled on other operating systems easily.

Java bytecode runs on any platform where there is a Java runtime environment available. The code doesn't need to be recompiled. Ofcourse you can write operating-system specific code in Java, but Java's standard library, and the many free libraries available on the web, provide a very rich cross-platform environment.

Besides portability, running on a virtual machine has other advantages. Java uses a JIT compiler to compile Java bytecode to native machine code at runtime. The JIT compiler can do sophisticated optimizations for the specific CPU that the program is running on and it can use profiling information that wouldn't be available to an ahead-of-time compiler - in principle, a JIT compiler can therefore produce more optimal code than a "normal" compiler.

Besides the Java VM, there are other virtual machines. For example, Microsoft .NET contains the CLR (Common Language Runtime) and there's also LLVM, which has front-ends for many different languages including C and C++ (and which is supposed to bring the advantages of JIT compilation also to C and C++).

Jesper
+2  A: 

I think the point is that on java you can do useful things that are portable, too. In C and C++, you sometimes end up having to do pointer arithmetic and worrying what sizes ints are (vary by OS and CPU) and such. There are fixes in the standards for dealing with that in a portable way, but java has been designed with this in mind from the start. There is another benefit of the JVM, I think. Things like jython and scala are able to use the vast java libraries (and any other available java class) as if they were part of their own language. In most other languages, the way to interface with different languages is by using the C ABI, which is somewhat limiting in an OOP world. In this sense, java is the new C. Also, the jvm provides garbage collection and reflection and such nice things.

Gary
also have a read about endianness
Gary
i did read of endianness years ago. big endian, little endian.. No doubt compilers would handle that usually. When would code refer to memory at that level? And if it is referring directly to memory, like specifying an address, then wouldn't it go through the OS and become OS dependent that way? I still haven't had any code examples.. It'd be interesting to see Hello World that does that!(obviously it wouldn't have to, but as an example)
barlop
think about what happens when you write code on C on one platform and it does network IO to the same code on a platform with a different endianness. At some point somewhere you'd have to be conscious about it or your data would be scrambled. It has less to do with compilers than processors.
Gary
yes, the hello world wouldn't care. But save something to a file, and copy it to another system with different endianness and read it, and you'd see the problem. The processor and system just makes different assumptions for performance reasons. Java enforces a contract that makes you not have to worry about it.
Gary
point is, either way it's an issue, but java takes it upon itself to abstract out more of those things, and in C-based stuff, you'd have to use a library or do it yourself, or you'd risk shooting yourself in the foot. The compiler will let you much more easily than in java.
Gary
i'm not familiar with network programming, or C, but i'm familiar with programming and networks. You give an interesting scenario. It'd be interesting to see an example where that happens with a standard OS provided data structure. And it's because of the OS. For example, if 2 OSs use different endianness for their TCP/IP stack communications. which OSs, which data structure..
barlop
hmm, well, the TCP part isn't what I'm worried about, because the OS's know how to deal. But send over an array of RGB values, and that's when you'll have to worry about their ordering. Just talking theoretically, I haven't actually done it :-). One case where I had the problem was in porting the GSM AMR codec and testing the output from windows to linux to a TI dsp chip simulator. I think each case handled it differently and I had to byteswap to compare the files.
Gary
do anybody have an example where 2 different OSs, use different endianness, and if you write directly to main memory or you write a file, you'd encounter it? I suppose the compiler normally handles that. So you wouldn't get different code. It's like declaring a variable. The compiler knows about the machine and deals with it.
barlop
simply not true. That's the whole point. in C, an int is 32-bit on a 32-bit box. 64-bits on a 64-bit box. Compiler doesn't do any translation of the data or it's no longer C. however, the portable way is to use int32_t. On different endiannesses, the numbers are stored differently, but C doesn't care. It just knows to call the ADD instruction, and the CPU does it. Java implements a memory model and CPU that doesn't change across hardware.C was meant to be a portable assembly language.
Gary
interesting.. thanks
barlop
+2  A: 

Besides the advantages of the JVM that will allow you to execute code independently of the CPU architecture with reasonable performance thanks to the JIT-compiler, one fundamental advantage of Java is that it's not just a programming language, but a runtime environment with a API common to all the underlying platforms on which it can run (there are some differences occasionally, but they tend to be bugs).

gcc (GNU Cross Compiler), for example, will let you compile C code for more or less any platform. That's fine in principle for anything that's limited to using calls in stdio.h and a few others. However, you'll run into trouble quite quickly as soon as you try to use something a bit more OS specific, which tends to appears quite quickly: GUI, some I/O, threading, processes, networking.

As soon as you get an #include <win32.h> or similar in your C code, you'll have to rewrite parts of the code to port it to a Linux/OSX platform, some of this work may not be obvious or directly possible.

The advantage of Java isn't just its virtual-machine and ability to read and run the same bytecode on any platform, it's also the availability of a rather large library as part of the JRE (for example J2SE) and a common threading and networking model.

Bruno
+1  A: 

Of course, it looks similar to the current situation, where everybody has a compiler specific for their platform.

The thing you need to understand is that even if there is a compiler specific for each platform, the languages are slightly different (unless it is the exact same compiler, which is rare for others than the gcc compiler), and that the platform the programs see are vastly different. "Oh, we have 64-bit integers here, and you need to use X11 to do graphics etc etc etc". You need to handle these things in code, and just the fact that there exist a pretty big GNU project just for handling the configuration of specifying these differences to programs (automake) should indicate that this is not a trivial matter.

The platform provided by a JVM is much more rigidly specified, and your programs behave the same on all of them. Integers overflowing? Oh, that means do this, and ignore that. etc. This is so well done that it is expected that things work the same on all JVM's, and that failures are not due to platform differences between development and deployment machines. You always look first for some external reason and only in the rarest cases you find a bug in the JVM. A very well-engineered piece of work.

Thorbjørn Ravn Andersen
I guess AMD 64-bit processor vs 32-bit processor could be an example. I still haven't seen any code examples.. it'd be interesting to see for example, an example of a program writing hello world in a way that works on a 64-bit cpu but doesn't work on a 32-bit cpu.
barlop
Thorbjørn Ravn Andersen
thanks.. but what about in C?
barlop
I see actually.. some code would be written to make use of 64-bit integers storing numbers > 32-bit, and the code would have to be adjusted into slightly different code, for 32-bit integers.
barlop
+1  A: 

The main advantage, to me, is the library portability. Libraries might have version dependencies between themselves, but, other than that, a JAR just works.

There is the so-called classloader hell, but that's not nearly as common.

In most other languages, you either have to find the correct library binary, or you have to download the sources to install it.

Daniel
A: 

Portability mostly. The same Java binary can run on Linux/Mac/Windows. Plus SPARC/PPC/x86/x86-64/ARM/MIPS etc. Read: same binary. No recompilation needed. :)

joemoe
not answering the question so much..java byte code being portable (which i'm not sure is so relevant in any comparison since it's an intermediate stage regular languages don't have. hence I look more at programming languge's portability which is the same portability I think), but good examples of processors some of which are contemporary.. which is good to know.. I think some HP IPAQs use ARM.. and no doubt some mobile phones have CPUs with assembly languages I could look into some time. Not so relevant to the question 'cos assembly is an obvious case, but still good to know.
barlop
A: 

I've put together some of the answers..

While I haven't tested them.. I see nice examples that make sense to me, from within the answers, of

Bruno provided an example in C

#include <win32.h> (An OS specific line and code would have to be rewritten for a different OS) anything that's limited to using calls in stdio.h and a few others (are portable)

Gary, spoke of a case with int. That in C, "an int is 32-bit on a 32-bit box. 64-bits on a 64-bit box" "the portable way is to use int32_t" and a point about C and assembly language.. I have asked around and found that if you go over the limit, it cycles back to 0. So, that'd be a case of code having a different effect on a different system and compiling, but perhaps not working as intended, and it having to be rewritten.

Thorbjørn provided a link to examples of assembly language on different CPUs . Win32 ASM for 32-bit CPUs and Win64 for 64-bit. It has a hello world example in each, and says that it's not easy to convert them, since "In Win32, all the parameters are passed via the stack, however in Win64 they are passed via the registers." He said it uses different instructions.. I guess thouh perhaps it's more than that, in the sense that if it's a different assembly language.. and assembly language is an obvious case of non portability.. hence I didn't mention it in the question, but it's good to see the examples at that link. And it's good knowledge to have. Good to see some contemporary assembly languages not obscure machines..

barlop