Question: I know a bit about JDK and JRE source and binary compatibility (e.g. [this](http://upstream.rosalinux.ru/java/versions/jdk.html) and [this](https://stackoverflow.com/questions/4692626/is-jdk-upward-or-backward-compatible)), 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?

Answer: 
*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](http://docs.oracle.com/javase/1.4.2/docs/api/java/math/BigDecimal.html) had only a constructor from `double` but the [1.5 version](http://docs.oracle.com/javase/1.5.0/docs/api/java/math/BigDecimal.html) 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.
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... :-)