knorv
knorv

Reputation: 50117

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

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:

House rules:

Upvotes: 49

Views: 4509

Answers (14)

linuxbuild
linuxbuild

Reputation: 16133

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.

Upvotes: 3

McDowell
McDowell

Reputation: 108879

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.

Upvotes: 25

tangens
tangens

Reputation: 39733

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.

Upvotes: 15

Andreas Petersson
Andreas Petersson

Reputation: 16518

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.)

Upvotes: 4

Chris
Chris

Reputation: 3519

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.

Upvotes: 1

Yishai
Yishai

Reputation: 91881

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.

Upvotes: 11

Laurence Gonsalves
Laurence Gonsalves

Reputation: 143154

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.

Upvotes: 3

Dan Dyer
Dan Dyer

Reputation: 54475

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.

Upvotes: 10

Thomas Jung
Thomas Jung

Reputation: 33092

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.

Upvotes: 7

Michael Easter
Michael Easter

Reputation: 24468

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;
}

Upvotes: 2

rsp
rsp

Reputation: 23373

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.

Upvotes: 8

Michael Easter
Michael Easter

Reputation: 24468

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";
    }
}

Upvotes: 4

Thomas Jung
Thomas Jung

Reputation: 33092

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).

Upvotes: 2

Sean Reilly
Sean Reilly

Reputation: 21836

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.

Upvotes: 19

Related Questions