FULL PRODUCT VERSION :
java version "9"
Java(TM) SE Runtime Environment (build 9+181)
Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
macOS Sierra 10.12.6
AND
Distributor ID: Ubuntu
Description: Ubuntu 14.04.5 LTS
Release: 14.04
Codename: trusty
A DESCRIPTION OF THE PROBLEM :
When attempting to generate javadocs under JDK 9 the bytecode below causes an exception.
This was discovered as part of adding Kotlin Assertions to the Junit 5 repo.
https://github.com/junit-team/junit5/pull/1001
The project generated JavaDocs for the Java source. I didn't expect that it would attempt to generate documentation for the Kotlin. While running the Javadoc generator the Java compiler seemed to find a problem with the Kotlin Compiler generated bytecode.
This was not a problem with JDK 8.
REGRESSION. Last worked in version 8u131
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Try to generate javadocs under JDK 9 with a class file containing the bytecode below.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
That the JavaDoc generator would correctly generate documentation for the java code and ignore the kotlin bytecode.
ACTUAL -
That the JavaDoc generator tried parsing the kotlin code and threw an exception when it hit code that it didn't know how to interpret.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
javadoc: error - An exception occurred while building a component: TagInfo
(com.sun.tools.javac.code.ClassFinder$BadClassFile: bad class file: /Users/jonathanleitschuh/personal/git/junit5/junit-jupiter-api/build/classes/kotlin/main/org/junit/jupiter/api/SimpleKt$sam$Supplier$i$4924a8ea.class
undeclared type variable: T
Please remove or make sure it appears in the correct subdirectory of the classpath.)
Please file a bug against the javadoc tool via the Java bug reporting page
(http://bugreport.java.com) after checking the Bug Database (http://bugs.java.com)
for duplicates. Include error messages and the following diagnostic in your report. Thank you.
com.sun.tools.javac.code.ClassFinder$BadClassFile: bad class file: /Users/jonathanleitschuh/personal/git/junit5/junit-jupiter-api/build/classes/kotlin/main/org/junit/jupiter/api/SimpleKt$sam$Supplier$i$4924a8ea.class
undeclared type variable: T
Please remove or make sure it appears in the correct subdirectory of the classpath.
at jdk.compiler/com.sun.tools.javac.jvm.ClassReader.badClassFile(ClassReader.java:278)
at jdk.compiler/com.sun.tools.javac.jvm.ClassReader.findTypeVar(ClassReader.java:963)
at jdk.compiler/com.sun.tools.javac.jvm.ClassReader.sigToType(ClassReader.java:670)
at jdk.compiler/com.sun.tools.javac.jvm.ClassReader.sigToType(ClassReader.java:732)
at jdk.compiler/com.sun.tools.javac.jvm.ClassReader.sigToType(ClassReader.java:656)
at jdk.compiler/com.sun.tools.javac.jvm.ClassReader.readType(ClassReader.java:499)
at jdk.compiler/com.sun.tools.javac.jvm.ClassReader$11.read(ClassReader.java:1193)
at jdk.compiler/com.sun.tools.javac.jvm.ClassReader.readAttrs(ClassReader.java:1537)
at jdk.compiler/com.sun.tools.javac.jvm.ClassReader.readMemberAttrs(ClassReader.java:1527)
at jdk.compiler/com.sun.tools.javac.jvm.ClassReader.readMethod(ClassReader.java:2391)
at jdk.compiler/com.sun.tools.javac.jvm.ClassReader.readClass(ClassReader.java:2641)
at jdk.compiler/com.sun.tools.javac.jvm.ClassReader.readClassBuffer(ClassReader.java:2706)
at jdk.compiler/com.sun.tools.javac.jvm.ClassReader.readClassFile(ClassReader.java:2719)
at jdk.compiler/com.sun.tools.javac.code.ClassFinder.fillIn(ClassFinder.java:348)
at jdk.compiler/com.sun.tools.javac.code.ClassFinder.complete(ClassFinder.java:285)
at jdk.compiler/com.sun.tools.javac.code.Symbol.complete(Symbol.java:633)
at jdk.compiler/com.sun.tools.javac.code.Symbol$ClassSymbol.complete(Symbol.java:1314)
at jdk.compiler/com.sun.tools.javac.code.Symbol$ClassSymbol.flags(Symbol.java:1248)
at jdk.compiler/com.sun.tools.javac.code.Symbol$TypeSymbol.getEnclosedElements(Symbol.java:800)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.util.Utils.getItems0(Utils.java:2468)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.util.Utils.getItems0(Utils.java:2463)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.util.Utils.recursiveGetItems(Utils.java:2451)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.util.Utils$16.visitPackage(Utils.java:2436)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.util.Utils$16.visitPackage(Utils.java:2432)
at jdk.compiler/com.sun.tools.javac.code.Symbol$PackageSymbol.accept(Symbol.java:1166)
at java.compiler@9/javax.lang.model.util.AbstractElementVisitor6.visit(AbstractElementVisitor6.java:106)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.util.Utils.getItems(Utils.java:2445)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.util.Utils.getClasses(Utils.java:2182)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.util.Utils.getAllClasses(Utils.java:2355)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.util.Utils.findClassInPackageElement(Utils.java:1047)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.WorkArounds.searchClass(WorkArounds.java:231)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.util.Utils.findClass(Utils.java:1065)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.taglets.ThrowsTaglet.inherit(ThrowsTaglet.java:76)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.util.DocFinder.search(DocFinder.java:257)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.taglets.ThrowsTaglet.inheritThrowsDocumentation(ThrowsTaglet.java:133)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.taglets.ThrowsTaglet.getTagletOutput(ThrowsTaglet.java:164)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.taglets.TagletWriter.genTagOutput(TagletWriter.java:238)
at jdk.javadoc/jdk.javadoc.internal.doclets.formats.html.HtmlDocletWriter.addTagsInfo(HtmlDocletWriter.java:319)
at jdk.javadoc/jdk.javadoc.internal.doclets.formats.html.MethodWriterImpl.addTags(MethodWriterImpl.java:206)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.builders.MethodBuilder.buildTagInfo(MethodBuilder.java:207)
at jdk.internal.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.builders.AbstractBuilder.build(AbstractBuilder.java:157)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.builders.AbstractMemberBuilder.build(AbstractMemberBuilder.java:87)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.builders.AbstractBuilder.buildChildren(AbstractBuilder.java:200)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.builders.MethodBuilder.buildMethodDoc(MethodBuilder.java:151)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.builders.AbstractBuilder.build(AbstractBuilder.java:157)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.builders.AbstractMemberBuilder.build(AbstractMemberBuilder.java:87)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.builders.AbstractBuilder.buildChildren(AbstractBuilder.java:200)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.builders.ClassBuilder.buildMethodDetails(ClassBuilder.java:412)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.builders.AbstractBuilder.build(AbstractBuilder.java:157)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.builders.AbstractBuilder.buildChildren(AbstractBuilder.java:200)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.builders.ClassBuilder.buildMemberDetails(ClassBuilder.java:346)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.builders.AbstractBuilder.build(AbstractBuilder.java:157)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.builders.AbstractBuilder.buildChildren(AbstractBuilder.java:200)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.builders.ClassBuilder.buildClassDoc(ClassBuilder.java:155)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.builders.AbstractBuilder.build(AbstractBuilder.java:157)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.builders.ClassBuilder.build(ClassBuilder.java:125)
at jdk.javadoc/jdk.javadoc.internal.doclets.formats.html.HtmlDoclet.generateClassFiles(HtmlDoclet.java:263)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.AbstractDoclet.generateClassFiles(AbstractDoclet.java:286)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.AbstractDoclet.generateClassFiles(AbstractDoclet.java:268)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.AbstractDoclet.startGeneration(AbstractDoclet.java:207)
at jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.AbstractDoclet.run(AbstractDoclet.java:117)
at jdk.javadoc/jdk.javadoc.doclet.StandardDoclet.run(StandardDoclet.java:72)
at jdk.javadoc/jdk.javadoc.internal.tool.Start.parseAndExecute(Start.java:574)
at jdk.javadoc/jdk.javadoc.internal.tool.Start.begin(Start.java:423)
at jdk.javadoc/jdk.javadoc.internal.tool.Start.begin(Start.java:340)
at jdk.javadoc/jdk.javadoc.internal.tool.Main.execute(Main.java:63)
at jdk.javadoc/jdk.javadoc.internal.tool.Main.main(Main.java:52)
1 error
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
Generated Bytecode from Kotlin:
// ================org/junit/jupiter/api/SimpleKt.class =================
// class version 50.0 (50)
// access flags 0x31
public final class org/junit/jupiter/api/SimpleKt {
// access flags 0x1A
// signature <T:Ljava/lang/Throwable;>(Lkotlin/jvm/functions/Function0<Ljava/lang/String;>;Lkotlin/jvm/functions/Function0<Lkotlin/Unit;>;)TT;
// declaration: T assertThrows<T extends java.lang.Throwable>(kotlin.jvm.functions.Function0<java.lang.String>, kotlin.jvm.functions.Function0<kotlin.Unit>)
private final static assertThrows(Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)Ljava/lang/Throwable;
@Lorg/junit/platform/commons/meta/API;(value=Lorg/junit/platform/commons/meta/API$Usage;.Experimental)
L0
LINENUMBER 20 L0
ICONST_4
LDC "T"
INVOKESTATIC kotlin/jvm/internal/Intrinsics.reifiedOperationMarker (ILjava/lang/String;)V
LDC Ljava/lang/Throwable;.class
ALOAD 1
DUP
IFNULL L1
ASTORE 3
NEW org/junit/jupiter/api/SimpleKt$sam$Executable$i$461cbf59
DUP
ALOAD 3
INVOKESPECIAL org/junit/jupiter/api/SimpleKt$sam$Executable$i$461cbf59.<init> (Lkotlin/jvm/functions/Function0;)V
L1
CHECKCAST org/junit/jupiter/api/function/Executable
ALOAD 0
DUP
IFNULL L2
ASTORE 3
NEW org/junit/jupiter/api/SimpleKt$sam$Supplier$i$4924a8ea
DUP
ALOAD 3
INVOKESPECIAL org/junit/jupiter/api/SimpleKt$sam$Supplier$i$4924a8ea.<init> (Lkotlin/jvm/functions/Function0;)V
L2
CHECKCAST java/util/function/Supplier
INVOKESTATIC org/junit/jupiter/api/Assertions.assertThrows (Ljava/lang/Class;Lorg/junit/jupiter/api/function/Executable;Ljava/util/function/Supplier;)Ljava/lang/Throwable;
DUP
LDC "Assertions.assertThrows(\u2026able), Supplier(message))"
INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkExpressionValueIsNotNull (Ljava/lang/Object;Ljava/lang/String;)V
ARETURN
L3
LOCALVARIABLE message Lkotlin/jvm/functions/Function0; L0 L3 0
LOCALVARIABLE executable Lkotlin/jvm/functions/Function0; L0 L3 1
LOCALVARIABLE $i$f$assertThrows I L0 L3 2
MAXSTACK = 5
MAXLOCALS = 4
@Lkotlin/Metadata;(mv={1, 1, 7}, bv={1, 0, 2}, k=2, d1={"\u0000\u001c\n\u0002\u0008\u0002\n\u0002\u0010\u0003\n\u0000\n\u0002\u0018\u0002\n\u0002\u0010\u000e\n\u0000\n\u0002\u0010\u0002\n\u0002\u0008\u0002\u001a:\u0010\u0000\u001a\u0002H\u0001\"\n\u0008\u0000\u0010\u0001\u0018\u0001*\u00020\u00022\u000e\u0008\u0008\u0010\u0003\u001a\u0008\u0012\u0004\u0012\u00020\u00050\u00042\u000e\u0008\u0008\u0010\u0006\u001a\u0008\u0012\u0004\u0012\u00020\u00070\u0004H\u0087\u0008\u00a2\u0006\u0002\u0010\u0008\u00a8\u0006\u0009"}, d2={"assertThrows", "T", "", "message", "Lkotlin/Function0;", "", "executable", "", "(Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)Ljava/lang/Throwable;", "production sources for module junit-jupiter-api"})
// compiled from: Simple.kt
}
// ================org/junit/jupiter/api/SimpleKt$sam$Executable$i$461cbf59.class =================
// class version 50.0 (50)
// access flags 0x31
public final class org/junit/jupiter/api/SimpleKt$sam$Executable$i$461cbf59 implements org/junit/jupiter/api/function/Executable {
@Lkotlin/Metadata;(mv={1, 1, 7}, bv={1, 0, 2}, k=3)
// access flags 0x1012
private final synthetic Lkotlin/jvm/functions/Function0; function
// access flags 0x1
public <init>(Lkotlin/jvm/functions/Function0;)V
ALOAD 0
INVOKESPECIAL java/lang/Object.<init> ()V
ALOAD 0
ALOAD 1
PUTFIELD org/junit/jupiter/api/SimpleKt$sam$Executable$i$461cbf59.function : Lkotlin/jvm/functions/Function0;
RETURN
MAXSTACK = 2
MAXLOCALS = 2
// access flags 0x1011
public final synthetic execute()V
L0
ALOAD 0
GETFIELD org/junit/jupiter/api/SimpleKt$sam$Executable$i$461cbf59.function : Lkotlin/jvm/functions/Function0;
INVOKEINTERFACE kotlin/jvm/functions/Function0.invoke ()Ljava/lang/Object;
DUP
LDC "invoke(...)"
INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkExpressionValueIsNotNull (Ljava/lang/Object;Ljava/lang/String;)V
POP
RETURN
L1
LOCALVARIABLE this Lorg/junit/jupiter/api/function/Executable; L0 L1 0
MAXSTACK = 3
MAXLOCALS = 1
// compiled from: Simple.kt
}
// ================org/junit/jupiter/api/SimpleKt$sam$Supplier$i$4924a8ea.class =================
// class version 50.0 (50)
// access flags 0x31
public final class org/junit/jupiter/api/SimpleKt$sam$Supplier$i$4924a8ea implements java/util/function/Supplier {
@Lkotlin/Metadata;(mv={1, 1, 7}, bv={1, 0, 2}, k=3)
// access flags 0x1012
private final synthetic Lkotlin/jvm/functions/Function0; function
// access flags 0x1
public <init>(Lkotlin/jvm/functions/Function0;)V
ALOAD 0
INVOKESPECIAL java/lang/Object.<init> ()V
ALOAD 0
ALOAD 1
PUTFIELD org/junit/jupiter/api/SimpleKt$sam$Supplier$i$4924a8ea.function : Lkotlin/jvm/functions/Function0;
RETURN
MAXSTACK = 2
MAXLOCALS = 2
// access flags 0x1011
// signature ()TT;
// declaration: T get()
public final synthetic get()Ljava/lang/Object;
L0
ALOAD 0
GETFIELD org/junit/jupiter/api/SimpleKt$sam$Supplier$i$4924a8ea.function : Lkotlin/jvm/functions/Function0;
INVOKEINTERFACE kotlin/jvm/functions/Function0.invoke ()Ljava/lang/Object;
ARETURN
L1
LOCALVARIABLE this Ljava/util/function/Supplier; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
// compiled from: Simple.kt
}
// ================META-INF/production sources for module junit-jupiter-api.kotlin_module =================
!
org.junit.jupiter.apiSimpleKt
Kotlin Code:
package org.junit.jupiter.api
import org.junit.jupiter.api.function.Executable
import org.junit.platform.commons.meta.API
import java.util.function.Supplier
/**
* Example usage:
* ```kotlin
* val exception = assertThrows<IllegalArgumentException>({ "Should throw an Exception" }) {
* throw IllegalArgumentException("Talk to a duck")
* }
* assertEquals("Talk to a duck", exception.message)
* ```
* @see Assertions.assertThrows
* @since 5.0
*/
@API(API.Usage.Experimental)
inline fun <reified T : Throwable> assertThrows(noinline message: () -> String, noinline executable: () -> Unit): T =
Assertions.assertThrows(T::class.java, Executable(executable), Supplier(message))
---------- END SOURCE ----------