Skip to content

Commit

Permalink
Ensure that Kotlin subclass of QuarkusApplication works properly
Browse files Browse the repository at this point in the history
Fixes: quarkusio#30054
(cherry picked from commit 59e73b7)
  • Loading branch information
geoand authored and gsmet committed Jan 4, 2023
1 parent fb45292 commit 914c623
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.jboss.jandex.ArrayType;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
import org.jboss.jandex.IndexView;
import org.jboss.jandex.MethodInfo;
import org.jboss.jandex.Type;
import org.jboss.logging.Logger;
Expand Down Expand Up @@ -102,6 +103,8 @@ public class MainClassBuildStep {
void.class);
public static final MethodDescriptor CONFIGURE_STEP_TIME_START = ofMethod(StepTiming.class.getName(), "configureStart",
void.class);
private static final DotName QUARKUS_APPLICATION = DotName.createSimple(QuarkusApplication.class.getName());
private static final DotName OBJECT = DotName.createSimple(Object.class.getName());

@BuildStep
void build(List<StaticBytecodeRecorderBuildItem> staticInitTasks,
Expand Down Expand Up @@ -335,7 +338,8 @@ public MainClassBuildItem mainClassBuildStep(BuildProducer<GeneratedClassBuildIt
PackageConfig packageConfig) {
String mainClassName = MAIN_CLASS;
Map<String, String> quarkusMainAnnotations = new HashMap<>();
Collection<AnnotationInstance> quarkusMains = combinedIndexBuildItem.getIndex()
IndexView index = combinedIndexBuildItem.getIndex();
Collection<AnnotationInstance> quarkusMains = index
.getAnnotations(DotName.createSimple(QuarkusMain.class.getName()));
for (AnnotationInstance i : quarkusMains) {
AnnotationValue nameValue = i.value("name");
Expand All @@ -349,7 +353,7 @@ public MainClassBuildItem mainClassBuildStep(BuildProducer<GeneratedClassBuildIt
"More than one @QuarkusMain method found with name '" + name + "': "
+ classInfo.name() + " and " + quarkusMainAnnotations.get(name));
}
quarkusMainAnnotations.put(name, sanitizeMainClassName(classInfo));
quarkusMainAnnotations.put(name, sanitizeMainClassName(classInfo, index));
}

if (packageConfig.mainClass.isPresent()) {
Expand Down Expand Up @@ -380,9 +384,9 @@ public MainClassBuildItem mainClassBuildStep(BuildProducer<GeneratedClassBuildIt
file.close();
}
} else {
Collection<ClassInfo> impls = combinedIndexBuildItem.getIndex()
.getAllKnownImplementors(DotName.createSimple(QuarkusApplication.class.getName()));
ClassInfo classByName = combinedIndexBuildItem.getIndex().getClassByName(DotName.createSimple(mainClassName));
Collection<ClassInfo> impls = index
.getAllKnownImplementors(QUARKUS_APPLICATION);
ClassInfo classByName = index.getClassByName(DotName.createSimple(mainClassName));
MethodInfo mainClassMethod = null;
if (classByName != null) {
mainClassMethod = classByName
Expand All @@ -401,7 +405,7 @@ public MainClassBuildItem mainClassBuildStep(BuildProducer<GeneratedClassBuildIt
generateMainForQuarkusApplication(mainClassName, generatedClass);
mainClassName = MAIN_CLASS;
} else {
ClassInfo classInfo = combinedIndexBuildItem.getIndex().getClassByName(DotName.createSimple(mainClassName));
ClassInfo classInfo = index.getClassByName(DotName.createSimple(mainClassName));
if (classInfo == null) {
throw new IllegalArgumentException("The supplied 'main-class' value of '" + mainClassName
+ "' does not correspond to either a fully qualified class name or a matching 'name' field of one of the '@QuarkusMain' annotations");
Expand All @@ -413,13 +417,28 @@ public MainClassBuildItem mainClassBuildStep(BuildProducer<GeneratedClassBuildIt
return new MainClassBuildItem(mainClassName);
}

private static String sanitizeMainClassName(ClassInfo mainClass) {
private static String sanitizeMainClassName(ClassInfo mainClass, IndexView index) {
String className = mainClass.name().toString();
if (isKotlinClass(mainClass)) {
MethodInfo mainMethod = mainClass.method("main",
ArrayType.create(Type.create(DotName.createSimple(String.class.getName()), Type.Kind.CLASS), 1));
if (mainMethod == null) {
className += "Kt";
ClassInfo classToCheck = mainClass;
boolean hasQuarkusApplicationSuperClass = false;
while (classToCheck != null) {
DotName superName = classToCheck.superName();
if (superName.equals(QUARKUS_APPLICATION)) {
hasQuarkusApplicationSuperClass = true;
break;
}
if (superName.equals(OBJECT)) {
break;
}
classToCheck = index.getClassByName(superName);
}
if (!hasQuarkusApplicationSuperClass) {
className += "Kt";
}
}

}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package `basic-kotlin-application-project`.src.main.kotlin.org.acme

import io.quarkus.runtime.Quarkus
import io.quarkus.runtime.QuarkusApplication
import io.quarkus.runtime.annotations.QuarkusMain

@QuarkusMain(name = "my-main")
class MyMainClass : QuarkusApplication {
override fun run(vararg args: String?): Int {
Quarkus.waitForExit()
return 0
}
}

0 comments on commit 914c623

Please sign in to comment.