Java is striving to be backward compatible. (It is to such an extent that it crippled its generics for that).

But are there situations when old code would not compile on newer versions (more importantly Java 5, and the forthcoming Java 7)

+5  A: 

Yeah, for example when using enum in older jdks:

Enumeration enum = ...

would compile with jdks prior to 1.5.

That was the only thing I myself thought of :)
@Bozho - another example is when the old code uses 'assert' as an identitier.
Stephen C
Even nastier (had it in some lagacy code): package names like `com.example.best.app.enum`. If those packages contain public/exported interfaces, you're close to being lost. Refactoring is a real challenge.
@Andreas_D, you're close to being lost... *until Java 7*, which supports exotic identifiers, so the snytax would be: `import com.example.best.app.#"enum".Interface` - that is, if Duke Nukem Fore... er, if Java 7 ever is released.
And `assert` in 1.4 and `strictfp` in 1.2.
Tom Hawtin - tackline

Methods and classes can be labeled deprecated, which would throw a compile time error. But you can tell the compiler to ignore it. Other than Enumeration, you could compile

1) the word is "deprecated", not "depreciated". 2) By default the compiler only issues a warning message.
Stephen C

At one point they took away getenv, but then the next version they put it back.

I once had a problem where a new library class name conflicted with the name of a class we had created. We used "import java.whateveritwas.*" so we dragged in the new class without even knowing it. I forget what the class name was, but it could happen to you with any new class, especially one with a fairly generic name like "List" or "Map".

That's the only problems with new versions that I recall running into.


I once had a related issue with Class#getRessource() - some code that compiled well under 1.4.2 and 1.5+ but didn't work on JVMs > 1.4.2.

And I remember some issues with third party libraries (some versions of bea weblogic 8.1.4, if I remember right) that refused to cooperate in a Java 1.5 environment because some interface had been moved to different package (it's long ago, correct me if the details are not accurate.)

+3  A: 

New versions might not "break" anything, and still make your code not compile.

For example, in JDK5, The method Timer.getId() was added, which returns long.
We actually had a class that subclassed Thread and had its own getId method that returned a string. This of course caused compilation problems, because all of a sudden we were attempting to override a method and change the type of its return value.

Change the *type* of the return value, you mean?
qualifies as an answer but is true for 1.5->1.6 and 1.6->1.7 migration too. Every new method added to a non-final class of any API has the potential to break your code.
This is why VB and C# have a way to "shadow" a method in a subclass. I'm surprised that Java still hasn't figured out this trick.
Jonathan Allen
+6  A: 

There seem to be quite a few of them actually - well, not all of them result in a compilation error but this is the official word from sun: http://java.sun.com/j2se/JM_White_Paper_R6A.pdf

I typically use these checks:

  1. Prior to 1.4, URLConnection.getInputStream threw a FileNotFoundException if the file type was known and the response code was greater than or equal to 400. Otherwise no exception would be thrown

  2. HttpURLConnection.getErrorStream can be used to read the error page returned from the server.Prior to 1.4, getErrorStream() always returned null.

  3. New methods have been added to the DOM interfaces, so some existing applications will not be able to compile with the new interfaces.

  4. ErrorHandler, EntityResolver, ContentHandler, and DTDHandler can now be set to null by applications. SAX 2.0 required the XML processor to throw java.lang.NullPointerException in this case. (The JAXP parser implemented in 5.0, like most implementations, reacts to null by using the default settings.)

  5. The resolveEntity method in DefaultHandler and the EntityResolver subclass throws IOException and SAXException. Previously it threw only SAXException.

  6. In SAX 2.0.1, an application can set ErrorHandler, EntityResolver, ContentHandler, or DTDHandler to null. This is a relaxation of the previous restriction in SAX 2.0, which generated a NullPointerException (NPE) in such circumstances.

  7. As of 5.0, XSLTC is the default transformer, XSLTC does not support all the extensions that Xalan does. These extensions are beyond the definition of the JAXP and XSLT specifications.

  8. In 5.0, the org.apache classes, have moved in 5.0 to com.sun.org.apache.package.internal so that they won’t clash with more recent, developer-downloaded versions of the classes.

  9. A BigDecimal method changed its behavior between 1.4 and 5.0, causing JDBC drivers to malfunction.

  10. As of 5.0, comparing a java.sql.Timestamp to a java.util.Date by invoking compareTo on the Timestamp results in a ClassCastException.

  11. The java.net.Proxy class was added in 5.0, making two classes named Proxy: (java.lang.reflect.Proxy,java.net.Proxy)

  12. The following words were added to the Java language between 1.3 and 5.0, so they are no longer available for use as field or method identifiers:[assert (added in 1.4),enum]

Ryan Fernandes
They broke the DOM interfaces? Wow, just when I thought the Java maintainers couldn't be any stupider.
Jonathan Allen
@Jonathan I believe that is `org.w3c.dom`. Perhaps be a bit smarter when calling people stupid.
Tom Hawtin - tackline
Sun didn't have to choose to ship the W3C's API for XML. And they certainly didn't have to accept a "standard" that is so poorly designed. And it is downright stupid to allow them to change the interface instead of making them create new interfaces with a different name or namespace.
Jonathan Allen

The nastiest problems I've had recently1 with migrating code was with Eclipse on OSX. The problem was with the Java5→6 migration, and was due to the fact that on OSX the default build of Java5 was 32-bit and the only build of Java6 was 64-bit. This caused a lot of problems because the SWT (which Eclipse is built on) uses native code.

The other thing I'm aware of is the tangle you can get into with the various libraries that support web services, but the fix I've usually found there is to upgrade to Java6 and use the system libraries wherever possible. It's an area where Java6 was massively better than 5.

1 To be fair, this was a while ago and newer builds of Eclipse come with the required workarounds built in.

Donal Fellows