Can Java 8 Code Be Compiled to Run on Java 7 Jvm

Can Java 8 code be compiled to run on Java 7 JVM?

No, using 1.8 features in your source code requires you to target a 1.8 VM. I just tried the new Java 8 release and tried compiling with -target 1.7 -source 1.8, and the compiler refuses:

$ javac Test -source 1.8 -target 1.7
javac: source release 1.8 requires target release 1.8

Can an application have both java 7 and java 8 class files and deployed on java 8 JVM

JVM 8 will run class files from all previous compilers. There is no problem for class file to call another compiled on a different compiler. This is evident when you use 3rd party libraries and you don't care which compiler was used to build the jar file.

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.

How to Run Jar on java 7 compiled in java 8 or higher version

You can't change a compiled jar's Java version. You have 2 option in hand.

  1. Compile the Source code using Java-7.

  2. Compile source code using Java-8 but using the following command when target vm version is java-7.

javac "Your java classes" -source 1.8 -target 1.7

Maven: compile Java 7 with JDK8

As stated in comments, it is possible to install multiple JDKs on Jenkins machine (see this answer as an example) and to configure each job to use a specific one.

Besides, you could perfectly compile your Java7 project using Java8 JDK. However, I advise you not to do that. indeed, if backwards compatibility is enforced at language level, you may find some APIs in which bugs you were unaware of, but the libs you use already knew, have been fixed, creating some weird behaviours. As a consequence, your Java7 application would compile using Java8 JDK, but expose bugs at runtime. And it would be the hell of a nightmare to solve those bugs (believe me, my friend, I've met that kind of horrors in a previous common company).

Compiling in Java 7 a method that uses Java 8 types

The only sure way of making your code Java7 AND Java8-compatible is to not use any Java8-specific features, including any classes introduced in Java8 and bytecode versions. The standard engineering practice is to follow the greatest-common-factor principle, which is Java7 and Java7-compatible libraries.

The import trick won't save you anything. JVM will load the class sooner or later, and then you'll either get one exception or another.

Using reflection would work, but you'd end up with horribly ugly and unreadable code with no type safety. On top of it, making your code run differently on different JVM versions can be a pain to debug.

There are other underhanded tricks such as manipulating bytecode or class loading, but this is thin ice and might break when you least need it.

If you absolutely have to use different versions side-by-side, you could separate the code into two parts and run it in separate JVMs. But if you're only writing a library, it's probably easier to make two versions - one for Java7 (also compatible with Java8) and one for Java8.

How can a project support Java 7 despite using Java 8 features

This is not a mistake (as I myself thought). The project indeed uses classes from Java 8. It does not compile with Java 7, and its Maven build doesn't run with Java 7 either.

However, as Java 8-specific features like Lambdas are used nowhere in the source code, it does run with Java 7.

Try creating a Java 7 project, declaring HikariCP as a dependency, and running the following code:

import com.zaxxer.hikari.util.FastList;

public class Main {

public static void main(String[] args) {

FastList<String> fastList = new FastList<>(String.class);
fastList.add("Hello");
System.out.println(fastList);
}
}

It runs successfully. On the other hand, the following code fails:

fastList.removeIf(null);

This is because removeIf() and some other methods use classes from Java 8, and can't therefore run with Java 7. But they all throw UnsupportedOperationException anyway! You may notice that the only class to import Java 8 classes is com.zaxxer.hikari.util.FastList. I'm not sure why they did it.

UPDATE: Just wanted to clarify that the project bytecode's version is 1.7, as can be easily verified with a decompiler or hexdump. Its source code does comply with Java 7 and therefore can be build with

<source>1.7</source>
<target>1.7</target>

as pointed out by @Puce.

On the other hand, it must be compiled with JDK 1.8 so that the Java 8 classes referenced in the source code are available during compilation. Once the code has been compiled, it can run with Java 7 as long as no attempts are made to load a missing Java 8 class (from the java.util.function package in this case).

Can I use a jar, compiled in Java 7 as a dependency in a project that is compiled against Java 6?

Can I use a jar, compiled in Java 7 as a dependency in a project that is compiled for compatibility with Java 6?

Let's unpick this:

  • You have a project that is compiled so that will run on a Java 6 JRE. (Lets suppose that you only use Java 6 APIs in that project.) The .class files for this project must have a classfile format major version less or equal to 50 ... otherwise a Java 6 JRE won't be able to load them.

  • Then you have a dependency that is "compiled in Java 7". That could mean one of two things:

    1. It could have been compiled using a Java 7 tool chain but with a target version of Java 6.

    2. It could have been compiled using a Java 7 tool chain for Java 7.

In both subcases above above, you should be able to use the dependency in your Java 6 project if you run the project on a Java 7 JRE1. A Java 7 JRE can load and run classfiles compiled for Java 6. In one of the subcases, you will be loading classes with two (or more) class version numbers. But that is OK.

On the other hand, if you try to run the code on a Java 6 JRE, then:

  • Subcase 1 will work provided that the Java 7 dependency doesn't make use of any Java 7 (or later) APIs; i.e. it only uses Java standard classes, methods, etc that were present in Java 6 or earlier.

  • Subcase 2 will not work. The Java 6 JRE won't be able to load the dependency. Indeed, if the dependency is static (i.e. the project source code has compile time dependencies on the APIs of the dependent), then the project code won't build ... because the Java 6 compiler should refuse to read the dependency's newer version classfiles.


The most advisable approach is to migrate your project and your execution platform to Java 7. Or better still to Java 8 or Java 11, since Java 7 is EOL'd

If you can't do that, the next best thing would be to avoid using the Java 7 dependency ... until you can upgrade.

If you have customers who insist they you continue to support Java 6, then they are impeding your ability to progress your product line. They should be charged a premium for that.

If you have decided to avoid upgrading your Java platform for internal reasons, this decision is accumulating technical debt ... that your organization will need to "pay down" that debt in the long term.


1 - .... or JDK. A JDK is equivalent to a JRE for the purposes of running code.



Related Topics



Leave a reply



Submit