Open woparry opened 8 years ago
I just started hitting this as well. @woparry did you ever find a workaround?
@chrisbenincasa I'm working on solution. I have it done, respectively, but I'm still uncertain if I don't break something, because my fix is backward incompatible. I solved it using a macro.
What about making the type Option[java.lang.Integer]
to avoid the primitive issue? If you really wanted an Int then you could use .map {_.toInt}
I'm not sure if there is a way to intercept the Injection and do the above automatically.
Unfortunately I discovered there is a problem with binding Scala types. I'm fighting it. The problem I spoke about above is more complicated than I thought that time :disappointed:
I believe there is no way how to intercept getting an instance from the Injector
unless we wrap something. I'm working on it, unfortunately it will become almost completely new library :-)
@tsuckow @chrisbenincasa @woparry Guys, I have bad news. I spent many hours with research and made a big effort to solve this issue, however it cannot be done. Here is why.
The problem lies in Java and Scala type system. In Java, you're unable to create Set<int>
, only objects can be used as generic type parameter (means Set<Integer>
), and even if you would hack the Guice somehow and bind int
(the primitive one), it would throw an error. On the other hand, Scala allows you to create Set[Int]
BUT the Int
is not an object (in resulting bytecode) and therefore it turns into Set[Object]
which is what you see in the error message. The problem is Guice will allow you to bind Set[Int]
because it doesn't count with Scala types.
"Hey, lets change the type on-the-fly to some object and back when injecting" you may say - at least I did. So, when binding, we are able to change the type which is being bound (e.g. by macro defining a custom Manifest
or TypeLiteral
). Unfortunately there is no way (I didn't find any and I considered both nice and ugly solutions) how to intercept the search for existing binding. The problem is we let the injection up to the Guice and it uses Java reflection inside, which cannot be changed. The reflection finds real types for the types being injected and we cannot say "hey, look instead for this" like when binding.
So, for me the outcome is we would have to change the Guice itself. Before that being done, we have to use Java types when using generic type parameters (basically what @tsuckow suggested above, even though it's very sad). BTW the maximum I'm able to do is to create a macro which will cause binding of such type to fail (maybe even in compile-time).
Is there any news on this? From what I understand, the workaround is to use ScalaOptionBinder
?
example:
Note that it works fine if you use @Provides instead
or if T is a reference type