Akka-http: akka.http.javadsl Http.get overloaded on return type - can't use in Java 11

Created on 18 Sep 2018  路  14Comments  路  Source: akka/akka-http

The Akka HTTP introduction :

https://doc.akka.io/docs/akka-http/current/introduction.html

has a code sample:

public class HttpServerStreamRandomNumbersTest extends AllDirectives {

  public static void main(String[] args) throws Exception {
    // boot up server using the route as defined below
    ActorSystem system = ActorSystem.create("routes");

    final Http http = Http.get(system);

which fails to compile on the last line shown above, as the Http.get method is overloaded on the return type. The decompiled Java code is as thus:

public class Http implements Extension {

    // ...

    public static Http get(final ActorSystem system) {
        return Http$.MODULE$.get(var0);
    }

    public static Extension get(final ActorSystem system) {
        return Http$.MODULE$.get(var0);
    }

(The original Scala code is here)

This means the code sample won't even compile on Java. As a workaround, the call to Http.get can be replaced with Http$.MODULE$.get.

The issue is present in V10.1.15, and the Http source code appears looks the same on the trunk (master).

bug 1 - triaged java

All 14 comments

Thanks for reporting, this was mentioned earlier and boils down to how the Scala compiler generates the static forwarders, but I can't see that we ever opened an issue to track it here.

https://discuss.lightbend.com/t/http-get-is-ambiguous-from-java/571/13

In that forum topic the person who reported the problems said it could be worked around by installing the Scala plugin for IntelliJ and that there actually only was a problem in the IDE, not when compiling against it with javac. So that could be worth checking out.

The Scalac issue here: https://github.com/scala/bug/issues/10812 has been merged for Scala 2.13-M4 (so there is not yet a 2.13 release that will help us fixing this)

It seems under Java 11 the problem is not IDE-only: https://github.com/scala/bug/issues/11061. This means that until we get a 2.12.7, our 2.12 artifacts might be broken for Java 11 users.

Thanks for the prompt response. Actually, you're right in that although Intellij complains about the line in question, the code does compile with Java 8. In fact, the IDE itself is also able to compile the code. Sorry, that is my mistake - I aassumed when I looked at the decompiled code that the IDE was correct in highlighting the line as an error.

As such I think it's bit of a non-issue at present. I will close if no-one objects.

But you are not using Java 11, right? I'd vote for keeping it open just for reference until we release a version built with Scala 2.12.7.

But you are not using Java 11

Not yet... still on Java 8.

Happy to leave it open.

https://github.com/akka/akka/issues/25449 was closed, should this one be closed too?

Right, I think we can close this as fixed in ac1a4f3d4773956f6ab0b503112e256b80b67d1b

We might need to put some emphasis on that Java users should use the 2.12 dependency (which we guess is the one they use, but better be clear about it).

We already do this to some extent (on purpose), for example the maven and gradle boxes here: https://akka.io/docs/ and inside of the docs (here for example: https://doc.akka.io/docs/akka-http/current/introduction.html ) but I don't think we have any text saying explicitly "if you use Java, prefer _2.12"

We have noticed this in Alpakka as well. Alpakka master currently does not compile with JDK 11, because of the same error:

[error] /home/martynas/projects/alpakka/doc-examples/src/main/java/csvsamples/FetchHttpEvery30SecondsAndConvertCsvToJsonToKafkaInJava.java:119:1: reference to get is ambiguous
[error]   both method get(akka.actor.ActorSystem) in akka.http.javadsl.Http and method get(akka.actor.ActorSystem) in akka.http.javadsl.Http match
[error]     Http http = Http.get(system);

I tried publishing locally Akka Http master (10.1.5+49-a0a1d667+20181026-1153) and compiling Alpakka with that, but still got the same error.

False alarm. Coursier did not like my locally published version of akka-http. When tried again with regular dependency resolution, it all is fine in Alpakka.

Good to hear, we still have one user reporting problems over in the Akka issue tracker, hopefully we'll get some details about that soon.

FYI, I currently work around this issue using this little Scala object that provides explicit, unambigous bridge methods:

package akka.actor

object ExtensionFactory {
  def bridgeGet[E <: Extension](eId: ExtensionId[E])
                               (implicit actorSystem: ActorSystem): E =
    eId.get(actorSystem)

  def Tcp(implicit actorSystem: ActorSystem): akka.stream.javadsl.Tcp =
    bridgeGet(akka.stream.javadsl.Tcp)

  def Http(implicit actorSystem: ActorSystem): akka.http.javadsl.Http =
    bridgeGet(akka.http.javadsl.Http)

  def Dns(implicit actorSystem: ActorSystem): akka.io.DnsExt =
    bridgeGet(akka.io.Dns)

  //add other Extensions to taste
}

As a bonus, you can now conjure your Http object in Java, using Scala syntax :wink:

import static akka.actor.ExtensionFactory.Http;
//...
final var http = Http(actorSystem);

Now, hopefully really fixed by updating to Scala 2.12.8 in #2305.

Was this page helpful?
0 / 5 - 0 ratings