I have two jars: CLI.jar and Some.jar; CLI.jar depends on Some.jar.
The major version of CLI.jar classes is 51 (Java 7)
The major version of Some.jar classes is 52(Java 8)
I run java -jar CLI.jar with JRE 1.7 on a host, it gave "Unsupported major.minor version 52.0" error.
I initially thought it was a JRE version issue, but when I switched to another host which also had JRE 1.7, I did not see this error and everything worked fine.
What did I miss here? I am a professional software developer and I know the basics and double checked the JRE version I am using.
JRE 1.7 is not able to run 1.8 class files (and, by extension, JARs that require 1.8 class files). The error you have encountered points that out quite well.
If another computer can run the same JAR file, its Java version is not 1.8. Note that multiple JREs can be installed on one machine.
TL;DR - No, Java byte code is not forward compatible, but it is backwards compatible.
A bit more details:
Generally, files compiled with later Java version can't be run on the earlier Java machines (e.g. classes compiled with Jdk 1.8 can't be run with Jdk 1.7).
However, this statement is false in the way around context. Any version of Jdk is inherently, and by design, backwards compatible1, which means, that Jdk 1.8 can run programs compiled with compiler from Jdk 1.7.
1There is a little catch here. It's rare, but sometimes, later Java versions deprecate and then finally remove some APIs, Frameworks, Libraries or etc. from the build. For example, JavaFX has been removed since Java 11. So, if this kind of situation arises, and you upgrade your Java, you'll just need to manually add missing (in this case - JavaFX) dependency.
Related
I have one question in my mind and I should note that I know the differences between JDK and JRE. I am not a new programmer in Java.
What I would like to ask is in Eclipse I can specify the compilation environment (correct me if I a wrong) in window> Preferences but we can also change it for a specific project.
OK. I added jre and jdk folder in the options. I can use both.
But JRE has no javac (no java compiler) in it. So how it is possible that some projects requires that I need to change to jre1.7 to COMPILE?
I was getting some minor.major version error and setting JRE solved my problem?
How can this be possible?
In fact now I realized something.
Ok the question changes a little.
I saw that these are VM not compiler. I understood.
Does JDK have also JRE in it? so if I specify JDK1.8 I am setting jre1.8 as VM and if I specify JRE1.7 I am setting jre1.7 as VM?
Is it right?
It makes confusions. Why JDK has JRE in it?
JDK has whole JRE (regular Java VM) inside, in order to allow you to run what you will develop with it.
Theoretically someone could make some small-JDK with just tools and without JRE, but it would make a whole lot more confusion as to which tools version run with which JVM version (most JDK tools needs JVM to be run). Look at you, how many people have only this problem? So it is bundled together, tools and JRE as a whole named JDK, thanks to that you have some guarantee that those JRE and tools will work together.
JRE - Java Runtime Environment - allows you to run java programs
JDK - Java Development Kit - allows you to run and develop java programs
JDK = JRE + tools for developer
Also note, that You can choose for the java compilation process two things:
compatibility with source version - this is basically the syntax you are allowed to use.
compatibility with VM version - this is the minimum VM level on which you can run the compiled binaries.
example from your post: If you have compiled something as Java 8, you can't run it on Java 7, this is the minor/major version problem you have. But the opposite (to run something for Java 7 on Java 8) is valid.
in your example JDK8 and JRE7 both are just fully functional VM's, but JDK8 has additionally (in comparison to JRE) development tools inside it.
I want to recompile an old jar file (which was compiled in java 1.2). So that there are no errors i need to compile it in Java 1.2 aswell. But havent found a jdk 1.2 which i can install on windows 7 (and 64bit).
Any suggestions?
thanks in advance!
Yes, you can set the version of compiler at compile time. And compile your java code into old versions of java.
From Oracle article : http://docs.oracle.com/javase/1.5.0/docs/tooldocs/windows/javac.html
Cross-Compilation Example
Here we use javac to compile code that will run on a 1.4 VM.
% javac -target 1.2 -bootclasspath jdk1.2/lib/classes.zip \
-extdirs "" OldCode.java
There are two scenarios, just compiling old code and actually developing for an old JRE.
For just compiling you don't need an old JDK, you can adjust the target language level javac compiles with the -target option (see: https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javac.html) - Although there may be edge cases that may break the compiled code if the compiler decides to select a different overload for a method that does not exist in the old JRE.
For developing old JRE compatible code, you could use above method but you run the risk accidentially using an API that isn't present in the real old JRE. To avoid that problem you need the actual 1.2 API, meaning you need the rt.jar file from a real 1.2 JRE/JDK. This can be added into your project in your IDE (and the current e.g. 1.8 JDK removed). The detailed procedure how to set this up depends on the IDE. Likewise the 1.2 rt.jar can be provided to javac, also using command line switches. Again you need no runnable 1.2 JRE to compile/develop.
I'm trying to consume a third-party API, where I get support for the third party API upto JDK 1.6.
I have other few projects which are built using JDK 1.7 and as part of the product I'm also packaging JRE 1.7.
if compiler compliance level is set to JDK 1.6, compile & run using JDK 1.7 libraries produce same result as of compile & run using JDK 1.6?
Would it be safe to claim support from third-party vendor when compiler compliance level is set to JDK 1.6.
Update:
I presumed that setting compiler level in eclipse is same as setting -source & -target options of javac.
I'm not sure if compiling using JDK 1.7 setting source & target to 6/1.6 is same as compiling in jdk1.6.
The problem is in changes of Java API between versions. There are some classes and methods that are available in Java 7 but not in Java 6 and other way round. The code compiles with Java 7 but it will not run with Java 6 because of missing classes or methods.
Unless you compile with Java 6 JDK, you cannot be 100% sure.
Yes, if you compile with compliance level set to 1.6, it will be able to run on java 6 - compiler will guarantee that. It should be able to run on java 7 as well, since JRE is backward-compatible.
You can actually specify the .class files version compatibility in the "Preferences->Java->Compiler" (project specific), so at worst you are benefitting from a more recent compiler building probably exactly the same bytecode as using JDK 1.6.
"Compliance 1.6" however does not ensure that you get exactly the same result as using JDK1.6, but java standard ensures applications built with 1.6 will run the same on a >= 1.6 JRE.
So if you are really afraid of incompatibilities, build the project (on your CI server I suppose) with a project specific setting 1.6 on a machine with both JRE 1.6 for this one, and 1.7 for other projects, and bundle a 1.7 in your distribution, it is guaranteed to run ok by Sun/oracle/java.
i.e. if the code is built with JDK 1.6, and used by other JDK >= 1.7 code you are fine with respect to versioning. Probably this is the case of many jars you use everyday.
However, building the code that is stamped 1.6, with a real JDK 1.6 is the only sensible thing to do if you are afraid of real world problems (money involved).
So I think then you are safe to "claim support", build in 1.6 and use the jar in 1.7.
In my experience with Eclipse, Compliance level set to Java 5 is not the same as compiling with JDK5. It has allowed Java 6 methods to pass compilation locally when the Installed Java was set to Java 6 and the compliance was set to 5 and then our build failed when the files were checked in.
I have a question regarding the compatibility between different java versions.
On my computer, I have java version "1.7.0_02".
But when I uploaded the .class and embedded it in a webpage it does not work
I get the error:
"Unsupported major.minor version 51.0"
the heading at the top of the console says:
"Java Plug-in 1.6.0_31
Using JRE version 1.6.0_31-b05 Java HotSpot(TM) Client VM"
I would like to ask what is causing the problem. Is it really my java version?
I mean, I visited the site with the computer I compiled the applet in.
You can't use classes compiled to Java 1.7-compatibility class files with an earlier virtual machine, and that "Java Plug-in" error you're seeing says that's exactly what happen.
Two options:
if you're not using Java 1.7 only features, you can compile your code to be compatible with 1.6 JVM's using the option -target 1.6 (see docs here)
Upgrade the Java plug-in your browser is using to 1.7, if possible (I don't think you can do this on OS X, for example). You didn't note what OS and browser you're using so I'm not sure what the upgrade path would be, if any.
Thanks for the answers, I figured out what was wrong.
I started off with both 1.7 and 1.6 on my machine, and it was really confusing me.
The problem was, 1.7 was 64 bit, and 1.6 was 32 bit.
My browser was chrome 32 bit.
I just installed 1.7 32 bit and it was fine
I have both JRE 1.6 and JRE/JDK 1.7 installed on my PC. Do I need both JREs, or can I just keep JRE 1.7 and uninstall JRE 1.6?
I only occasionally have anything to do with the JDK so I'm largely unfamiliar with the Java world. Mostly I just need the JRE for the misc application that needs it.
I do know from PHP web development experience that I need both PHP 5.1 and 5.3 due to deprecation versus enhancement issues, so I was not sure if JRE 1.6 and 1.7 were similar.
Please advise.
Unless you have something that specifically depends on JRE 1.6, you can just keep 1.7.
In general, the Java language is very backwards compatible, so such dependencies on older versions are rare.
There is one special concern with the 6-to-7 leap, though: Oracle changed the licensing model for Java distribution, so you must be aware that OpenJDK 1.7 and Oracle Java 1.7 are not quite the same. So if you have Oracle JDK 1.6, you can't necessarily replace it with OpenJDK 1.7 -- you might have software that depends on the proprietary Oracle-only packages.
JRE 7 should be backward compatible with 6. Since you said JRE, and not JDK, I'd say you're safe to remove JRE 6.
if you have JRE 1.7 then I think you don't need the JRE 1.6. you will get all the features of JRE 1.6 in JRE 1.7
If you have JRE 7u45, you may have issue while reading system properties from JNLP files, in this case better to use java 6