Vert.x java List<Futures> parameterization
Asked Answered
C

3

13

I ran in to a strange issue with Vert.x futures the other day that doesn't break the code but bothers me still.

Future without parameter results in the following warning:

Future is a raw type. References to generic type Future should be parameterized

Add the parameter, problem solved:

Future<YourClassName> future = ...

When dealing with a list of futures, you can also parameterize it just fine:

List<Future<YourClassName>> future = ...

But CompositeFuture.all() can't seem to deal with a parameterized list and forces you to remove the parameter.

Is there any way to make parameterized list of futures work with CompositeFuture or do we just have to ignore that warning? It doesn't break anything but would still be nice to find a solution to get rid of that warning.

Cancroid answered 4/1, 2017 at 15:7 Comment(5)
Can you just cast your list to an unparameterized one when passing it to the all method: CompositeFuture.all((List<Future>) future)? This will probably still give you a warning while casting, but at least outside the method call your List will contain Futures that are parameterized. Apart from that i can only think of getting in contact with the vert.x developers and asking them if they would consider changing the method signature of the all method to accept List<Future<?>>Cancer
@911DidBush you can't do it that way (results in Cannot cast from List<Future<YourClassName>> to List<Future>) error and even if it did work, you would just move the issue from 1 place to another.Cancroid
You're right. I should have checked before if that worked. instead of casting you could however use the copy constructor to convert it CompositeFuture.all(new ArrayList<Future>(future)). You are of course right that this doesn't give you much, but at least you could keep the List fully parameterized outside of the .all call and retain some type safety. Maybe someone else has another idea, but unless vert.x changes the signature of that method you probably have to live with having the raw type + warning at some point in your code.Cancer
Updating the signature to accept a List<? extends Future<?>> would workPyromagnetic
Well it would work in Java, but wildcards are not supported by codegen (CompositeFuture is annotated with @VertxGen to be translated in alternate languages)Pyromagnetic
R
7

On one hand, you can't use CompositeFuture.all() with list of parametrized futures. This is a design decision that the developers took, due to type erasure.
But actually, CompositeFuture.all() doesn't do anything special. So you may have your own interface with static method, that will do the same:

interface MyCompositeFuture extends CompositeFuture {

    // This is what the regular does, just for example
    /*
    static CompositeFuture all(List<Future> futures) {
        return CompositeFutureImpl.all(futures.toArray(new Future[futures.size()]));
    }
    */

    static <T> CompositeFuture all(List<Future<T>> futures) {
        return CompositeFutureImpl.all(futures.toArray(new Future[futures.size()]));
    }
}

And now:

    List<Future<String>> listFuturesT = new ArrayList<>();
    // This works
    MyCompositeFuture.all(listFuturesT);

    List<Future> listFutures = new ArrayList<>();
    // This doesnt, and that's the reason for initial design decision
    MyCompositeFuture.all(listFutures);
Rust answered 5/1, 2017 at 17:3 Comment(0)
P
0

CompositeFuture.all() returns a CompositeFuture, which is itself a Future<CompositeFuture>. So you can assign the result to a Future<CompositeFuture> instead of a raw Future:

Future<String> fut1 = asyncOp1();
Future<Integer> fut2 = asyncOp2();
Future<CompositeFuture> all = CompositeFuture.all(fut1, fut2);
Pyromagnetic answered 4/1, 2017 at 16:31 Comment(1)
I don't see how that's going to help with lists.Cancroid
A
0

[promoting a comment]

Suggestion from @oh-god-spiders in the comments did help in my case.

val futures: util.List[Future[List[CustomClass]]] = asyncCode()
// Doesn’t work
val compositeFuture = CompositeFuture.all(futures)

// Works
val compositeFuture = CompositeFuture.all(new util.ArrayList[Future[_]](futures))
Ancilla answered 27/8, 2020 at 16:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.