Here's a question. Suppose I have a Maven project ("A") that pulls in a different Maven project ("B") as a dependency. Both currently use Java 7 to compile. If Project B switches to Java 8, does it force Project A to use Java 8 as well?
If so, is there a way around it - that is, have Project B generate code that Project A can use, without downgrading Project B to Java 7 or upgrading Project A to Java 8? For example, having Project B do some form of "source 1.8 target 1.7", for example. (javac doesn't seem to like that, and I can't find an alternative compiler that will - for example, plexus-compiler-eclipse doesn't support Java 8, but that's another issue altogether; the issue is that of decoupling the generated bytecode from the source version that was used to generate it)
Java is backwards compatible but not forwards compatible. When running a program with a JVM (JRE) version older than what the program was compiled with you will get an error, (the usual Unsupported major.minor version error). Its quite logical. Some new byte code directives might have been introduced in the newer JRE version which the old JRE doesn't know about (especially with all the new Java 8 fancy stuff).
If you have a dependency that is compiled with Java 8 (although I doubt any of the popular dependencies have already been migrated to exclusively use Java 8!) then you have to upgrade your project to use Java 8.
On the other hand, if your project is upgraded to Java 8, then any dependencies, irrespective if they were compiled with Java 8, 7 or 6, will work, due to the backwards compatibility guarantee.
If Project B switches to Java 8, does it force Project A to use Java 8 as well?
Yes, unless you can compile Project B with -source 1.7 -target 1.7, which means you can't use Java 8 features in B.
It has nothing to do with Maven.
Related
For a project I must use Java 6, so I set my eclipse compiler setting to 1.6 (JDK compliance level).
However, I included java.nio.file.Files which is a Java 7 library and I am not getting any complaints. I can ensure that my project specific setting is set to 1.6. I even changed my entire workspace to 1.6 and rebuilt, still no complaints. My colleagues are seeing the complaint on java.nio.files.
Is it becuase I have a jdk7 which is recognizing the java.nio.file.Files even when set to 1.6 spcs?
These are two different things:
the compliance level is about the syntax that you can use when writing Java code (respectively about the Java version number that gets put into compiled byte code)
but the libraries that are available to you depend on the JDK that your project is using!
In other words: if you truly want to restrict your project to Java 6 libraries, you will have to install a Java 6 JDK on your system, and point to that within your project setup ( most likely, your current project setup makes use of a newer-than-Java-6 JDK ).
And the usual disclaimer: Java 6 has had end of life many years ago. You should do whatever you can to upgrade your setup.
JDK compliance level is the level of the Java syntax, not the runtime libraries. It will just prevent you from using language features that were introduced in later versions like try-with-resources which was introduced in JDK 7.
If you want to develop for JDK6, you need to use JDK6.
Java 6 is able to interpret java.nio.file.Files because there is no special Java 7 syntax in contrast to Java 7 and Java 8 (lambda expressions etc.). So you are working on standard libraries. Uninstall Java 7 JDK and install Java 6 JDK and you will that java.nio.file.Files is not available anymore.
I'm reading the document about the new Java 9 module system.
The paragraph 3 Compatibility & migration explains how to migrate code
from Java 8 to Java 9, but says nothing on how "migrate" or run an application
written in Java 9 to pre Java 9 runtimes.
So, if I have, say a JAR application written in a modularity way (every module has a module descriptor) what does happen if I deploy it on, i.e, a JDK 8 runtime?
If your class files are compiled with --release 8 flag, then they should run fine on Java 8. module-info.class files will be ignored by the older JVMs.
If your Java 8 project is maven-based, you can easily configure it to include module-info.java: https://maven.apache.org/plugins/maven-compiler-plugin/examples/module-info.html
Also, take a look at JEP 238 (Multi-Release JAR Files). This allows you to take even more advantages of Java 9 features without breaking compatibility with Java 8.
You cannot start a Java application with a JRE which is less than the one it is built for.
If you just use javac without any special options it will produces classes which do run on JREs equal or bigger than the one of the used JDK.
However javac supports cross compilation. You can use JDK 8 to compile JDK 6 compatible class files. Search for Cross-Compilation Options in the javac docs.
Java Class files contain version information. As with any Java version it should not be possible to execute a class file (or jar) that was compiled with a newer major version than your runtime. See: https://stackoverflow.com/a/4692743/6239524
Fast-ClassPath-Scanner
https://github.com/lukehutch/fast-classpath-scanner using latest version.
On executing(get names of all classes in war which includes all jars and classes)
new FastClasspathScanner(basePackage).scan().getNamesOfAllClasses()
getting:
unsupportedclassversion error with jre 6
Please provide a solution to it or alternative to perform same.
FastClasspathScanner is compiled for java 1.7
When you try to load it in a 1.6 (JRE6) environment it fails with an UnsupportedClassVersionError. This error indicates that the class version (here 1.7) is not compatible with the JVM version (here 1.6).
Java 7 is not backwards compatible with Java 6. You could try to build the FastClasspathScanner library yourself unter 1.6 (not sure if that's possible). Or upgrade your project to Java 7.
Correct, I am the author of FastClasspathScanner, and it's not a goal to get this working with JRE6. However, patches for supporting 1.6 are welcome.
I am using JDK8 on my normal desktop and I have a separate linux box that I am trying to run the Java program on.
The problem I'm running into is that the linux box is running jdk7, so the computer has JRE7 basically that it is running off of. My question is, is it possible to create a jar file in JDK8 that will be compatible with java 7?
I'm using IntelliJ to compile. I tried to compile in 1.7, but it gave an error when I did end up trying to do it. I compile it here:
In 1.8 it works fine to compile, but when I try to compile in 1.7 it doesn't work.
I know the short answer is to update the linux to JRE 8. But I am curious, is there a way to make it backwards compatible? Or is the other answer to simply install JDK7 on the desktop in order for it to run on the linux box using JRE7?
Java programs built with JDK 8 will only run on machines running JRE 8 (or higher).
I found this when trying to compile classes on my local Linux machine (using JDK 8) and deploying to a remote server running JRE 7. The classes just wouldn't work (like you're finding).
If you want to use JRE 8 on linux, I recommend using the oracle-java8-installer package from webupd8team. Installation instructions found here (assuming Debian based distro).
If you want to compile to JDK 7, it's not good enough to only have JDK 8 installed and pick to compile 1.7. You need JDK 7 installed to and restage your project to use JDK 7.
The thing you have to remember is that the difference between JRE/JDK versions is not just the extra features developers can use (e.g Lambda functions) but it's also that the JRE itself is improved (efficiency, garbage collection, etc.).
As a extreme example: If you wrote code that only used JDK 1 features but compiled it using JDK 8, it wouldn't run on a machine running JRE 1 because the Java classes had been compiled with JRE 8 in mind.
Do note though, that if you're Java Code uses only features from JDK 7 or 6 etc., you might think it good practice to compile using the minimum JDK required to allow for compatibility with more machines. Well...you'd have that compatibility but at a cost of using inefficient, out of date, possibly vulnerable compiled classes (At little extreme, but you get my point).
Are you using any new Java 8 features? Because if you are, this means you cannot build the project against the JRE7.
If you are not using any Java 8 features, you can build to Java 7 most easily by downloading the JDK7 and switching the project to use that instead of the JDK8.
You should also set project language level to 1.7 (and module language level(s) as well, if they're different). It's done in Project Structure settings dialog. After that the project should compile.
Note that you shouldn't use any of the APIs that appeared in 1.8, but such usages will most likely be highlighted in the editor.
I have an Eclipse workspace with several Java projects (in Maven); these have dependencies on each other. Recently I started changing just some of the projects to target Java 1.7, and other than resolving some new warnings, nothing is different when compiling.
However, it feels like something might go wrong when I try to run everything. How are class files loaded, and are there any issues, in the following situations?
Is there a problem when a Java 1.6 project depends on a Java 1.7 project? Will the 1.6 VM just refuse to run any 1.7-generated bytecode, or does something weird happen in order to get it to run?
Is there a problem when the reverse happens?
When you have java 1.6 project depends on a Java 1.7 project or java 1.7 project depends on a Java 1.6 project, you should always run your program on the higher version of JVM, which is java 1.7 in this case. In a nutshell, in most cases, class files built with the Java SE 6 compiler will run correctly in Java SE 7. But there are some exceptions. Please see Incompatibilities between Java SE 7 and Java SE 6 for a list of incompatibilities between Java 6 and Java 7.
You can build a project with JDK 1.6 that has some libraries that where generated with 1.7
HOWEVER if some of the code from the project 1.7 needs some JDK 1.7 feature (for example, it uses the new Swing combobox with generics) it won't run on a 1.6 JVM.
So this is something to be very careful about, as you can run into compile time trouble (which is at least not silent) but also runtime trouble. If you can avoid this, it might be better for you.
I have also faced a similar problem and as per my knowledge i don't think that 1.6 VM can run any 1.7-generated bytecode but i think the reverse is possible as 1.7 is a upgraded version of 1.6VM.