How to link code that is compatible with other version of java - java

My existing server is running on Java 1.6 and I cant upgrade it.
I need to use some third party jar/api that is compatible with Java 1.8, when I write some code to access its API, eclipse throws
Exception in thread "main" java.lang.UnsupportedClassVersionError: JVMCFRE003 bad major version
How I can proceed now? Not sure if this is duplicate question, if yes please provide some link on this.

The point is: Java virtual machines are not forward compatible.
A .class file that was generated by an "n+1" compiler can't be used on a "n" JVM. (unless you specifically instruct the compiler to compile for older versions of java)
Your choices:
see if you can acquire a version of that library compiled for Java 6
see if you can run your application on a Java 8 JRE (there is no problem running java6 classes on a newer JVM!)
Option 1 can get pretty ugly - as that library might have dependencies on system classes that Java6 doesn't have.

This is not possible to use multiples Java version or even multiples JVMs in the same project
If you really need this API, then you have just few choices, the best one is to upgrade all the project to use Java 1.8

No, you can't use jars compiled under java 1.8 in an environment running at java 1.6

As others have pointed out, you can't do this. However, you may be able to find older versions of the libraries you wish to use, and those libraries may support your particular version of Java. This potentially means that you will be adopting bugs into your software, but that's just how software evolves over time.

If you must use this 3rd party jar,
then you must compile the 3rd party jar using -target 1.6 (to target java 1.6).
Maybe you will get the source and compile it yourself or maybe you will get somebody else (the vendor, perhaps) to compile it.
All other options are:
Upgrade your JVM to Java 8.
Don't use that 3rd party jar. Either write or find one that is compatible with java 6.

Related

running java code in higher versions, compiled in lower java versions

I have java EE artifacts like .jar , .war, .ear files compiled and running in java 1.6 version. i wanted to run them (.ear file [.jar + .war]) in latest java versions like java 1.8.
Which Option would be the best considering moving to new java version.
1) Recompile Code in 1.8 and deploy to Application server
- to be at a little safer.
2) Just deploy to java 1.8
- No Code Compilation required (means .ear file generated using java 1.6). .ear file can be safely deployed to latest java 1.8 version
- probably we wont end-up having runtime issues ?
As this this is a production code base and no developer. Hence No Code changes in either cases, the only change is java version. I prefer going with Option-1, as compilation in higher version of exiting java classes to avoid any runtime issues.
Any thoughts ! or other useful options in this regard.
Thanks
As #Stultuske mentioned you only telling no code changes possible in either cases then your first case not valid one only.
But anyway as per java(Oracle) compatibility specification Java 8 is backward compatible with previous versions for sure no doubt about this except some very rare cases where binary incompatibilities happened.
For more information about this you can refer below stack overflow link --
Can newer JRE versions run Java programs compiled with older JDK versions?
Recently I did a similar thing but we updated the code/dependencies if needed.
I will suggest recompiling the code base first because this will tell you quickly if it or any dependencies don't support the newer Java version. If compilation is successful, then deploy to test environment and do sanity, regression, etc.
I hope you aren't talking about deploying to Production environment directly :)

JAVA Compilation : compile with new JVM version and run on older version

Here is a small explanation of my problem.
I have an application which was compiled with java 1.5. This application is installed on 2000 pc (blockboxes) installed at customer premisses.
The jar of my application is often updated to add new feature and fixes, but for technical reasons, it is not very easy to update the java version, so I must keep using Java 1.5 on those existing machines.
Few months ago, I got a request for a new requirement for this application. To fulfil this task I have added the usage of Hazelcast in this application.
My problem if the following:
- Hazelacast jar file needs Java 1.6 or above, so I must compile my application with 1.6
- The new functionality using hazelcast will only be activated on demand by settings a new parameter. This means that it will not be used in the 2000 already installed blackboxes.
- All new blackboxes will be installed with Jave 1.6 or above to be able to use the Hazealcast functionality.
My problem is that I want to have a unique source code and unique version of my application for old blackboses using Java 1.5 and new blackboxes using 1.6 or above.
In the beginning, my idea was to always compile with version 1.5 and make sure that the new functionality would only be activated in blockboses using java 1.6 or above. This option is not working, because when I compile with 1.5, the compiler complains that Hazelcast jar file needs 1.6 :(
The second option would be to compile with 1.6, but then I cannot be sure that my application will still work properly on all blackboxes using 1.5. :(
I'm would like to know if someone here would know how to solve this kind of problem?
Just let me know if my explanation is not clear ;)
Thanks in advance for your help.
JVM is Backward compatible.You can run almost all code from Java 1 on Java 8.
So the best way is to use the option two. Compile it with 1.6 on some testing machines. And if it works( which most probably will) you don't have to make much change to the application .
You can compile your code to Java 1.5 bytecode using JDK 1.6, just take care of the following:
-source=1.5 and -target=1.5 compiler options
bootclasspath should point to rt.jar from JRE 1.5
See this post for more info: http://www.draconianoverlord.com/2014/04/01/jdk-compatibility.html
The post also recommends simply building your application with older JDK if possible. You need to figure out a different build process and exclude incompatible libraries from the classpath. If you use Maven, consider having two pom.xml files, with an optional parent file.

Compiling the source code in java 1.6.0

teacher said: "your source code should compile in java “1.6.0”. This version is general. I search but cannot find the version.
Which version you think is better in this situation from following site:
http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase6-419409.html
How can we understand witch version of this site is almost the same version that we want
JDK 1.6 update 45 is the latest version for Java 6, so use that.
You don't really need to have exact version. Most of the code you write can be compiled in other version if you are just starting java programming, based on your question it seems you are just beginning.
There won't be too many changes among different updates of one version. So, you don't have to worry about it. If you want to be sure what ever you write can be compiled in 1.6.0, you can take any version of 1.5 and develop your code. This way your code will almost always compile in any version of 1.6. So, go ahead and use Java SE Development Kit 6u45.
Or if you want to just run already compiled code, it is enough if you take latest version of JRE.
When someone says 'your source code should compile in java “1.6.0”' they mean any Java 1.6.0 distribution.
All of the downloads on that page are for Java 1.6.0, so anyone of them will do. But with Java it is best to use the most recent patch release. This is currently Java 1.6.0 patch 45.
For the record, you are pretty much guaranteed that if your code will compile with one patch release of Java 1.6.0, it will compile with all of the. (As in, I am not aware of any case where this won't be true ... modulo the possibility of obscure compiler bugs in earlier patch releases.)

JRE version must be equal to or above JDK version?

I've read that the bytecodes that the JDK generate are generic. What I say is that they only do things like memory mapping, calling, etc... So if that's true, it would mean that I can, for example, if write a program with characteristics of JDK 1.7, I don't need to worry about if it can run in a user with JRE 1.6? (It's an example, it could happen with more exagerated cases).
So, my question is: Can I write a program with new things from 1.7 and run it in 1.6?
Can I write a program with new things from 1.7 and run it in 1.6?
No. Java is not backward compatible.
Note that it is possible to create code compatible with a Java 1.6 JRE in a 1.7 JDK by using the cross-compilation options, but that code can only use the classes, attributes, methods and language features available in version 1.6.
Can I write a program with new things from 1.7 and run it in 1.6?
The short answer is yes, but it is not officially supported. You'll have to resort to some hacks, but you can get it to work if you really want to. I wouldn't recommend doing this in a major project though.
In general bytecode is not backwards compatible because each classfile contains a version field. The JVM will refuse to run classes with a higher version than it was built for (lower versions are of course ok). By default, the javac that comes with Java 7 will create classes with version 51.0, which means they can only be executed by the JVM that comes with Java 7 or higher.
However, this doesn't mean it's impossible if you really want to create Java 6 compatible code. You can tell the compiler to generate classfiles with an earlier version. All this means is that you won't be able to use library and bytecode level features introduced in the new version.
Luckily, version 51.0 did not actually introduce any new bytecode features used by javac. All of the new features in Java 7 are implemented at compile time - the bytecode isn't any different except for the version! This means that any Java 7 class can be made to work as long as it doesn't rely on standard library updates (for example Try With Resources requires library support).
Unfortunately, javac refuses to compile Java 7 to version 50.0. But you can always change the bytecode version field yourself, either manually or with a tool. Since there were no new bytecode features, it will work just fine.
P.S. Memory mapping is down by the VM. There's no bytecode instructions for it. But you have the right idea.

Will compiling for Java 1.5 on Java 1.7 still work?

I've recently moved to Java 7 in one of my projects. I claim that it can run on Java 1.5 simply because there's nothing I depend on that is in Java 6 or 7. However when compiling today I noticed this:
bootstrap class path not set in conjunction with -source 1.5
Google has found little information on this warning. Does this mean that you can't compile to Java 1.5 from Java 1.7?
This Oracle blog explains the warning:
http://blogs.oracle.com/darcy/entry/bootclasspath_older_source
The reason is, that if you fail to set rt.jar for the older platform, then:
If the second step is not taken, javac will dutifully use the old
language rules combined with new libraries, which can result in class
files that do not work on the older platform since references to
non-existent methods can get included.
Does this mean that you can't compile to Java 1.5 from Java 1.7?
No it doesn't. It means that there is a right way and a wrong way to do this ... and you are doing it the wrong way.
The right way to compile for the Java 1.5 on a Java 1.7 JDK is:
Get hold of a copy of the "rt.jar" from Java 1.5 and put it on the compilation bootclasspath.
Compile with -source 1.5 and -target 1.5.
The warning message is telling you that you haven't done the first of these.
The way that you are building right now is implicitly using the 1.7 version of "rt.jar" for the Java runtime APIs. This may work! (Indeed, it should work assuming that you've made no changes to the code since it last built on 1.5.) However, there is a risk that you may accidentally introduce dependencies on classes or methods added in Java 1.6 or 1.7. That would result in runtime errors when you try to run your application on Java 1.5.
You better be setting -source and -target 1.5.
To be really sure that you aren't accidentally incorporating dependencies on newer classes, methods, or fields, use the maven-animal-sniffer plugin or something like it.
--source 1.5 will make sure the source files comply with Java 5 conventions. --target 1.5 will make sure the generated class files comply with Java 5 conventions. Neither of these will protect you from using Java 6 or 7 library methods. You must either compile against the appropriate rt.jar using --bootclasspath, or use something like the animal-sniffer-plugin (if you are using maven) which will inspect everything's type signature, and compare with published profiles.
With the animal-sniffer-plugin, you may be in for a treat, because you can bump into 3rd party libraries that use Java 6 APIs, which may cause your build process to fail given you are pursing Java 5.

Categories