7

I am calling a java method from io.netty.bootstrap.BootStrap that has the following signature:

public <T> B option(ChannelOption<T> option, T value)

I am using the following code to call this method:

b.option(ChannelOption.SO_KEEPALIVE, true);

And this fails to compile with the following error:

Error:(57, 30) type mismatch;
 found   : io.netty.channel.ChannelOption[Boolean]
 required: io.netty.channel.ChannelOption[Any]
Note: Boolean <: Any, but Java-defined class ChannelOption is invariant in type T.
You may wish to investigate a wildcard type such as `_ <: Any`. (SLS 3.2.10)
      b.option(ChannelOption.SO_KEEPALIVE, true); // (4)
                         ^

I don't fully understand what this says, but I understand it's complaining about getting a boolean since it was parametrized with Any instead of Boolean. So I tried the following code and it works:

b.option(ChannelOption.SO_KEEPALIVE, Boolean.box(true));

This compiles and works. Is there a way to make this prettier without the box call?

Can anyone translate that compiler error?

Thank you.

simao
  • 14,491
  • 9
  • 55
  • 66

1 Answers1

8

Java generics are invariant in scala, so you cannot pass a scala Boolean and have the type inferred as you would expect. Explicitly annotating the type should fix it:

b.option[java.lang.Boolean](ChannelOption.SO_KEEPALIVE, true)
Gabriele Petronella
  • 106,943
  • 21
  • 217
  • 235
  • Could you explain a bit more what "java generics are invariant"? Or point me some link where I can read about this. Thank you – simao Nov 11 '14 at 17:06
  • Here's a nice writeup: http://stackoverflow.com/questions/8481301/covariance-invariance-and-contravariance-explained-in-plain-english – Gabriele Petronella Nov 11 '14 at 17:10
  • 1
    Or annotate the true. https://groups.google.com/d/msg/scala-user/T93aNh6PYTA/_7wSBGT3phUJ – som-snytt Nov 11 '14 at 20:18
  • I don't understand how variance matters to type inference here. A Scala Boolean is not a java.lang.Boolean, right? `implicitly[Boolean <:< java.lang.Boolean]` If you need a java boolean you can get it by virtue of autoboxing, but you have to induce the implicit conversion. – som-snytt Nov 11 '14 at 20:37
  • btw, could I define some implicit conversion here instead? – simao Nov 11 '14 at 20:39