Are there any specific examples of backward incompatibilities between Java versions?
Asked Answered
S

14

49

Have there been incompatibilities between Java releases where Java source code/Java class files targeting Java version X won't compile/run under version Y (where Y > X) ?

By "Java release" I mean versions such as:

  • JDK 1.0 (January, 1996)
  • JDK 1.1 (February, 1997)
  • J2SE 1.2 (December, 1998)
  • J2SE 1.3 (May, 2000)
  • J2SE 1.4 (February, 2002)
  • J2SE 5.0 (September, 2004)
  • Java SE 6 (December, 2006)

House rules:

  • Please include references and code examples where possible.
  • Please try to be very specific/concrete in your answer.
  • A class that is being marked as @Deprecated does not count as a backwards incompatibility.
Stepaniestepbrother answered 31/10, 2009 at 16:55 Comment(7)
do you mean 'no answer is worse that an excessively vague answer'Swaim
this should be definitively a community wikiAronow
Why? It's a perfectly legitimate technical question...Largescale
It might be of a technical nature, but this is not the kind of question you ask because you >>need<< to know the answer.Raseta
Stephen C: I do need to know the answer.Stepaniestepbrother
knorv, Mind if I ask why? If there's a specific area where backwards compatibility is a concern, maybe we can be more helpful.Nordstrom
@Sean: A good reason to need to know this answer is to advocate the choice of java against .NET or php or any competing technology for some given project in which backward compatibility is a must.Obstacle
G
25

Compatibility notes for various versions:

The first major hiccup I remember was the introduction of assert in Java 1.4. It affected a lot of JUnit code.

Gonzalogoo answered 31/10, 2009 at 17:36 Comment(4)
Introducing new, reserved keywords should be severely punished! And they did it again with enum.Lathy
And yet they have never removed goto as a reserved word!Swine
It's interesting that there's no comment about incompatibilities of the JDBC package inside the official notes. Or did I miss it?Seleta
@Seleta - probably not noted because JDBC client code would not be required to change to work against the new API; Java applications would generally not implement these interfaces; the database vendors would. You can find specific information in the @since tags in the javadoc and there's probably more detail in the JDBC spec: java.sun.com/products/jdbc/download.htmlGonzalogoo
N
19

First of all, Sun actually considers all of the releases you mentioned (other than 1.0 of course) to be minor releases, not major ones.

I am unaware of any examples of binary incompatibility in that time. However, there have been some examples of source incompatibility:

  • In Java 5, "enum" became a reserved word; it wasn't before. Therefore, there were source files that used enum as an identifier that would compile in java 1.4 that wouldn't compile in java 5.0. However, you could compile with -source 1.4 to get around this.

  • Adding methods to an interface can break source compatibility as well. If you implement an interface, and then try to compile that implementation with a JDK that adds new methods to the interface, the source file will no longer compile successfully, because it doesn't implement all of the interface's members. This has frequently happened with java.sql.Statement and the other jdbc interfaces. The compiled forms of these "invalid" implementations will still work unless you actually call one of the methods that doesn't exist; if you do that, a MissingMethodException will be thrown.

These are a few examples I can recall off of the top of my head, there may be others.

Nordstrom answered 31/10, 2009 at 17:10 Comment(2)
The worst part was some of the methods added in the JDBC interfaces relied on new types that didn't exist in earlier versions. This meant it was impossible to make implementations that could compile in multiple versions of the JDK.Ogre
I actually ran into this again myself just last week at work. We ended up resorted to writing a dynamic proxy to get an implementation that would compile in both Java 5 and 6.Nordstrom
S
15

The interface java.sql.Connection was extended from Java 1.5 to Java 1.6 making compilation of all classes that implemented this interface fail.

Seleta answered 31/10, 2009 at 17:7 Comment(2)
I think all JDBC versions do that extensively. It should not be a surprise!Russianize
And again with JDK 1.8.Sharlasharleen
A
11

Every release of Swing broke something for us, from 1.3 through 1.6.

The JDBC issue has already been mentioned, but existing code worked.

From 1.5 to 1.6 there was a change in the behavior of Socket which broke the Cisco client.

Of course new reserved keywords were introduced.

The big one which I think was truely unforgivable on Sun's part was System.getenv(). It worked in 1.0, and then was deprecated and changed to throw an error on all platforms under the rather dubious justification that the Mac didn't have system environment variables. Then the Mac got system environment variables, so in 1.5 it was undeprecated and works. There is no reasonable justification for doing that. Return an empty set on a Mac (Swing has much bigger cross-platform issues if you want to care about that level of cross platform consistency) or even on all platforms.

I never agreed with them turning off the feature, but to change it to throw an error was just a pure breaking change that if they were going to do, they should have just removed the method entirely.

But, really from 1.0 to 1.1 they were less concerned about backwards compatability. For example, they dropped "private protected" as a modifier.

So the upshot is that every version changes enough to require close evaluation, that is why you still see many 1.4 questions here on SO.

Augustineaugustinian answered 1/11, 2009 at 0:11 Comment(0)
F
10

The main one that I can think of is the introduction of new reserved words:

Java 1.3: strictfp
Java 1.4: assert
Java 5.0: enum

Any code that previously used these values as identifiers would not compile under a later version.

One other issue that I remember causing problems on a project that I worked on was that there was a change in the default visibility of JInternalFrames between 1.2 and 1.3. They were visible by default, but when we upgraded to 1.3 they all seemed to have disappeared.

Felt answered 31/10, 2009 at 17:51 Comment(1)
Maybe it would be wise if they reserve some keywords that may get used in the future, even if it's not certain. Words like struct and function are valid identifiers at the moment.Jacaranda
C
8

Between 1.3 and 1.4 the interpretation of Long.parseLong(String) handled the empty string differently. 1.3 returns a 0 value, whereas 1.4 throws a NumberFormatException.

Recompiles aren't needed, but working code stopped working if it relied on the 1.3 behaviour.

Colostrum answered 31/10, 2009 at 17:37 Comment(0)
A
7

The semantics of the memory model changed from 1.4 to 1.5. It was changed to allow besides other things double checked locking again. (I think volatile semantics were fixed.) It was broken.

Adrenalin answered 31/10, 2009 at 17:5 Comment(1)
That is a change, but how would code in 1.4 break going to 1.5? Seems backwards compatible to me.Augustineaugustinian
S
4

The following will compile under Java 1.4 but not Java 1.5 or later.

(Java 5 introduced 'enum' as a keyword. Note: it will compile in Java 5 if the "-source 1.4" option is provided.)

public class Example {
    public static void main(String[] args) {
        String enum = "hello";
    }
}
Selfcommand answered 31/10, 2009 at 17:36 Comment(0)
T
4

Obviously the naming convention of release names is not backwards-compatible.

  • JDK 1.0 (January 23, 1996)
  • JDK 1.1 (February 19, 1997)
  • J2SE 1.2 (December 8, 1998)
  • J2SE 1.3 (May 8, 2000)
  • J2SE 1.4 (February 6, 2002)
  • J2SE 5.0 (September 30, 2004)
  • Java SE 6 (December 11, 2006)
  • Java SE 6 Update 10, Update 12, Update 14, Update 16
  • Java SE 7 ??? JDK7?

(The list is from Wikipedia.)

Tropopause answered 31/10, 2009 at 18:39 Comment(0)
O
3

Yet another example of java.sql breaking compatibility:

In 1.5 a compareTo(Date) method was added to java.sql.Timestamp. This method would throw a ClassCastException if the supplied Date was not an instance of java.sql.Timestamp. Of course, java.sql.Timestamp extends Date, and Date already had a compareTo(Date) method that worked with all Dates, so this meant that code that compared a Timestamp to a (non-Timestamp) Date would break at runtime in 1.5.

It's interesting to note that it appears that 1.6 seems to have fixed this problem. While the documentation for java.sql.Timestamp.compareTo(Date) still says "If the argument is not a Timestamp object, this method throws a ClassCastException object", the actual implementation says otherwise. My guess is that this is a documentation bug.

Ogre answered 31/10, 2009 at 17:57 Comment(0)
T
3

See report on API changes for the JRE class library here: http://abi-laboratory.pro/java/tracker/timeline/jre/

The report includes backward binary- and source-compatibility analysis of Java classes.

The report is generated by the japi-compliance-checker tool.

enter image description here

...

enter image description here

Another interesting analysis for JDK 1.0-1.6 you can find at Japitools JDK-Results page.

Trapshooting answered 7/1, 2011 at 10:16 Comment(0)
A
2

As Sean Reilly said, a new method can break your code. Besides the simple case that you have to implement a new method (this will produce a compiler warning) there is a worst case: a new method in the interface has the same signature as a method you do already have in your class. The only hint from the compiler is a warning that the @Override annotation is missing (Java 5 for classes, the annotation is supported for interfaces in Java 6 but optional).

Adrenalin answered 31/10, 2009 at 17:25 Comment(1)
Workaround: never make a method public unless it implements or overrides an interface method (not as hard as it might sound - I have been sticking to this rule for a few years now.)Lapidify
S
2

I have not tried it but in theory this would work in Java 1.1 and break in Java 1.2. (More info here)

public class Test {
    float strictfp = 3.1415f;
}
Selfcommand answered 31/10, 2009 at 17:39 Comment(0)
A
1

From personal experience, we had some AWT/Swing text fields embedded in a SWT_AWT frame in 1.5, that ceased to be editable after upgrading to 1.6.

Ambrogino answered 5/11, 2009 at 21:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.