Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List.sort() NoSuchMethodException 1.6 vs 1.8

Tags:

So i'm a little confused about a change in Java 8 - List.sort - bear with me as the confusion will become apparent.

I have Java 8 JDK installed and running Eclipse with the Project in question set to compile in 1.6 (Windows environment).

Throughout my code I've been doing (Example extends BaseExample):

public static final Comparator<BaseExample> sortByLevel_DESC = new Comparator<NavItemBase>() {...};

List<Example> examples = new ArrayList<Example>();

examples.sort(sortByLevel_DESC);

Despite compiling to 1.6, this worked, and has always worked for me (remember i have Java 8 installed).

However...

Since applying this code to a clients machine - with Java 7 (JRE not JDK) installed (Linux Environment), the exception "java.util.List.sort() NoSuchMethodException" is thrown.

Changing the code from: examples.sort(sortByLevel_DESC); to: Collections.sort(examples, sortByLevel_DESC); resolves the issue.

This leads me to the obvious conclusion that its due to the Java 8 specific code, and due to Java 8 not being installed, it falls over.

But i'm left wondering...

Why eclipse does not complain about Java 8 code when not compiled to Java 8 in the exact same way it will complain if you try to use Lambda expressions while not compiled to Java 8:

examples.stream().filter(e -> e.active()).collect(Collectors.toList());

(e -> e.active()) being the problem:

1.8 source

I would have thought if the method was java 8 only, and i was compiled to 6, then only java 6 code can be executed - I have actually relied on this "project specific setting" to to ensure i don't write any code that is not compatible with the lower version that clients often have, like when i tried the lambda expression.

Perhaps this is actually a problem with Eclipse and not Java? Or perhaps this is NOT the same as lambda expressions at all (in the way it should show an error)?

like image 475
Steve Avatar asked May 30 '17 15:05

Steve


2 Answers

When it comes to working out what methods a class or interface has Eclipse just uses the runtime jars in whatever JRE (or JDK) you have specified for the project in the Java Build Path.

So to check that your code compiles with Java 6 you need to tell Eclipse about a Java 6 JRE in the Preferences in 'Java > Installed JREs'. You then use that JRE for the project (in the 'Library' tab of 'Java Build Path' in the project Properties).

Note that changing the execution environment to Java 1.6 is not enough unless you have an 'perfect match' JRE/JDK installed.

like image 109
greg-449 Avatar answered Sep 25 '22 09:09

greg-449


The issue is definitely with the settings in eclipse, please follow the steps mentioned below to avoid the problem you are facing.

From the menu bar: Project -> Properties -> Java Compiler

Enable project specific settings (checked) Uncheck "use Compliance from execution environment '.... Select the desired "compiler compliance level"

That will allow you to compile "1.6" code using a "1.8" JDK.

If you want to acutally use a 1.6 JDK to produce "1.6" compliant code, then install a suitable 1.6 JDK and tell eclipse where it is installed via:

Window -> preferences -> Installed JREs

And then go back to your project

Project -> properties -> Java Build Path -> libraries

remove the 1.8 system libaries, and: add library... -> JRE System LIbrary -> Alternate JRE -> The JRE you want.

Verify that the correct JRE is on the project's build path, save everything, and enjoy!

Reference : how do I get eclipse to use a different compiler version for Java?

like image 24
Sadiq Ali Avatar answered Sep 22 '22 09:09

Sadiq Ali