Is Java really platform-independant?

Hi friends,
I hope everybody is fine and doing well. I had a previous thread quering about system calls. Unfortunately, you got the impression that I was discussing some kind of homework with you guys, and you got the thread closed. Infact, there was no homework involved there, it was just an idea that came to mind, when I was writting a c program using the read() system call. I hope this question of mine is not mistaken for a homework.

I am in the process of learning Java, with the help of a very good book titiled, "Java The complete Reference". There it is mentioned that java is a platform-independant language, and it can be interpreted anywhere regardless of the underlying hardware or operating system. About Java they say, "Write once, run anywhere" unlike in C/C++ which says, "Write once, compile anywhere". Java programs are compiled into an intermediary form, "the byte code" with .class extension, which can be interpreted by the Java Virtual Machine.

Here is my query, and a small java program which I want to run on a different platform.

 
// File name Java_Port.java
// Compiled on x64 architecture running Windows 7
// To be run on Solaris 10 , SPARC architecture running in 32-bit mode
 
public class Java_Port
{
        public static void main(String args[])
        {
                  System.out.println("Java is portable!");
        }
}

I compiled it by

javac Java_Port.java

I got the the file Java_Port.class

Interpreting it on the same computer where it has been compiled, it runs successfully.

But when I transfer this class file to a SPARC machine, with the latest version of JDK, it doesn't run there.

It says,

 
$ java Java_Port
Exception in thread "main" java.lang.UnsupportedClassVersionError: Java_Port : Unsupported major.minor version 51.0
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
        at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
Could not find the main class: Java_Port.  Program will exit.
 

The same problem persists whenever I run the same .class file on different versions of Microsoft Windows.

I am a novice as far as java is concerned, so if I have stated any thing silly, I beg your pardon for that.

Looking forward to your wonderful and helpful replies!

Thanks in advance!

Any program COMPILED on one architecture becomes architecture specific, the resulting binary will only be able to run on that platform...
Do not mix a language with result of compilation, Java is portable because you can get java for almost any architecture and so you can then use your code... and compile again :wink:

So what is the difference between Java and C/C++ then? You can also get C/C++ compilers for any plaform you want. I don't figure how Java is more protable or "Write once, run any where". According to you Java should also say, "Write once, compile and run any where". So what's the different. And where does the bytecode thing fit in the equation, I don't really get it dear!
Thanks for your wonderful reply anyway!

The ease at reading the code you did not write in a language you dont know but have to debug... :smiley:

Yes, You just have to "copy" your code (no rewrite then! )... true compiling is generating a machine language and so is processor dependant...(plus libraries... etc...)

All the best

My dear friend,
Could you please have a look at wikipedia
Java class file - Wikipedia, the free encyclopedia
which clearly says

 
In the Java programming language, source files (.java files) are compiled into (virtual) machine-readable class files which have a .class extension. 
Since Java is a platform-independent language, source code is compiled into an output file known as bytecode, which it stores in a .class file. 
If a source file has more than one class, each class is compiled into a separate .class file. These .class files can be loaded by any Java Virtual Machine (JVM). 
JVMs are available for many platforms, and the .class file compiled in one platform will execute in a JVM of another platform. 
This makes Java platform-independent.

What do you say about that?

I believe the error you're seeing is related to JDK version mismatch.
I suppose that the latest version on the SPARC machine is older than the one used for the compilation on Win 7.
So:

  1. Check the version on the Solaris machine: java -version .
  2. Use the same version to compile on Windows
    (I have very limited experience with Java, but I believe you need to use at least the same major version:
    if you compile the code with JDK 7, it won't work with 6,
    if you use 6 for compilation, it will work with both 6 and 7).
  3. Try to execute the .class file that you've compiled on Windows on the SPARC machine again.

The JVM will hide the specific platform dependencies.

1 Like

Yes true but the java virtual machine is still architecture dependant... you will have difficulties running a 64 bit binary on a 32 bit JVM... and java is very "version dependant" ... have you checked?
Why if it were so miraculous that big vendors (e.g. oracle) when giving installation software using java distribute their version in it?

I missed your post Radoulov... sorry repeating things... and Thanks!

Yes,
sure - the JVM itself *IS* platform specific.

 
I believe the error you're seeing is related to JDK version mismatch.

Thanks radoulov buddy! You are absolutely right, there was a mismatch in JDK version. Java is really platform-independant, I think I've confirmed it. Thanks for your help.
Problem solved!

Hi.

Googling java Unsupported major.minor version produces essentially the answer provided by radoulov. The second of about 86K hits contained:

Google is your friend.

Best wishes ... cheers, drl

---------- Post updated at 11:18 ---------- Previous update was at 09:51 ----------

Hi.

Here is a script that compiles a java code on a 64-bit box with Sun java:

#!/usr/bin/env bash

# @(#) s1	Demonstrate translation of java code.

# Utility functions: print-as-echo, print-line-with-visual-space, debug.
# export PATH="/usr/local/bin:/usr/bin:/bin"
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
edges() { local _f _n _l;: ${1?"edges: need file"}; _f=$1;_l=$(wc -l $_f);
  head -${_n:=3} $_f ; pe "--- ( $_l: lines total )" ; tail -$_n $_f ; }
db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf "\n" ) >&2 ; }
db() { : ; }
C=$HOME/bin/context && [ -f $C ] && $C java

FILE=${1-hello.java}

pl " Input data file $FILE:"
cat $FILE

pl " Results, compile and execute:"
javac $FILE
ls -lgG hello*
java -verbose hello |
specimen 3

exit 0

producing:

% ./s1

Environment: LC_ALL = C, LANG = C
(Versions displayed with local utility "version")
OS, ker|rel, machine: Linux, 2.6.26-2-amd64, x86_64
Distribution        : Debian GNU/Linux 5.0.8 (lenny) 
bash GNU bash 3.2.39
java version "1.6.0_22"

-----
 Input data file hello.java:
public class hello
{
  public static void main( String[] args )
  {
    System.out.println( "Hello, world from java." );
  }
}

-----
 Results, compile and execute:
-rw-r--r-- 1 427 Mar 12 11:03 hello.class
-rw-r--r-- 1 127 Mar 12 10:34 hello.java
Edges: 3:0:3 of 308 lines in file "-"
[Opened /usr/lib/jvm/java-6-sun-1.6.0.22/jre/lib/rt.jar]
[Loaded java.lang.Object from /usr/lib/jvm/java-6-sun-1.6.0.22/jre/lib/rt.jar]
[Loaded java.io.Serializable from /usr/lib/jvm/java-6-sun-1.6.0.22/jre/lib/rt.jar]
   ---
Hello, world from java.
[Loaded java.lang.Shutdown from /usr/lib/jvm/java-6-sun-1.6.0.22/jre/lib/rt.jar]
[Loaded java.lang.Shutdown$Lock from /usr/lib/jvm/java-6-sun-1.6.0.22/jre/lib/rt.jar]

Now the code will be transferred to a 32-bit box running GNU java, and only executed with this script:

#!/usr/bin/env bash

# @(#) s1	Demonstrate execution of 64-compiled java on 32-bit platform.

# Utility functions: print-as-echo, print-line-with-visual-space, debug.
# export PATH="/usr/local/bin:/usr/bin:/bin"
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
edges() { local _f _n _l;: ${1?"edges: need file"}; _f=$1;_l=$(wc -l $_f);
  head -${_n:=3} $_f ; pe "--- ( $_l: lines total )" ; tail -$_n $_f ; }
db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf "\n" ) >&2 ; }
db() { : ; }
C=$HOME/bin/context && [ -f $C ] && $C java

FILE=${1-hello.class}

pl " Input data file $FILE:"
file $FILE

pl " Results, execute:"
ls -lgG hello*
pe
java -verbose hello 2>&1 |
specimen 3

exit 0

producing:

./s1

Environment: LC_ALL = C, LANG = en_US.UTF-8
(Versions displayed with local utility "version")
OS, ker|rel, machine: Linux, 2.6.26-2-686, i686
Distribution        : Debian GNU/Linux 5.0 
GNU bash 3.2.39
java version "1.5.0" ( gij (GNU libgcj) version 4.3.2 )

-----
 Input data file hello.class:
hello.class: data

-----
 Results, execute:
-rw-r--r-- 1 427 Mar 12 11:03 hello.class
-rw-r--r-- 1 127 Sep 17  2009 hello.java
-rw-r----- 1 108 Jan  6  2008 hello.java.orig

Edges: 3:0:3 of 256 lines in file "-"
[Loaded (pre-compiled) java.lang.ClassLoader from <no code source>]
[Loaded (pre-compiled) java.lang.Object from <no code source>]
[Loaded (pre-compiled) java.lang.Class from <no code source>]
   ---
[Loaded (pre-compiled) java.util.Vector$1 from <no code source>]
[Loaded (bytecode) hello from (file:/home/drl/try/java/hello/ <no certificates>)]
Hello, world from java.

My conclusion is that for simple codes, java is platform independent. Whether or not this holds for complex codes is left as an exercise.

Best wishes ... cheers, drl