Search code examples
interfacejava-8backwards-compatibilityspliterator

Java 8: Spliterator, Iterator, Collection and "default" implemenations in Interfaces (Duplicate methods named spliterator)


Have an interesting situation following the release of Java 1.8.0_25 into the wilds... I believe the root of my issue is related primarily to the new (to 1.8) features of "default" implementations within Interfaces.

The application I am working on is currently targeted at 1.7, which until now has been working well. Until users started updating to 1.8. Now that our users have started updating to 1.8, our hand is forced somewhat into moving to 1.8 support.

We have fixed most of the issues (mainly relating to changes to the JavaFX packages between 1.7 and 1.8) but have one vexing issue remaining.

In my wisdom, or lack thereof, I, some time ago, decided to create a SortedList<T> which extends from AbstractList<T>. Until now, this class has worked fine, however when running on a 1.8 runtime, I get:

Duplicate methods named spliterator with the parameters () and () are inherited 
from the types Collection<T> and Iterable<T>

This, to me, appears to be caused by the "default" implementations in some of the Interfaces that are implemented by AbstractList<T> (my SortedList<T> class does not implement any additional Interfaces other than Serializable). Implementing Serializable is another problem for us, as we need to support deserialisation of SortedList<T> objects, there's no way around that!).

I can get rid of the error by providing an override implementation of spliterator() in my SortedList<T> class. However, if this is built, it no longer runs on a Java 1.7 environment. If I attempt to use SortedList<T> with a 1.7 runtime, I get:

Problem:
Error: Unresolved compilation problems:
The import java.util.Spliterator cannot be resolved
Spliterator cannot be resolved to a type

com.xxxx.xxxx.util.SortedList.<init>(SortedList.java:13) 

This error is pretty obvious, since we've now overridden the spliterator() method in SortedList<T> it needs to include java.util.Spliterator, but that doesn't exist in 1.7.

Ideally we would like to NOT require our customers to update to Java 1.8 if they don't want to.

Is our hand being forced here? Do we need to force users to update to 1.8 and also roll out a new version to any users who have updated to 1.8 by themselves?

Does anyone know a way around this issue?

On a more philosophical note, why has Interface been corrupted with with implementation :-(. Might be a nifty new feature, but they really should have avoided doing anything that would result in breaking changes to existing code, particularly in something so fundamental as lists/collections etc.

Any help or suggestions regarding this predicament would be greatly appreciated.

Cheers,

Mark


Solution

  • Ok, so both of you (@Holger and @assylias) were correct... But, our situation is a little more complicated.

    The environment we're working in is Eclipse 3.8.1 which doesn't support Java 8 (and won't in the future to my knowelege). So we can't just change to a Java 8 compiler to fix the issues.

    Our product is a sizeable Eclipse RCP application. Upgrading our IDE is not currently an option, as there would be major rework involved. We will need to continue to develop under a Java 1.7 environment for this reason.

    If anyone is interested, we have resolved the issue by:

    • Creating fragments (one per Java version that causes issues, so three in our case) for our main plugin. These fragments are configured as patch fragments.
    • Added the Java FX JARs into the fragments (This was done to resolve some issues with Java FX in an earlier release and again for the 1.8.0_25 release).
    • Also in the fragments, in the same namespace as the main plugin, we added the implementation of the SortedList class. The code is identical for each case, but the fragment for Java 8 is compiled specifically with a Java 8 compiler. Overriding the spliterator() method wasn't necessary in the end (when compiled with the Java 8 compiler, it works ok and still compiles with the 1.7 compiler as there is no reference to the Spliterator class anymore).

    This is probably not an ideal solution, but it will work we think :-).

    Thanks for your input & suggestions, much appreciated.