How to setup Eclipse executions environments and projects to be developed for both JAVA 6 and JAVA 7 JREs?
I'm asking this because not all programs that are developed to run over JAVA 6 will run in JAVA 7.
In this situation for example:
I need to use a JAVA API interface, and the JAVA 6 version of this interface is:
public interface Foo {
int getValue();
}
But, the JAVA 7 version of this interface is:
public interface Foo {
int getValue();
int getNewValue();
}
Now, if I code my program like this:
public class FooImp implements Foo {
public static void main( String[] args ) {
}
public int getValue() {
return 1;
}
}
This will run work fine on JRE 6. But, if I run it over JRE 7 it will not work, because the Foo interface requires the operation getNewValue to be implemented.
In this case, what is the best solution, using Eclipse, to code my program and ensure that it will run over JRE 6 and 7? How should I configure the execution environments and run the tests?
Note: At this moment, I'm working like this:
I code my program over JDK 6, to ensure that I'm not using any resourses of JDK 7 that doest exists in JDK 6.
I run the first test over JRE 6.
Then, it export my project and run it over JRE 7.
Note 2: Searching specifically about the java.sql.ResultSet problem, I found this question:
Java 6 Source backward-compatibility and SQL
Now I see that, this problem is common with JDBC, the sourcecode compability is broken with frequency. So, I think that there is no much to discuss here. Thanks all for the answers and the effort.
I don't know if there's an elegant way to do this, but the following could work.
Reorganize and refactor your codebase into two parts:
the part that needs to work in the the Java 6 version of your codebase, and
the other code that is specific to the Java 7 version.
(This is likely to involve creating some Java interfaces with Java 6 and Java 7 specific implementation classes.)
Put the Java 6 and Java 7 code into separate Eclipse Java projects. Set the Eclipse project preferences to select the appropriate Java compliance level for each project; e.g. "Project > Properties > Java Compiler" ...
If you haven't already done so, further refactor the code so that the Java 6 and Java 7 specific classes are dynamically loaded by the core; e.g. using Class.forName(...)
This should allow you to develop the Java 6 and Java 7 parts in the same Eclipse workspace.
You should also be able to use "Run > Run Configurations" and/or "Run > Debug Configurations" to create launchers for Java 6 and Java 7 for in-Eclipse testing.
Note: I've not tried this myself. Please let us know if it works.
Related
I develop and distribute a Java Swing app that uses Apache Batik and JavaCV. I've updated it through java 1.6, 7 and 8. Installers for macOS, Windows and Linux are built with Javapackager. Java 8 is end of support in Jan '19 and I can't find a solution to package and distribute at Java 11, the new LTS version.
Neither JavaCV or Batik produce modular jars but I have managed to repackage them to the point where I can compile and produce a runnable jar at Java 11, app works fine but I can't package it for distribution. I was planning dropping to Java 10 to use javapackager and bundle the 11 runtime from there but it uses jlink to produce a custom runtime, jlink fails because JavaCV and Batik aren't modular. jdeps won't produce a module-info.class to patch in and make them modular due to unsatisfied references in Batik and JavaCV, even though my app works fine without them.
As a result I'm going to have to leave the code base at Java 8, and ship it even though no longer supported.
I know there's a call to create a replacement for javapackager but that won't be there until way after Java 8 is deprecated. And I'd still need Batik and JavaCV projects to refactor and build modular jars to produce a custom runtime.
Can anyone offer any other solution please? Have I missed something? Thanks.
Update: jpackage is now included since JDK 14. The following answer is still applicable for older JDK versions, though.
I've had the same issue. I wanted to use JDK 11, but according to JDK-8212780 JEP 343 is scheduled for JDK 13, so we'll need to wait a little longer. Packaging "native" self-contained applications under Java 8 - 10 wasn't a problem, since the packager was included (at least in the Oracle JDK).
Today I found out about this email and figured I'd like to give it a try: You can see my sample project on github.com/skymatic/javafx11-test, which I successfully packaged using the back-ported jpackager from the JDK development branch.
What I did here:
Created a new HelloWorld project using OpenJDK 11 and OpenJFX 11.
Downloaded the packager and invoke it from the Maven build (note it needs to reside with the JDK and you need to set JAVA_HOME for it to work...)
Bonus: I used jdeps to find out the dependency of my non-modular jar and set the --add-modules parameter to produce a smaller runtime image
Of course it is even easier for modular projects: In this commit to my sample project you can see that I used jpackager's parameters for the module path and main module instead of the classpath and main class.
Here is a link to a GitHub template showing how to use jlink, jpackage and GitHub Actions to produce a JavaFX app and native macOS, Windows, and Linux installers with a small JVM:
https://github.com/wiverson/maven-jpackage-template
Here is a (WIP) version that uses Swing and an embedded Spring Boot server:
https://github.com/wiverson/desktop-spring-boot
So the only solution was to write a wrapper app that uses ProcessBuilder to launch the original apps jar.
Advantage in this is that link can be used to produce the minimal required runtime. Place the jar in the bin directory, then use FPM (https://github.com/jordansissel/fpm) to create an installer.
Sample code for the wrapper
package xyz.arwhite.dslauncher;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class DrumScoreLauncher {
public static void main(String[] args) {
String installHome = System.getProperty("java.home");
String installBin = installHome + File.separator + "bin" + File.separator;
System.out.println("Launching Drum Score Editor from "+installHome);
List<String> cmdLine = new ArrayList<String>();
cmdLine.add(installBin + "java");
cmdLine.add("-jar");
cmdLine.add(installBin + "DrumScoreEditor.jar");
for ( int i = 0; i < args.length; i++ )
cmdLine.add(args[i]);
try {
ProcessBuilder p = new ProcessBuilder(cmdLine);
p.inheritIO();
p.start();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Exiting launcher");
}
}
I am studying object oriented programming in my university and my professors is making an example of streams on java. Unfortunately when I try to run this code it says "println cannot be resolved as a variable" on System.out::println.
It also says to delete the two colons,
while on my professor's eclipse it does work.
This is the code. I am running it on eclipse for ubuntu and my version of java is 1.8 update 91
package stream;
import java.util.Arrays;
public class StreamExamples {
public static void main(String[] args){
String text = "I have no idea what is the problem";
String[] words = text.split(" ");
Arrays.stream(words)
.sorted()
.limit(3)
.forEach(System.out::println);
}
}
Most likely the version of Eclipse you are running does not understand Java 8 syntax.
You need to be running the current Eclipse 4.6 (Neon) or the previous release 4.5 (Mars) for full Java 8 support. You code works fine on Eclipse Neon.
1) Check your build path by right clicking on your project, Build Path > Configure Build Path. The libraries tab should show a JRE with version 1.8, if that is not the case, click Edit and select a JRE that is at least version 8.
2) Check the compiler settings by right clicking on your project, Properties > Java Compiler. Change the Compiler compliance level to 1.8.
I have encountered strange behaviour of nullcheck analysis under Spring tool suite 3.6.2 (Eclipse clon) on windows 7 64bit with Oracle java 8u25. The same maven project with java 7 source compatibility successfully finds NPE error in eclipse, but when I change compilation version in maven to java 1.8, the eclipse is unable to find this error.
My nullcheck analysis configuration in Eclipse (Java->Compiler->Errors/Warnings->Null analysis) is:
Include asserts in null analysis true
Enable annotation based analysis true
NotNull custom annotation is properly set to javax.validation.constraints.NotNull
etc. (everything seems to be OK, as it works under java 7)
My maven pom is here http://pastebin.com/pF1yJSG2 , as mentioned above when java.version in pom is 1.7 null check works, when is 1.8 null check does not work.
Sample source code is:
package test.nullcheckbug.core;
import javax.validation.constraints.NotNull;
public class Program {
/**
* This will fail to compile under java 7 (null analysis works in STS
* 3.6.2). But under java 8 it does not show error in Eclipse Markers -
* static analysis does not work ?!
*
* #return null which is not allowed
*/
#NotNull
public String fail() {
return null;
}
/**
* Simple main.
*
* #param args
* ignored args
*/
public static void main(String[] args) {
}
}
Does anybody know where is problem and how to enable nullcheck to work under jdk 1.8 compatibility ?
EDITED:
Maven seems to be not involved. The same problem simulated on non maven project with the same source code and compatibility level of compiler set to 1.7. Is it a bug ?
EDITED-2:
After more examination I have found that the following difference in annotation makes difference : java.lang.annotation.ElementType.TYPE_USE , when annotation does not have this, the nullcheck is not detected under Java 8, but is detected under Java 7.
But why ?! Why there is so different behaviour ?!
EDITED-3:
After research from MartinLippert and tested by me it seems that nullcheck API has drastically changed between java 7 and java 8. Null detection requires (as seen from version 2.0 of eclipse libraries) java.lang.annotation.ElementType.TYPE_USE, the types #Target(value={METHOD,FIELD,ANNOTATION_TYPE,CONSTRUCTOR,PARAMETER}) are ignored in analysis. SO THE QUESTION IS NOW AS FOLLOWS: WHY NULL ANALYSIS UNDER JAVA 8 REQUIRES AND WORKS ONLY UNDER NEW ELEMENT TYPE ? (I understand that with java 8 it is good to fully utilise new language features, but why was needed to break compatibility ? For example javax.validation #NotNull is now unusable as nullchecking annotation :-((( )
For Eclipse Luna, the development effort was focused on the "typical" combinations:
Java 7 and declaration annotations
Java 8 and type annotations
In this version the combination Java 8 and declaration annotations (what is requested in this question) was not fully implemented.
This has been fixed via https://bugs.eclipse.org/bugs/show_bug.cgi?id=435805
The fix is available in milestone builds towards Eclipse Mars since M4.
OTOH, I can only encourage projects using Java 8 to upgrade to type annotations for much greater expressiveness - enabling much more precise null type checking.
Receiving the below error:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Syntax error, 'for each' statements are only available if source level is 1.5 or greater at Tuto.OneDimArrays.main(OneDimArrays.java:14)
CODE:
public class OneDimArrays {
public static void main(String[] args) {
int[] xabc = new int[5];
xabc[2]=20;
xabc[0]=50;
for(int temp:xabc){
System.out.println(temp);
}
}
}
Please help..
If you are using Eclipse IDE then right click on the project, goto properties, Java Compiler, Check Enable project specific settings and set the Compiler compliance level to greater than 1.5. I solved this issue by setting it to 1.6.
Hope it helps
The error tells you exactly what the problem is. You are using a for-each loop:
for(int temp : xabc)
{
System.out.println(temp);
}
This syntax was only added in Java 1.5, so you appear to be compiling using an earlier version. Without knowing what IDE/environment you're using, I can't tell you how to fix this, but see if you can find a way to compile your code using a more up-to-date version of java.
Note that there is a difference between the JRE (Java Runtime Environment) and the JDK (Java Development Kit). The JRE is used to run java programs on your computer, while the JDK is used to write java programs on your computer. Normally your system only warns you when the JRE is outdated (as most computer users don't write code and probably don't even have the JDK installed). Therefore, even if your JRE is up to date, you won't be able to compile the latest features unless you have the right JDK.
If you're using an old JDK, you can download the latest version here.
If you're using an up-to-date JDK, you will have to change some settings in your project in order to use it.
If for whatever reason neither of these are an option, you can emulate the for-each loop using pre-1.5 language constructs. The most basic approach is described in Pat's answer.
Compile this in a later version of java if you can.
If you are unable to use a later version of java for some reason just use a regular for loop:
for(int i = 0; i < xabc.length; i++) {
int temp = xabc[i];
System.out.println(temp);
}
Try changing compiler compilance level in eclipse:-
click Windows , go to preferences.
select java from the options ,select compiler in drop down menu.
change compiler compilance level to a value 1.5 or greater.
click on the link for reference: https://i.stack.imgur.com/79tvV.png
This is for eclipse.
window -> preferences -> java -> compiler -> configure project specific settings -> double click on created 'project name' -> uncheck 'use compliance from execution environment' -> then select 'compiler compliance level' to 1.5 or higher(best to choose the last level which is maximum and latest)
Done. now apply and close all. re run the program.
I know, this sounds like an old question, which has been asked before(*). But it is a little bit different. I installed a clean system with the newest versions of JDK (7u2) and eclipse (and also AndroidSDK). When I import old projects, I get an error "The method methodName(Parameter) of type Class must override a superclass method".
The #override-tag was there (correctly), because the method overrides a method of an INTERFACE of the superclass. somehow compiler thinks that this tag is just for superclass directly. As far as i know #override is not changed in Java 7 and my project was working properly on 6. Is it a possible bug or compability problem or I am missing something?
(*)Similar problem used to happen, when compiling on JDK5, simply because #override was yet implemented in Java 5. Solution was, of course changing compiler compliance level to 6. But what is it with JDK 7 now?
You shouldn't use JDK 7 for the development. There is a requirement that you have to use JDK 5 or 6.