Is Jdk "Upward" or "Backward" Compatible

Is JDK upward or backward compatible?

Note that for something to be backwards compatible there must be a counterpart that is forwards compatible (either intentionally or unintentionally). For example: are the DVD readers backwards compatible with CD's or are the CD's forward compatible with DVD readers?

In this case, it depends if you look at the compiler (or the bytecode it generates) or the virtual machine.

The compiler is not backwards compatible because bytecode generated with Java5 JDK won't run in Java 1.4 jvm (unless compiled with the -target 1.4 flag). But the JVM is backwards compatible, as it can run older bytecodes.

So I guess they chose to consider the compatibility from the point of view of javac (as it is the part specific to the JDK), meaning that the bytecode generated can be run in future releases of the jvm (that is more related to the JRE, but also bundled in the JDK).

In brief, we can say:

  • JDK's are (usually) forward compatible.
  • JRE's are (usually) backward compatible.

(And it also serves as a lesson that should be learnt long ago: the people writing the compilers are usually right, and we the people using them wrong xD)

By the way, doesn't it make more sense to pair backward/forward and downward/upward rather than mixing them up?

Can newer versions of java run on older versions?

Short answer: Yes. That’s the point. Your ancient byte code, even from Java 1, will run under Java 11.

More detailed answer: There have been a few classes that have now finally actually been deleted from the standard library. But chances are that you did not use them.

Edit: I seem to have misread your question. No, you cannot run code compiled with Java 11 under Java 8. The bytecode version has been increased, and Java 8 will refuse to run it.

Can program developed with Java 8 be run on Java 7?

In general, no.

The backwards compatibility means that you can run Java 7 program on Java 8 runtime, not the other way around.

There are several reasons for that:

  • Bytecode is versioned and JVM checks if it supports the version it finds in .class files.

  • Some language constructs cannot be expressed in previous versions of bytecode.

  • There are new classes and methods in newer JRE's which won't work with older ones.

If you really, really want (tip: you don't), you can force the compiler to treat the source as one version of Java and emit bytecode for another, using something like this:

javac -source 1.8 -target 1.7 MyClass.java

(the same for Maven), and compile against JDK7, but in practice it will more often not work than work. I recommend you don't.

EDIT: JDK 8 apparently doesn't support this exact combination, so this won't work. Some other combinations of versions do work.

There are also programs to convert newer Java programs to work on older JVM's. For converting Java 8 to 5-7, you can try https://github.com/orfjackal/retrolambda To get lower than 5, you can pick one of these: http://en.wikipedia.org/wiki/Java_backporting_tools

None of these hacks will give you new Java 8 classes and methods, including functional programming support for collections, streams, time API, unsigned API, and so on. So I'd say it's not worth it.

Or, since you want to run your Java 8 JEE applications on an application server, just run your entire server on Java 8, it may work.

Java JDK 11 Breaking Old Jars/Programs

Java tries to be backward compatible but sometimes breaking changes are necessary to evolve the ecosystem. Until now breaking changes were shipped with major release e.g. Java 9, 10, 11. In your case you are most likely affected by Java 11's JEP 320: Remove the Java EE and CORBA Modules.

Remember that Java 8 was released in 2014. For 5 years Oracle and the Java community provided patches and security fixes for Java 8 but doing this forever is impossible.

Has the Java language maintained source-code backward compatibility throughout its history?

Sun, and now Oracle, have always been extremely careful with backward compatibility with regards to Java.

Binary compatibility: You should be able to run Java code compiled with older versions on newer versions without modification. There might, however, be small incompatibilities.

Source compatibility: Code originally written for an older JDK version should almost always compile without modification with a newer Java compiler, but there are a number of small incompatibilities. One of them is the enum keyword added in Java 5; on older versions of Java, enum was a valid identifier, but not on Java 5. Also, importing classes from the default package has been removed (I think since Java 1.4). So you can't do:

import SomeClassName;

anymore on Java 1.4 or newer.

In the documentation of every JDK release there is a document about backward compatibility with previous releases, which lists the details.

  • Java SE 7 and JDK 7 Compatibility
  • Java SE 6 Compatibility
  • Incompatibilities in J2SE 5.0 (since 1.4.2)

  • Java 2 Platform, Standard Edition Version 1.4.0 Compatibility with Previous Releases

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

Compatibility notes for various versions:

  • Java 1.4
  • Java 5
  • Java 6
  • Java 7
  • Java 8

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

EJB specifications and Java versions - backwards compatibility

You shouldn't even have to "upgrade" the Java code, since I think older code can only be incompatible at source level due to identifiers that collide with newly introduced keywords, but that's not a problem at the bytecode level.

So your old Java 1.3/EJB 2.0 EARs should still run unchanged on a Java 5/EJB 3 appserver, and you could even do bugfixes in code and compile it with -target 1.3 on a modern JDK without having to fix the colliding identifiers (of course you then also cannot use the new source-level features).

Managing Java version compatibility

The strategy that's worked well for us is to decide up front which versions of the JRE we'll support. We do this by considering the platforms in use by our users, the version-specific features of a particular JRE that we'd like to use, and the release dates of the JRE versions. All of this is done in close consultation with our customer support department. (Of course all else being equal we prefer newer releases, as they tend to have bug fixes, optimizations, security updates, etc.)

Then, this becomes input into our QA process. Our testing effort must encompass all of the versions of the JRE that we're supporting.

Finally, we use the ability to specify specific JRE versions in the JNLP file when we deploy our application, to ensure that customers who try to run our app with an unsupported version get a "fail-fast" experience (with a helpful message about how to get the right JRE version), rather than mysterious failures down the road.

One thing we do to minimize incompatibilities is to avoid undocumented APIs (sun.misc, etc.).

Explicitly checking the current version of the JRE from within your code should be considered only as last resort to work around a known bug in a particular JRE version. If such a bug is discovered early enough in the process, we much prefer to just remove that JRE version from the list of supported versions.



Related Topics



Leave a reply



Submit