12

I know a bit about JDK and JRE source and binary compatibility (e.g. this and this), but not sure about the following situation:

Consider I have an application which is compiled using JDK5 and runs on JRE6. It uses some libraries (jars) which are also compiled using JDK5.

Now I want to compile my application using JDK6. What new problems could arise in runtime in such a case (particularly, in compatibility with the "old" jars)? Should I fully retest the application (touch every library) or can rely on promised JDK/JRE compatibility?

Community
  • 1
  • 1
Igor Nardin
  • 1,611
  • 14
  • 12
  • possible duplicate of [Are there any specific examples of backward incompatibilities between Java versions?](http://stackoverflow.com/questions/1654923/are-there-any-specific-examples-of-backward-incompatibilities-between-java-versi) – Ciro Santilli OurBigBook.com May 04 '15 at 10:38

3 Answers3

9

Normally no problems should arise if you set the compiler option of JDK6 to use 1.5 source compatibility. However sometimes this is not always true.

I remember once when compiling 1.4 code with 1.5 compiler (using 1.4 compatibility). The jars where ok (1.4 binary level) but the application crashed due to a funny conversion.

We used a BigDecimal number passing an integer as argument to the constructor. The 1.4 version had only a constructor from double but the 1.5 version had both, the int and the double constructors. So when compiling with 1.4 compiler made the automatic conversion from int to double, but with the 1.5 compiler it checked that the int constructor existed and did not realize that conversion. Then when using the perfect binary compatible code on 1.4 JRE the program crashed with a NoSuchMethodException.

I have to admit that it was a strange case, but it is one of those cases where logic does not work. So my advice is if you plan to compile for older versions of JRE try to use the target version JDK whenever possible.

Fernando Miguélez
  • 11,196
  • 6
  • 36
  • 54
  • @Igor, From the JDK compatibility document: 7. Java SE 6 Properly Rejects Illegal Casts The cast implementation adheres more closely to the Java Language Specification. In general, this means that javac will accept more programs. However, in some rare cases, javac can now reject previously accepted, yet incorrect programs. http://www.oracle.com/technetwork/java/javase/compatibility-137541.html#incompatibilities Actually I have 1 such issue. – alexsmail Jan 24 '12 at 17:14
  • 1
    Of course they might have improved compatibility issues. My case was 1.4->1.5 migration. And 1.3->1.4 was even worse (1.3 was badly broken) – Fernando Miguélez Jan 25 '12 at 07:35
  • Sorry for resurrecting this issue -- I misread the question and upvoted, and after re-reading I feel compelled to undo my vote-- I'm not sure that your described situation matches that of the OP. Are you talking only about source compatibility (`-source`), or also about target (`-target`) compatibility? And you mentioned you compiled with a JDK5 to run in a JRE1.4. The OP compiles with JDK5 for JRE6, and upgrades to compile with JDK6 for JRE6. Your situation seems much different. But if you don't remember, forget it anyway (I already upvoted, and this could still serve as warning for others) – Alberto Sep 16 '15 at 12:50
  • 1
    The problem described here is caused by not specifying an appropriate `-bootclasspath`. It’s not sufficient to specify `-source 1.4 `target 1.4` while compiling with a newer JDK. Nowadays, this problem has been solved with the `--release` option which sets all three options at once (these JDKs carry a description of the older APIs for this purpose). – Holger Apr 18 '23 at 07:24
2

Untill and unless you have not changed your code and added new Java 6 features, there should be no issues. With regards to other jars there should be no issues at all. JDK always maintains backward compatibility.

NiranjanBhat
  • 1,812
  • 13
  • 17
  • "_JDK always maintains backward compatibility_" At least misleading: See the linked question in the comments to the OP. – Alberto Sep 16 '15 at 12:32
2

Compatibility mostly works. I would not expect any issue for you to arise aside from various warnings for e.g. not using generics. Maybe some barely used APIs were deprecated, but I assume they were left in place, just marked as deprecated.

Just try it, if it compiles you should be fine.

A key design aspect of Java - unfortunately - is full backwards compatibility.

There are very few exceptions where backwards compatibility was not preserved; most prominently Eclipse suffered when the sorting algorithm was changed from a stable to a non-stable sort algorithm (the order of objects that sort identically was no longer preserved); but that was never part of the Java specification, but a bug in Eclipse.

It's unfortunate, because there were a few poor choices that now cannot be changed. Iterator should not have had a remove() function in the API, Vector should not have been synchronized (solved by having ArrayList now), StringBuffer should not have been synchronized, hence StringBuilder. String should probably have been an interface, not a class, to allow for e.g. 8-bit strings, 32-bit strings - CharSequence is the better string interface, but too many methods do not accept CharSequence and require returning a String. Observable should be an interface too: you cannot make a subclass observable with this API. To name a few. But because of backwards compatibility, these cannot be fixed anymore until maybe JDK modularization (at which point some can at least disappear into an donotuse module ...).

Of course you should already have thousands of unit tests to help you test with the new JDK... :-)

Has QUIT--Anony-Mousse
  • 76,138
  • 12
  • 138
  • 194
  • AND ALSO you should also try to execute the compiled unit, if it is executable.. using the intended Java VM that will launch the the used in production. That way, i guess, i check compatibility. – Victor Aug 24 '15 at 15:04
  • To be fair, "_Just try it, if it complies[sic] you should be fine_" sounds to me like a too risky approach: I'd still fear unexpected problems at runtime. So the -1 (that I cannot undo without editing the answer) still holds. – Alberto Sep 16 '15 at 12:29
  • Java has high backwards compatibility requirements. They are supposed to have an extensive test suite, too. So unless they did some ugly hacks back then, the code should still be compatible; because all the methods should still be there, just as they were. And if they didn't write tests ... – Has QUIT--Anony-Mousse Sep 16 '15 at 16:55