Can I use higher java version (17) on my machine than mentioned in existing (11) spring boot project's pom.xml ?
will it create any problem ?
Backward Compatibility
Java versions are expected to be binary backwards-compatible. For example, JDK 8 can run code compiled by JDK 7 or JDK 6. It is common to see applications leverage this backwards compatibility by using components built by different Java version.
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. JDK’s are (usually) forward compatible.
See: https://alanxelsys.com/php/what-is-meant-by-backward-compatible-in-java.html
Related
Backward binary compatibility (or downward compatibility) - an ability of clients built with an old version of library API to run on a new one (wiki).
Upward binary compatibility (or forward compatibility) - an ability of clients built with a new version of library API to run on old one (wiki).
The general Sun's document about JDK Incompatibilities in J2SE 5.0 since 1.4.2 (and Java SE 6 compatibility with J2SE 5.0 too) describes the compatibility of JDK as following:
JDK 5.0 is upwards binary-compatible with Java 2 SDK, v1.4.2 except for the incompatibilities listed below. This means that, except for the noted incompatibilities, class files built with version 1.4.2 compilers will run correctly in JDK 5.0.
I suppose that documentation writers have mixed up terms "upward" and "backward" compatibility in this sentence. They describe a "backward" compatibility, but call this feature as "upward" compatibility.
Is this a typo, mistake or intended term here?
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?
Extending answers to include the most recent Java …
Java SE 7 and JDK 7 Compatibility
Quotes from Oracle's undated page:
Compatibility is a complex issue. This document discusses three types
of potential incompatibilities relating to a release of the Java
platform:
Source: Source compatibility concerns translating Java source code into class files including whether or not code still compiles at
all.
Binary: Binary compatibility is defined in The Java Language Specification as preserving the ability to link without error.
Behavioral: Behavioral compatibility includes the semantics of the code that is executed at runtime.
… and
Incompatibilities between Java SE 7 and Java SE 6 Java SE 7 is strongly compatible with previous versions of the Java platform.
Almost all existing programs should run on Java SE 7 without
modification. However, there are some minor potential source and
binary incompatibilities in the JRE and JDK that involve rare
circumstances and "corner cases" that are documented here for
completeness.
Java SE 7 Incompatibilities in the Language, the JVM, or the Java SE API
… and
Incompatibilities between JDK 7 and JDK 6
JDK 7 Incompatibilities in javac, in HotSpot, or Java SE API
(No preamble there – just a list of incompatibilities.)
Backward only. Forward compat ("gracefully accept input intended for later versions of itself") would require the 1.5 JVM to be able to run 1.6 compiled code, which it can't.
Backward requires "if it can work with input generated by an older device" which is true as a 1.6 JVM can run 1.5 compiled code.
Each release of the JDK/JRE coincides with a version of Java bytecode. Each compiler produces code of a specific bytecode version. Each JVM understands a version and all earlier versions of a specific bytecode version.
When the JVM loads a class it checks the bytecode version and if it is > than the JVMs latest understood version you'll get an Error. (ClassVersionError or something).
Java (VM) is Backward compatible. Code built by java 1.4.2 will run on 1.5 & 6 VM's. The JDK compiler is not backward compatible. So code cannot be compiled by java 1.5 to run on 1.4.2 for example.
JDK is Backward compatible, i.e. Byte Code that complies to 1.4.2 spec will run on Java 5 JVM
JDK is downwards compatible as per the definition from wiki.
It should be backward compatible.
jdk is upward compatible - new version can run on old one
Has Java always maintained source-code backward compatibility during its development?
More precisely: given two Java versions X and Y with X < Y, is any program for Java X also a valid program for Java Y, with the same semantics?
E.g. X = Java 2 (or 1.2 with the old numbering) and Y = Java 5.
Or is there only compatibility at the JVM level: e.g. a class compiled for the JVM 1.2 can be run by the JVM 5?
If it is possible to run Java 2 code on a Java 5 (or 6, or 7), what are the exact steps that I have to follow? Compile directly with a Java 5 compiler? Compile with a Java 2 compiler and run on JVM 5?
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
Starting witg Java 1.5 enum became a reserved word. Thus any Java 1.4 source code containing enum became broken starting with 1.5
As far as I know JVMs are backwards compatible. A class compiled with JDK 1 will work in the latest JRE 7.
The libraires are definitely not 100% compatible. Some methods have been deprecated (and subsequently removed). Some classes changed behavior in (usually) subtle ways which will cause programs to behave differently.
You can always run with a newer version of the JDK then the one used for compilation. The other way around is not possible (unless you compile using the -target parameter).
You might want to read this document (in particular the Cross-Compilation Options section), which explains the target parameter and the default behavior
You can look at the backward compatibility analysis of the Java (Jre) library classes here: http://abi-laboratory.pro/java/tracker/timeline/jre/
The report is generated by the japi-compliance-checker tool.
Java is generally compatible with previous releases but anyway it may be a lot f issues with migration.
See my article about migration from JDK 6 to 8 for details
I'm using CLDC 1.1 + MIDP 2.0 .
The "Compiler compliance level" is set to 1.4 .
When I set "Compiler compliance level" to 1.6, I get the following error: "ALERT: java/lang/ClassFormatError: Bad version information.".
How can I use java 1.6 with J2ME?
This answer maybe outdated now, please refer below for latest answers.
Date: April 2011
How can I use java 1.6 with J2ME?
You can't
Core Reason: J2ME is meant for mobile device where the memory & cpu are the biggest constraint.
Java ME is a subset of Java, and most of the ME specific code will reside mostly on the client, so you don't need any special versions of Java to compile the program.
The problem here is that you are using a version of Java compiler that didn't exist when the phone was invented. The version of the Java compiler is written to the .class compilation output.
Ideally you would compile the project with an older version of Java, but it is very hard to install an old version. So we can act as a compiler ourselves, and manually set the version in the .class output files to the version we desire, and we should make sure that we don't use features from after that version. In this case we will target version 1.2.
You can use the -source and -target options of the compiler to prohibit as many features as possible but many javac compilers have a limit to the older versions they can target, my Java 9 (1.9) can go as low as 1.6. You will need to manually ensure that you are not using features introduced between 1.2 and 1.6
The first 4 bytes in a .class file are the infamous "CAFEBABE" magic string.
bytes 5 and 6 are usually 0
bytes 7 and 8 are the java minor and major versions.
Change Byte 8 to 0x2E. According to https://en.wikipedia.org/wiki/Java_class_file this corresponds to version 1.2 or Java2.
We are using Java2 because, as you can see in its initials J2ME, Micro Edition was released in Java 2. So for backwards compatibility reasons, you can be fairly confident that the phone will run such applications. If you need features introduced after this Java version, just keep increasing the version number until it fails again to find out the exact version of Java supported by your phone.
you can not use it because it is for se and ee version not compatible with mobile
latest sdk for j2me 3.0 is available
Does the bytecode depend on the version of Java it was created with?
If I compiled a java file in the newest JDK, would an older JVM be able to run the .class files?
That depends on three things:
The actual Java versions you are talking about. For instance, a 1.4.0 JVM can run code compiled by a 1.4.2 compiler, but a 1.3.x JVM cannot1.
The compilation flags used. There is a -target compiler flag that tells it to generate code that will run on an older (target) JVM. And the -source compiler flag tells it to only accept the older JVM's language features. (This approach won't always work, depending on the Java language features used by your code. But if the code compiles it should work.)
The library classes that the class file uses. If it uses library classes that don't exist in the older class libraries, then it won't run ... unless you can include a JAR that back-ports the classes2. You can avoid this problem by using the -bootclasspath option to compile your code against the APIs of the older version of Java.
Does the bytecode depend on the version of the java it was created with?
Yes, modulo the points above.
1 - The Java 8 JVMS states this: "Oracle's Java Virtual Machine implementation in JDK release 1.0.2 supports class file format versions 45.0 through 45.3 inclusive. JDK releases 1.1.* support class file format versions in the range 45.0 through 45.65535 inclusive. For k ≥ 2, JDK release 1.k supports class file format versions in the range 45.0 through 44+k.0 inclusive."
2 - A backport could be problematic too. For example: 1) Things which depend on native code support would most likely require you to implement that native code support. 2) You would most likely need to put any back-port JAR file onto the bootclasspath when you run the code on the older JVM.
Does the bytecode depend on the version of the java it was created with?
Normally yes. But by using the -source, -target and -bootclasspath options, a 1.7+ compiler can be used to create binaries that are compatible with Java 1.1
First and foremost all java files have a version byte in the class header. Older jvms won't load classes with newer versions, regardless of what features they have.
JVM bytecode is forward compatible between major JVM version, but not backward compatible. However, for the best information you will have to read the JVM release notes because they typically indicate how backward compatible the bytecode is.
Edit clarification since this caused discussion in the comments
JVM bytecode is forward compatible, such that bytecode from one JVM is compatible with with later JVM releases. For example, you can take bytecode from the 1.4 JVM and run it in Java 5 or Java 6 JVM (aside from any sort of regression issues as pointed out by Andrew).
JVM bytecode is not backward compatible between JVMs, such that bytecode from a JVM is not guaranteed to work in a previous release of the JVM, as would be the case if you were attempting to run code compiled for Java 6 in a 1.4.2 JVM.
Does the bytecode depend on the version of the java it was created with?
Yes.
If I compiled a java file in the newest JDK, would an older JVM be able to run the .class files?
No. But the opposite will work, most likely. You might like see this interesting thread, it talks about backporting Java.
No, unless you specify as target the old JVM.
Eg.with Java 6 you can compile and run in Java 1.4 using:
javac -target 1.4 SomeClass.java
Obviously the source code should be 1.4 compatible.
You can compile classes that are older-version JVMs compatible if you don't use features available in higher JVMs.
javac -target 1.5 MyJava.java
javac -target 1.4 MyJava.java
I have a problem deploying compiled classes in a Tomcat web application: I'm deploying a class which is to be called from a servlet, but when I run the application it fails telling me of a ServletException: Error allocating the servlet instance due to an UnsupportedClassVersionError: Bad version number in .class file.
Tomcat is using Java 1.5.0_06 as reported by the manager. My class was compiled using Java 1.6.0_14. Running javap on any of the classes already present tells me "Major version 46, minor version 0" which should be 1.2.0 initial and which isn't available anymore for download. The oldest I can find is 1.2.1_004 which doesn't even compile.
Do i need to match my Java version to the Tomcat environment or to the classes already there? Re-compiling the whole project using more modern Java is not feasible for me at the moment, although I'd love to do so.
That's easy: You compiled your application with a later version Java compiler than the Java runtime underneath Tomcat.
Update
The java compiler, javac, supports the options
-source release
Specifies the version of source code accepted. The following values for release are allowed:
1.3 the compiler does not support assertions, generics, or other language features introduced after JDK 1.3.
1.4 the compiler accepts code containing assertions, which were introduced in JDK 1.4.
1.5 the compiler accepts code containing generics and other language features introduced in JDK 5. The compiler defaults to the version 5 behavior if the -source flag is not used.
5 Synonym for 1.5
...and even more importantly,
-target version
Generate class files that will work on VMs with the specified version. The default is to generate class files to be compatible with the JDK 5 VM. When the -source 1.4 or lower option is used, the default target is 1.4. The versions supported by javac are:
1.1 Generate class files that will run on VMs in JDK 1.1 and later.
1.2 Generate class files that will run on VMs in JDK 1.2 and later, but will not run on 1.1 VMs.
1.3 Generate class files that will run on VMs in JDK 1.3 and later, but will not run on 1.1 or 1.2 VMs.
1.4 Generate class files that will run on VMs in JDK 1.4 and later, but will not run on 1.1, 1.2 or 1.3 VMs.
1.5 Generate class files that are compatible only with JDK 5 VMs.
5 Synonym for 1.5
... which will allow you to compile code for a certain version of the JVM.
In other words, you can continue to use your 1.6 compiler, just throw these options at it and you can make it generate 1.5 code which Tomcat will be able to handle.
Do i need to match my Java version to the Tomcat environment or to the classes already there?
You need to ensure that your code is compiled with a version (less than or equals) supported by the JVM you are using; but no, this doesn't need to be the same version that the Tomcat code base was built from - the two code bases can be jvm version independent of each other, as long as they are both supported by the jvm you are using.
Instead of recompiling your source to be 1.5 compatible you could update the JDK that Tomcat is using to 1.6.
You should be able to change this by setting the JAVA_HOME environment variable to point to a Java 1.6 install.
I got the same UnsupportedClassVersionError issue a while ago. The root cause there was not my own compiled code, but some libraries that were needed, which were compiled with a newer JDK.