Reputation: 50117
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
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.
...
Another interesting analysis for JDK 1.0-1.6 you can find at Japitools JDK-Results page.
Upvotes: 3
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
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
Reputation: 16518
Obviously the naming convention of release names is not backwards-compatible.
Upvotes: 4
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
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
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
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
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
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
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
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
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
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