Skip to content

Introduce ReversedRedisListView for Java 21 compatibility #2608

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from

Conversation

jxblum
Copy link
Contributor

@jxblum jxblum commented Jun 14, 2023

See #2602

Do not merge yet.

@jxblum jxblum added type: dependency-upgrade A dependency upgrade type: task A general task labels Jun 14, 2023
@jxblum jxblum force-pushed the issue/2602/java21 branch from 0dfe613 to ea8c303 Compare June 14, 2023 17:34

DefaultRedisList<E> redisList = new DefaultRedisList<>(getKey(), getOperations(), this.maxSize);

StreamSupport.stream(this.spliterator(), false)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should honor that reversed is a view of the underlying list. Here, we duplicate the contents of the list by inserting everything that is stored at getKey().

I suggest introducing a package-private ReversedRedisList type where we delegate to this. As our baseline remains Java 17, I think we will have to set up our own implementation without being able to reuse much from the Java libraries.

Looking at the JDK libs, their classes are delegations.

Copy link
Contributor Author

@jxblum jxblum Jul 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this change was intentional and only a temporary hack. I will change this into a proper, view-based abstraction.


@Override
default RedisList<E> reversed() {
throw new UnsupportedOperationException("Not Implemented");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's turn that into a proper implementation using a package-private delegation type. Users looking at the code and finding UOE will have a hard time understanding why this is and whether reversed is supported at all.

Copy link
Contributor Author

@jxblum jxblum Jul 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, methods : [ addFirst(:E), addLast(:E), getFirst(), getLast(), removeFirst(:E), removeLast(:E) ] must be redefined in RedisList<E> since RedisList is an "interface", unlike Java's own LinkedList, which is a "class".

And, since the declarations/definitions of these methods differ between Java's List interface and the Deque interface, where List provides default implementations, and Deque does not, leads to the following compilation error:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.11.0:compile (java-compile) on project spring-data-redis: Compilation failure
[ERROR] /Users/jblum/pivdev/spring-data-redis/src/main/java/org/springframework/data/redis/support/collections/RedisList.java:[40,7] error: types List<E#1> and BlockingDeque<E#2> are incompatible;
[ERROR]   interface RedisList<E#3> inherits abstract and default for addFirst(E#3) from types List and BlockingDeque
[ERROR]   where E#1,E#2,E#3 are type-variables:
[ERROR]     E#1 extends Object declared in interface List
[ERROR]     E#2 extends Object declared in interface BlockingDeque
[ERROR]     E#3 extends Object declared in interface RedisList

Copy link
Contributor Author

@jxblum jxblum Jul 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reversed(), on the other hand, can indeed be encapsulated in a proper type with a supporting implementation.

@jxblum jxblum force-pushed the issue/2602/java21 branch from ea8c303 to c4d99d7 Compare July 6, 2023 18:14
@jxblum jxblum force-pushed the issue/2602/java21 branch 2 times, most recently from ce6fa3a to 38a42cc Compare July 7, 2023 02:00
@jxblum jxblum force-pushed the issue/2602/java21 branch from 38a42cc to 4c9e591 Compare July 7, 2023 02:49
@mp911de mp911de added this to the 3.2 M1 (2023.1.0) milestone Jul 7, 2023
…versed().

* Add delegate methods to avoid using Java 21 API.
* Rename ReversedRedisList to ReversedRedisListView to express its view aspect.
* Refine tests.

Closes spring-projects#2602
@jxblum jxblum force-pushed the issue/2602/java21 branch from 3274747 to 98336a0 Compare July 11, 2023 23:18
Copy link
Member

@mp911de mp911de left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks pretty decent. I left a few thoughts, other than that, I will go ahead and merge this one for Friday.

"Next or previous must be called before set");

try {
DefaultRedisList.this.set(indexOf(this.lastReturnedElement), element);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's resort to using the cursor index. Using the index of the last returned element can hit an equal object in the list (e.g. if the list contains [a a a b c c c] and the last returned element is c).

public boolean addAll(Collection<? extends E> collection) {

@SuppressWarnings("unchecked")
E[] adds = (E[]) collection.toArray();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could have the toArray conversion even after the isEmpty() check

@mp911de mp911de changed the title Test against Java 21 Introduce ReversedRedisListView for Java 21 compatibility Jul 12, 2023
@jxblum
Copy link
Contributor Author

jxblum commented Jul 12, 2023

This looks pretty decent. I left a few thoughts, other than that, I will go ahead and merge this one for Friday.

FYI, I am still in favor of removing all this (copy/pasted) code after we move to a Java baseline >= 21, with preference for the provided Java library & API facilities. I had this working reliably on Java 21 in this commit, and I am not interested in maintaining their code. As such, I see this only as a temporary solution.

Additionally, though I did not try it, Google Guava would provide what we need in this case (for example: here), even though it would add a library dependency.

@jxblum jxblum force-pushed the issue/2602/java21 branch from 98336a0 to 8944101 Compare July 12, 2023 22:45
@jxblum
Copy link
Contributor Author

jxblum commented Jul 12, 2023

Once more, I have made some modifications based on your feedback. SD Redis still builds reliably on Java 17 and Java 21.

@jxblum jxblum force-pushed the issue/2602/java21 branch from 8944101 to 652f916 Compare July 12, 2023 22:55
mp911de pushed a commit that referenced this pull request Jul 13, 2023
See #2602
Original pull request: #2608
mp911de pushed a commit that referenced this pull request Jul 13, 2023
mp911de added a commit that referenced this pull request Jul 13, 2023
Add documentation for generics. Fix remove() and element() methods to adhere to their contract.

See #2602
Original pull request: #2608
@mp911de
Copy link
Member

mp911de commented Jul 13, 2023

That's merged and polished now.

@mp911de mp911de closed this Jul 13, 2023
@mp911de mp911de linked an issue Jul 13, 2023 that may be closed by this pull request
mp911de pushed a commit that referenced this pull request Jul 13, 2023
See #2602
Original pull request: #2608
mp911de pushed a commit that referenced this pull request Jul 13, 2023
mp911de added a commit that referenced this pull request Jul 13, 2023
Add documentation for generics. Fix remove() and element() methods to adhere to their contract.

See #2602
Original pull request: #2608
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: dependency-upgrade A dependency upgrade type: task A general task
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Introduce ReversedRedisListView for Java 21 compatibility
2 participants