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.

Didier L
  • 18,905
  • 10
  • 61
  • 103
Rauno
  • 616
  • 8
  • 22
  • Can you just cast your list to an unparameterized one when passing it to the all method: `CompositeFuture.all((List) 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> – OH GOD SPIDERS Jan 04 '17 at 15:50
  • @911DidBush you can't do it that way (results in Cannot cast from `List> to List`) error and even if it did work, you would just move the issue from 1 place to another. – Rauno Jan 04 '17 at 15:53
  • 1
    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))`. 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. – OH GOD SPIDERS Jan 04 '17 at 16:17
  • Updating the signature to accept a `List extends Future>>` would work – tsegismont Jan 05 '17 at 09:55
  • Well it would work in Java, but wildcards are not supported by codegen (CompositeFuture is annotated with @VertxGen to be translated in alternate languages) – tsegismont Jan 05 '17 at 10:02

3 Answers3

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);
Alexey Soshin
  • 16,718
  • 2
  • 31
  • 40
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);
tsegismont
  • 8,591
  • 1
  • 17
  • 27
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))
raevilman
  • 3,169
  • 2
  • 17
  • 29