import java.io.{File, FileOutputStream} import scala.tools.partest._ import scala.tools.asm import asm.{AnnotationVisitor, ClassWriter, FieldVisitor, Handle, MethodVisitor, Opcodes} import Opcodes._ // This test ensures that we can read JDK 8 (classfile format 52) files, including those // with default methods. To do that it first uses ASM to generate an interface called // HasDefaultMethod. Then it runs a normal compile on Scala source that extends that // interface. Any failure will be dumped to std out. // // By its nature the test can only work on JDK 8+ because under JDK 7- the // interface won't verify. object Test extends DirectTest { override def extraSettings: String = "-opt:l:classpath -usejavacp -d " + testOutput.path + " -cp " + testOutput.path def generateInterface() { val interfaceName = "HasDefaultMethod" val methodType = "()Ljava/lang/String;" val cw = new ClassWriter(0) cw.visit(52, ACC_PUBLIC+ACC_ABSTRACT+ACC_INTERFACE, interfaceName, null, "java/lang/Object", null) def createMethod(flags:Int, name: String) { val method = cw.visitMethod(flags, name, methodType, null, null) method.visitCode() method.visitLdcInsn(s"hello from $name") method.visitInsn(ARETURN) method.visitMaxs(1, 1) method.visitEnd() } createMethod(ACC_PUBLIC, "publicMethod") createMethod(ACC_PUBLIC+ACC_STATIC, "staticMethod") createMethod(ACC_PRIVATE, "privateMethod") cw.visitEnd() val bytes = cw.toByteArray() val fos = new FileOutputStream(new File(s"${testOutput.path}/$interfaceName.class")) try fos write bytes finally fos.close() } def code = """ class Driver extends HasDefaultMethod { println(publicMethod()) println(HasDefaultMethod.staticMethod()) } """ override def show(): Unit = { // redirect err to out, for logging val prevErr = System.err System.setErr(System.out) try { // this test is only valid under JDK 1.8+ testUnderJavaAtLeast("1.8") { generateInterface() compile() Class.forName("Driver").newInstance() () } otherwise { println("hello from publicMethod") println("hello from staticMethod") } } finally System.setErr(prevErr) } }