views:

1016

answers:

7

Will code compiled using 1.5 and 1.6 run on a 1.4 JRE? We weren't sure which Java versions the 1.4 JRE supports.

We know that if the code in question implements 1.5 or 1.6 supported features then it definitely won't compile... and that there are some risks with "backwards compiling" but wasn't sure if the 1.4 JRE would refuse to even load the 1.5/1.6 compiled classes or not.


Update: I confirmed you get a java.lang.UnsupportedClassVersionError exception if you run an 1.6 class file on JRE 1.4.

A: 

I don't think it will.

Occasionally (for reasons too complicated to explain), I try to run code in a 1.5 JRE that I compiled in a 1.6 JDK. It typically throws a java.lang.UnsupportedClassVersionError exception.

Seth
This answer inspires much confidence. ;)
Chris Farmer
Sorry. I was editing. :)
Seth
And of course, you compile explicity for backwards compatibility as shown above.
Seth
+4  A: 

Only if you compile with javac -target 1.4 switch.

Obviously you will not be able to use 1.5+ features, such as Generics, Executors, etc.

Alexander Pogrebnyak
just using -target without the other advice in the sun.com link (see my answer) is dangerous.
Kevin Bourrillion
What happens if you don't use the switch? Will the JRE 1.4 raise an error?
Marcus
Most likely it will give you a class incompatibility error or something similar.
cjstehno
I had come across 'Version Major Minor' error when I tried to do the same.
Kushal Paudyal
No, the problem is just that your code may accidentally use a library method that doesn't exist in the older version of the platform. Result: a NoSuchMethodError etc. at runtime.
Kevin Bourrillion
+5  A: 

You can cross-compile. This document shows you how:

http://java.sun.com/javase/6/docs/technotes/tools/solaris/javac.html#crosscomp-example

You must specify the specific major version you're targeting (1.4, it sounds like).

Using this technique, your best bet is to always use the newest javac you can find! That way you have all the latest bug fixes and performance improvements, and it's perfectly safe.

EDIT: note that this does address the problem of library incompatibilities, which was discussed in several answers!

Kevin Bourrillion
I strongly disagree. If you do not want to use the javac coming with the JDK of the version you need to deploy on, then use the Eclipse compiler instead, and do it running under the Java version you need to deploy on. I believe the Eclipse compiler has seen MUCH more care in the last 5 years than javac.
Thorbjørn Ravn Andersen
I don't disagree that eclipse's compiler is very good.
Kevin Bourrillion
A: 

Yes and no. You can run code compiled under Java 6 on a 1.4 jvm if you set the "source" and "target" javac options to the version you are targeting (e.g. 1.4) when you compile them. This will work in cases where you have not used any of the additional classes or language features that were added since the target version.

Good luck.

cjstehno
+3  A: 

If you just build with the defaults of javac 1.6, your class files will not work on old versions of Java.

The best way to compile for older Java is just to use the older JDK releases. But if you really want to try to compile for older Java from newer, here are some instructions:

Adam Goode
Naw, the best way to compile for older Java is not to use the older releases, as they have *bugs*, and performance problems. The advice I shared in my answer -- to always use the newest you can get, but follow the proper advice for cross-compiling -- comes from Peter von der Ahe, who was the tech lead for javac for several years until recently.
Kevin Bourrillion
There are few bugs in the compiler so this isn't really appropriate. Furthermore, even with the -target switches, it's still possible to include a method call that is present in 1.6 but not 1.4 (e.g. string.split()). No amount of -target switches will fix that.On the other hand, compiling with an older JDK guarantees that you don't fall out of favour with either older or newer versions of the JDK.
AlBlue
There's always ecj if you're worried about bugs in javac.
Adam Goode
@AlBlue, on the issue of "few bugs in the compiler", yes, they're few, but they DO exist, and I have been bitten by them. Why bother with that? And on the issue of library incompatibilities, you're just plain wrong -- sounds like you never actually read my answer.
Kevin Bourrillion
+1  A: 

You also might be interested in http://en.wikipedia.org/wiki/Java%5Fbackporting%5Ftools

newacct
A: 

Yes, you can produce class files that are compatible with 1.4 with the 1.6 compiler (javac) however, simply doing this is not necessarily going to produce code that will work. The problem is that that will still compile against the 1.6 version of the API.

At first glance you would not expect this to be a problem since the contracts should not change but it is - I had a problem in that a new constructor that takes IIRC an integer was added to BigDecimal (in 1.5) and so at compile time the call to that constructor was specified however at runtime that constructor did not exist and so a runtime exception. You're probably going to have issues like this when methods are overloaded and you're relying on auto variable conversion.

The Javac app is in fact independent of the version of Java that it belongs to - you can specify a different API to use against 1.6 javac and in order to obviate any runtime issues this should be done.

Michael Wiles