invoking scala generic classes from java looses generic info

90 Views Asked by At

trying to use in java class defined in scala library. Definition:

final class ScenarioBuilder(...) extends StructureBuilder[ScenarioBuilder]
trait StructureBuilder[B <: StructureBuilder[B]] extends Execs[B] with Feeds[B]

yes, it is Gatling.

my java code:

    public ScenarioBuilder callMyApi(ScenarioBuilder in) {
        return in.feed(myFeeder.asScala())
                .exec(addCookie(Cookie("key", "value")).asScala())
                .exec( http("my api call")
                    .get("/api").asScala());
    }

Idea finds this code correct, but whenever i try to compile it i get this errors:

symbol:   method exec(io.gatling.core.action.builder.ActionBuilder)
location: class java.lang.Object
or
java: incompatible types: java.lang.Object cannot be converted to io.gatling.core.structure.ScenarioBuilder

in other words methods B feed(...) from Feeds[B] and B exec(...) from Execs[B] always return Object and i would expect B to be ScenarioBuilder

the only way to compile and run this code i came up with is this:

    public ScenarioBuilder callMyApi(ScenarioBuilder in) {
        StructureBuilder<ScenarioBuilder> sb = in;
        sb = (StructureBuilder<ScenarioBuilder>) sb.feed(myFeeder.asScala())
                .exec(addCookie(Cookie("key", "value")).asScala());
        return (ScenarioBuilder) sb.exec( http("my api call")
                    .get("/api").asScala());
    }

and it looks disgusting

questions:

  • why does java misses generic info from scala classes?
  • is there better way to utilise scala Gatling api in java?
  • why does IDE finds the first variant correct and compiler does not?

yes, i know there's java api in Gatling though by some reason method make is defined like this:

  public ScenarioBuilder make(
      Function<io.gatling.core.structure.ScenarioBuilder, io.gatling.core.structure.ScenarioBuilder>
          f) {
    return new ScenarioBuilder(f.apply(wrapped));
  }

and to me it is very open question why it is defined this way.

thanks in advance

UPD: java- 1.8, scala- 2.11.8

myFeeder  = listFeeder(Arrays.asList(
                Collections.singletonMap("items", Arrays.asList("Item 1", "Item 2"))
)).circular()

Gatling version - 3.9.0 though the question not about Gatling itself it is mostly about calling scala code with generics from java.

By some reason javac does not see generic info in scala classes, and i wonder why.

As to Gatling i've solved the issue by proper API usage, long story short don't use make methods for construction scenario from different steps exec(ChainBuilder) is the choice.

1

There are 1 best solutions below

2
Stéphane LANDELLE On

Disclaimer: Gatling's author here

is there better way to utilise scala Gatling api in java?

Don't. Gatling's Java DSL wasn't built with interoperability with the Scala DSL in mind. In particular, asScala() is an internal.

Go with either one or the other, but don't mix them together.