How to generate a default method for a Scala trait?

Any thoughts on how a Scala trait’s method can become a default method? I didn’t find very much documentation on this. My aim is for Java programs to avoid having to provide an implementation of a given trait.

To expand, given the following trait:

  trait Provider[T <: SecretStore] {
    def acquireSecretStore(config: Config)(implicit mat: Materializer, system: ActorSystem): T
  }

I’m assuming that there’s no default method given that there’s no implementation. Here’s the javap output to confirm:

public interface com.github.huntc.streambed.identity.SecretStore$Provider<T extends com.github.huntc.streambed.identity.SecretStore> {
  public abstract T acquireSecretStore(com.typesafe.config.Config, akka.stream.Materializer, akka.actor.ActorSystem);
}

If I then provide an implementation:

  trait Provider[T <: SecretStore] {
    def acquireSecretStore(config: Config)(implicit mat: Materializer, system: ActorSystem): T =
      doAcquireSecretStore(config)
    
    def doAcquireSecretStore(config: Config)(implicit mat: Materializer, system: ActorSystem): T
  }

My, perhaps unreasonable, expectation is that acquireSecretStore will become a default method. Unfortunately not as per the following javap output:

public interface com.github.huntc.streambed.identity.SecretStore$Provider<T extends com.github.huntc.streambed.identity.SecretStore> {
  public static com.github.huntc.streambed.identity.SecretStore acquireSecretStore$(com.github.huntc.streambed.identity.SecretStore$Provider, com.typesafe.config.Config, akka.stream.Materializer, akka.actor.ActorSystem);
  public T acquireSecretStore(com.typesafe.config.Config, akka.stream.Materializer, akka.actor.ActorSystem);
  public abstract T doAcquireSecretStore(com.typesafe.config.Config, akka.stream.Materializer, akka.actor.ActorSystem);
  public static void $init$(com.github.huntc.streambed.identity.SecretStore$Provider);
}

Thanks for any guidance.

On further investigation, I see that javap outputs no flag in relation to default - this is a misunderstanding on my part. I can see that Scala 2.12 lays out the byte code for the default method as per Java 8.

I was curious if it’s easy or possible to discover the release notes for 2.12, see “Traits compile to interfaces” for caveats on Java interop.

Yes it was. The problem was really just down to my misunderstanding of javap in relation to the default qualifier.

Side note: personally I almost never use javap, but asm instead.

$> cat $(which asm)
#!/bin/sh

files="$@"

asm_jar=~/Applications/bin/asm-5.0.2/lib/all/asm-all-5.0.2.jar
asm_main=org.objectweb.asm.util.Textifier

for f in $files; do
  dirname=$(dirname "$f")
  basename=$(basename "$f")
  class=${basename%%.class}
  java -cp $asm_jar $asm_main -debug $f > $dirname/$class.asm
done

And, in many cases, instead of using asm, the output of cfr-decompiler is enough to study a problem (and easier to read than asm).

2 Likes