Quarkus: Gradle + Kotlin: failure to run or build

Created on 10 Mar 2019  路  83Comments  路  Source: quarkusio/quarkus

I've tried setting up a minimal project with Gradle (5.2.1) and Kotlin (1.3.21) and of course Quarkus (0.11.0), but it failed with many issues.

The complete project is available at https://github.com/jnizet/quarkustest

Here are the various issues I faced during this experiment.

First, the guide about Gradle promotes quite discouraged practices, like applying plugins imperatively rather than using the plugins block, which is necessary to benefit from the generated type-safe extensions when using the Gradle Kotlin DSL. Or using deprecated configurations, like testCompile. I know how to fix that, so it's not a big issue for me, but the Gradle guide could be improved.

The Kotlin guide doesn't explain how to use configure a Kotlin Quarkus project with Gradle. So I had to make guesses based on the Maven instructions and on the source code of the gradle plugin. This could be improved too. I don't have numbers, but Kotlin developers probably use Gradle more than Maven, so having a guide showing the usage of both together would be nice. In particular, one thing that is not obvious is how to do the equivalent of the following:

Maven鈥檚 sourceDirectory and testSourceDirectory build properties are configured to point to Kotlin sources (src/main/kotlin and src/test/kotlin respectively)

Executing ./gradlew tasks to know what the gradle plugin does gives the following:

Quarkus tasks
-------------
add-extension - Adds one of the available quarkus extensions to the current project
list-extensions - Lists the available quarkus extensions
quarkus-build - Quarkus builds a runner jar based on the build jar
quarkus-dev - Creates a native image
quarkus-native - Building a native image

The descriptions don't seem correct and clear to me, especially the one of quarkus-dev task.
Two other things that look weird to me is that the standard Gradle lifecycle and conventions don't seem to be respected:

  • ./gradlew assemble should build the final runnable jar file
  • the generated jar file should be under build/libs, not build/lib

If the Quarkus plugin is applied, but the quarkus gradle extension is not configured, running ./gradlew quarkus-dev gives the following:

Execution failed for task ':quarkus-dev'.
> The `src/main/java` directory is required, please create it.

That's weird: I shouldn't have to create such a directory if using Kotlin only. And BTW, creating the src/main/java directory has absolutely no effect: the same error message is still generated if I do.

So I thought this must have to do with the sourceDirectory, that is changed to src/main/kotlin in the Maven instructions. Reading the Gradle plugin source code, my guess was that I had to add this to the gradle build script:

quarkus {
    setSourceDir("src/main/kotlin")
}

That makes the quarkus-dev task work (sort of): it doesn't throw any error, and gives the same output as when using Java. But navigating to http://localhost:8080/ then gives the following error message:

java.lang.RuntimeException: Unable to invoke Kotlin compiler
    at io.quarkus.kotlin.deployment.KotlinCompilationProvider.compile(KotlinCompilationProvider.java:41)
    at io.quarkus.dev.ClassLoaderCompiler.compile(ClassLoaderCompiler.java:135)
    at io.quarkus.dev.RuntimeUpdatesProcessor.scanForChangedClasses(RuntimeUpdatesProcessor.java:111)
    at io.quarkus.dev.RuntimeUpdatesProcessor.doScan(RuntimeUpdatesProcessor.java:83)
    at io.quarkus.undertow.deployment.devmode.UndertowHotReplacementSetup.handleHotDeploymentRequest(UndertowHotReplacementSetup.java:54)
    at io.quarkus.undertow.deployment.devmode.UndertowHotReplacementSetup$1$1.handleRequest(UndertowHotReplacementSetup.java:35)
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:364)
    at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830)
    at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
    at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1998)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1525)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1416)
    at java.lang.Thread.run(Thread.java:748)

I have no idea how to fix that issue. So I tried to execute the quarkus-build task (after a clean), and it gave the following exception:

io.quarkus.creator.AppCreatorException: Failed to build a runner jar
        at io.quarkus.creator.phase.runnerjar.RunnerJarPhase.provideOutcome(RunnerJarPhase.java:199)
        at io.quarkus.creator.phase.runnerjar.RunnerJarPhase.provideOutcome(RunnerJarPhase.java:70)
        at io.quarkus.creator.outcome.OutcomeResolver.resolve(OutcomeResolver.java:48)
        at io.quarkus.creator.AppCreator.resolveOutcome(AppCreator.java:255)
        at io.quarkus.gradle.tasks.QuarkusBuild.buildQuarkus(QuarkusBuild.java:172)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:103)
        at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:48)
        at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:41)
        at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:28)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:705)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:672)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$4.run(ExecuteActionsTaskExecuter.java:338)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:402)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:394)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:92)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:327)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:312)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.access$200(ExecuteActionsTaskExecuter.java:75)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.execute(ExecuteActionsTaskExecuter.java:158)
        at org.gradle.internal.execution.impl.steps.ExecuteStep.execute(ExecuteStep.java:46)
        at org.gradle.internal.execution.impl.steps.CancelExecutionStep.execute(CancelExecutionStep.java:34)
        at org.gradle.internal.execution.impl.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:69)
        at org.gradle.internal.execution.impl.steps.TimeoutStep.execute(TimeoutStep.java:49)
        at org.gradle.internal.execution.impl.steps.CatchExceptionStep.execute(CatchExceptionStep.java:34)
        at org.gradle.internal.execution.impl.steps.CreateOutputsStep.execute(CreateOutputsStep.java:49)
        at org.gradle.internal.execution.impl.steps.SnapshotOutputStep.execute(SnapshotOutputStep.java:42)
        at org.gradle.internal.execution.impl.steps.SnapshotOutputStep.execute(SnapshotOutputStep.java:28)
        at org.gradle.internal.execution.impl.steps.CacheStep.executeWithoutCache(CacheStep.java:133)
        at org.gradle.internal.execution.impl.steps.CacheStep.lambda$execute$5(CacheStep.java:83)
        at java.util.Optional.orElseGet(Optional.java:267)
        at org.gradle.internal.execution.impl.steps.CacheStep.execute(CacheStep.java:82)
        at org.gradle.internal.execution.impl.steps.CacheStep.execute(CacheStep.java:37)
        at org.gradle.internal.execution.impl.steps.PrepareCachingStep.execute(PrepareCachingStep.java:33)
        at org.gradle.internal.execution.impl.steps.StoreSnapshotsStep.execute(StoreSnapshotsStep.java:38)
        at org.gradle.internal.execution.impl.steps.StoreSnapshotsStep.execute(StoreSnapshotsStep.java:23)
        at org.gradle.internal.execution.impl.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:95)
        at org.gradle.internal.execution.impl.steps.SkipUpToDateStep.lambda$execute$0(SkipUpToDateStep.java:88)
        at java.util.Optional.map(Optional.java:215)
        at org.gradle.internal.execution.impl.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:52)
        at org.gradle.internal.execution.impl.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:36)
        at org.gradle.internal.execution.impl.DefaultWorkExecutor.execute(DefaultWorkExecutor.java:34)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:109)
        at org.gradle.api.internal.tasks.execution.ResolveIncrementalChangesTaskExecuter.execute(ResolveIncrementalChangesTaskExecuter.java:84)
        at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:91)
        at org.gradle.api.internal.tasks.execution.ResolveBeforeExecutionStateTaskExecuter.execute(ResolveBeforeExecutionStateTaskExecuter.java:74)
        at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
        at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:109)
        at org.gradle.api.internal.tasks.execution.ResolveBeforeExecutionOutputsTaskExecuter.execute(ResolveBeforeExecutionOutputsTaskExecuter.java:67)
        at org.gradle.api.internal.tasks.execution.ResolveAfterPreviousExecutionStateTaskExecuter.execute(ResolveAfterPreviousExecutionStateTaskExecuter.java:46)
        at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:93)
        at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:45)
        at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:94)
        at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
        at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
        at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
        at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:63)
        at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:49)
        at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:46)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:416)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:406)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:102)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
        at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:46)
        at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:43)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:355)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:343)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:336)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:322)
        at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker$1.execute(DefaultPlanExecutor.java:134)
        at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker$1.execute(DefaultPlanExecutor.java:129)
        at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:202)
        at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:193)
        at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:129)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
        at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
        at java.lang.Thread.run(Thread.java:748)
Caused by: io.quarkus.creator.AppCreatorException: Failed to augment application classes
        at io.quarkus.creator.phase.augment.AugmentPhase.doProcess(AugmentPhase.java:398)
        at io.quarkus.creator.phase.augment.AugmentPhase.provideOutcome(AugmentPhase.java:196)
        at io.quarkus.creator.phase.augment.AugmentPhase.provideOutcome(AugmentPhase.java:82)
        at io.quarkus.creator.outcome.OutcomeResolver.resolve(OutcomeResolver.java:48)
        at io.quarkus.creator.AppCreator.resolveOutcome(AppCreator.java:255)
        at io.quarkus.creator.phase.runnerjar.RunnerJarPhase.provideOutcome(RunnerJarPhase.java:197)
        ... 89 more
Caused by: org.jboss.builder.BuildException: Build failure: Build failed due to errors
        [error]: Build step io.quarkus.deployment.steps.SubstrateSystemPropertiesBuildStep#writeNativeProps threw an exception: java.lang.IllegalStateException: java.io.FileNotFoundException: /Users/jb/projects/quarkustest/build/classes/java/main:/Users/jb/projects/quarkustest/build/classes/kotlin/main/native-image.properties (No such file or directory)
        at org.jboss.builder.Execution.run(Execution.java:123)
        at org.jboss.builder.BuildExecutionBuilder.execute(BuildExecutionBuilder.java:136)
        at io.quarkus.deployment.QuarkusAugmentor.run(QuarkusAugmentor.java:102)
        at io.quarkus.creator.phase.augment.AugmentPhase.doProcess(AugmentPhase.java:316)
        ... 94 more
Caused by: java.lang.IllegalStateException: java.io.FileNotFoundException: /Users/jb/projects/quarkustest/build/classes/java/main:/Users/jb/projects/quarkustest/build/classes/kotlin/main/native-image.properties (No such file or directory)
        at io.quarkus.deployment.ExtensionLoader$1.execute(ExtensionLoader.java:444)
        at org.jboss.builder.BuildContext.run(BuildContext.java:413)
        at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
        at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1998)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1525)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1416)
        at java.lang.Thread.run(Thread.java:748)
        at org.jboss.threads.JBossThread.run(JBossThread.java:479)
Caused by: java.io.FileNotFoundException: /Users/jb/projects/quarkustest/build/classes/java/main:/Users/jb/projects/quarkustest/build/classes/kotlin/main/native-image.properties (No such file or directory)
        at java.io.FileOutputStream.open0(Native Method)
        at java.io.FileOutputStream.open(FileOutputStream.java:270)
        at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
        at java.io.FileOutputStream.<init>(FileOutputStream.java:162)
        at io.quarkus.deployment.steps.SubstrateSystemPropertiesBuildStep.writeNativeProps(SubstrateSystemPropertiesBuildStep.java:45)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at io.quarkus.deployment.ExtensionLoader$1.execute(ExtensionLoader.java:435)
        ... 7 more

At that point, I'm stuck.

aregradle arekotlin kinbug

Most helpful comment

@stalep suggestion: you guys might want to have a label for issues related to kotlin.

All 83 comments

I've debugged the KotlinCompilationProvider class and found out that this is the cause of the Unable to invoke Kotlin compiler error.

I'm trying to figure out how to fix it.

java.lang.NoClassDefFoundError: Could not initialize class org.jetbrains.kotlin.com.intellij.openapi.util.io.FileUtil
    at org.jetbrains.kotlin.com.intellij.openapi.application.PathManager.extractRoot(PathManager.java:399)
    at org.jetbrains.kotlin.com.intellij.openapi.application.PathManager.getResourceRoot(PathManager.java:364)
    at org.jetbrains.kotlin.utils.PathUtil.getResourcePathForClass(PathUtil.kt:143)
    at org.jetbrains.kotlin.utils.PathUtil.getPathUtilJar(PathUtil.kt:138)
    at org.jetbrains.kotlin.utils.PathUtil.getKotlinPathsForCompiler(PathUtil.kt:98)
    at org.jetbrains.kotlin.cli.common.CLICompiler.computeKotlinPaths(CLICompiler.java:212)
    at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.java:85)
    at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.java:52)
    at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:93)
    at io.quarkus.kotlin.deployment.KotlinCompilationProvider.compile(KotlinCompilationProvider.java:35)
    at io.quarkus.dev.ClassLoaderCompiler.compile(ClassLoaderCompiler.java:135)
    at io.quarkus.dev.RuntimeUpdatesProcessor.scanForChangedClasses(RuntimeUpdatesProcessor.java:111)
    at io.quarkus.dev.RuntimeUpdatesProcessor.doScan(RuntimeUpdatesProcessor.java:83)
    at io.quarkus.undertow.deployment.devmode.UndertowHotReplacementSetup.handleHotDeploymentRequest(UndertowHotReplacementSetup.java:54)
    at io.quarkus.undertow.deployment.devmode.UndertowHotReplacementSetup$1$1.handleRequest(UndertowHotReplacementSetup.java:35)
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:364)
    at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830)
    at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
    at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1998)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1525)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1416)
    at java.lang.Thread.run(Thread.java:748)

I've submitted the PR https://github.com/quarkusio/quarkusio.github.io/pull/135 to improve the Gradle guide.

That NoClassDefFound is very weird..

@jnizet @renannprado Do you have the final Gradle config that causes the problem?

Is there any difference in the dependency tree between the Maven and the Gradle projects?

@geoand Here's output of dependencies task, I didn't compare with maven though.

dependencies.txt

Gradle version:

------------------------------------------------------------
Gradle 5.2.1
------------------------------------------------------------

Build time:   2019-02-08 19:00:10 UTC
Revision:     f02764e074c32ee8851a4e1877dd1fea8ffb7183

Kotlin DSL:   1.1.3
Kotlin:       1.3.20
Groovy:       2.5.4
Ant:          Apache Ant(TM) version 1.9.13 compiled on July 10 2018
JVM:          1.8.0_202 (Oracle Corporation 25.202-b08-jvmci-0.55)
OS:           Linux 4.9.0-8-amd64 amd64

Java version:

openjdk version "1.8.0_202"
OpenJDK Runtime Environment (build 1.8.0_202-20190206132807.buildslave.jdk8u-src-tar--b08)
OpenJDK GraalVM CE 1.0.0-rc13 (build 25.202-b08-jvmci-0.55, mixed mode)

@renannprado Thanks! Do you have a Gradle project that you could include so I can debug use locally and debug?

@geoand A complete project reproducing the issue is available at https://github.com/jnizet/quarkustest

@jnizet Thanks! I will check it out in a few hours

@geoand I was using @jnizet's setup as well

First of all it was weird that the compilation was being triggered even for the first request.
I fixed that problem by setting:

quarkus {
    setSourceDir("src/main/kotlin")
    setOutputDirectory("build/classes/kotlin/main")
}

Now the compilation problem obviously remains and I'll continue to look into it

I was able to get this work by adding the following dependencies:

implementation("org.jetbrains.intellij.deps:trove4j:1.0.20181211")
implementation("org.jetbrains.kotlin:kotlin-script-runtime:1.3.21")

It seems like for some reason the process that creates the devjar does not resolve the correct dependencies (for the Kotlin compiler) when launched via the Gradle plugin - cc @aloubyansky.

The fact that there is work actively being done for bootstrapping makes me reluctant to dig into this more. It's probably best that we reexamine this once that works lands.

@geoand do you know anything about the native-image.properties file not found error?
Both quarkus-native and quarkus-build tasks are failing with gradle.

@renannprado I do not unfortunately, I haven't had time to look into that yet, but hopefully I will soon enough.

@renannprado @jnizet setting setOutputDirectory("build/classes/kotlin/main") also fixes the issue with native-image.properties issue.
However in order for quarkus-build to work, it is mandatory to specify the version on the quarkus deps (even though the issue uses a BOM) and make those quarkus deps compileOnly

@geoand I've tried to put the version in all quarkus dependencies and run build-native and move to compileOnly, still it doesn't work. Would you share your working example?

Could it be it's trying to open the tar.gz file as it was a zip?

TL;DR:

Caused by: java.lang.RuntimeException: Error opening zip stream from artifact: /home/user/.gradle/caches/modules-2/files-2.1/com.oracle.substratevm/svm-hosted-native-linux-amd64/1.0.0-rc12/647c9d48ae91b1d2cd88781372912abdf8f6d4a2/svm-hosted-native-linux-amd64-1.0.0-rc12.tar.gz

Full stacktrace:

io.quarkus.creator.AppCreatorException: Failed to build a runner jar at io.quarkus.creator.phase.runnerjar.RunnerJarPhase.provideOutcome(RunnerJarPhase.java:199) at io.quarkus.creator.phase.runnerjar.RunnerJarPhase.provideOutcome(RunnerJarPhase.java:70) at io.quarkus.creator.outcome.OutcomeResolver.resolve(OutcomeResolver.java:48) at io.quarkus.creator.AppCreator.resolveOutcome(AppCreator.java:255) at io.quarkus.gradle.tasks.QuarkusBuild.buildQuarkus(QuarkusBuild.java:172) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:103) at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:48) at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:41) at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:28) at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:705) at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:672) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$4.run(ExecuteActionsTaskExecuter.java:338) at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:402) at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:394) at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165) at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250) at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158) at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:92) at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:327) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:312) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.access$200(ExecuteActionsTaskExecuter.java:75) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.execute(ExecuteActionsTaskExecuter.java:158) at org.gradle.internal.execution.impl.steps.ExecuteStep.execute(ExecuteStep.java:46) at org.gradle.internal.execution.impl.steps.CancelExecutionStep.execute(CancelExecutionStep.java:34) at org.gradle.internal.execution.impl.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:69) at org.gradle.internal.execution.impl.steps.TimeoutStep.execute(TimeoutStep.java:49) at org.gradle.internal.execution.impl.steps.CatchExceptionStep.execute(CatchExceptionStep.java:34) at org.gradle.internal.execution.impl.steps.CreateOutputsStep.execute(CreateOutputsStep.java:49) at org.gradle.internal.execution.impl.steps.SnapshotOutputStep.execute(SnapshotOutputStep.java:42) at org.gradle.internal.execution.impl.steps.SnapshotOutputStep.execute(SnapshotOutputStep.java:28) at org.gradle.internal.execution.impl.steps.CacheStep.executeWithoutCache(CacheStep.java:133) at org.gradle.internal.execution.impl.steps.CacheStep.lambda$execute$5(CacheStep.java:83) at java.util.Optional.orElseGet(Optional.java:267) at org.gradle.internal.execution.impl.steps.CacheStep.execute(CacheStep.java:82) at org.gradle.internal.execution.impl.steps.CacheStep.execute(CacheStep.java:37) at org.gradle.internal.execution.impl.steps.PrepareCachingStep.execute(PrepareCachingStep.java:33) at org.gradle.internal.execution.impl.steps.StoreSnapshotsStep.execute(StoreSnapshotsStep.java:38) at org.gradle.internal.execution.impl.steps.StoreSnapshotsStep.execute(StoreSnapshotsStep.java:23) at org.gradle.internal.execution.impl.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:95) at org.gradle.internal.execution.impl.steps.SkipUpToDateStep.lambda$execute$0(SkipUpToDateStep.java:88) at java.util.Optional.map(Optional.java:215) at org.gradle.internal.execution.impl.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:52) at org.gradle.internal.execution.impl.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:36) at org.gradle.internal.execution.impl.DefaultWorkExecutor.execute(DefaultWorkExecutor.java:34) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:109) at org.gradle.api.internal.tasks.execution.ResolveIncrementalChangesTaskExecuter.execute(ResolveIncrementalChangesTaskExecuter.java:84) at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:91) at org.gradle.api.internal.tasks.execution.ResolveBeforeExecutionStateTaskExecuter.execute(ResolveBeforeExecutionStateTaskExecuter.java:74) at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58) at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:109) at org.gradle.api.internal.tasks.execution.ResolveBeforeExecutionOutputsTaskExecuter.execute(ResolveBeforeExecutionOutputsTaskExecuter.java:67) at org.gradle.api.internal.tasks.execution.ResolveAfterPreviousExecutionStateTaskExecuter.execute(ResolveAfterPreviousExecutionStateTaskExecuter.java:46) at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:93) at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:45) at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:94) at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57) at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56) at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36) at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:63) at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:49) at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:46) at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:416) at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:406) at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165) at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250) at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158) at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:102) at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36) at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:46) at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:43) at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:355) at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:343) at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:336) at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:322) at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker$1.execute(DefaultPlanExecutor.java:134) at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker$1.execute(DefaultPlanExecutor.java:129) at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:202) at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:193) at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:129) at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63) at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55) at java.lang.Thread.run(Thread.java:748) Caused by: io.quarkus.creator.AppCreatorException: Failed to augment application classes at io.quarkus.creator.phase.augment.AugmentPhase.doProcess(AugmentPhase.java:398) at io.quarkus.creator.phase.augment.AugmentPhase.provideOutcome(AugmentPhase.java:196) at io.quarkus.creator.phase.augment.AugmentPhase.provideOutcome(AugmentPhase.java:82) at io.quarkus.creator.outcome.OutcomeResolver.resolve(OutcomeResolver.java:48) at io.quarkus.creator.AppCreator.resolveOutcome(AppCreator.java:255) at io.quarkus.creator.phase.runnerjar.RunnerJarPhase.provideOutcome(RunnerJarPhase.java:197) ... 89 more Caused by: java.lang.RuntimeException: Error opening zip stream from artifact: /home/user/.gradle/caches/modules-2/files-2.1/com.oracle.substratevm/svm-hosted-native-linux-amd64/1.0.0-rc12/647c9d48ae91b1d2cd88781372912abdf8f6d4a2/svm-hosted-native-linux-amd64-1.0.0-rc12.tar.gz at io.quarkus.creator.phase.augment.AugmentPhase.openZipFile(AugmentPhase.java:431) at io.quarkus.creator.phase.augment.AugmentPhase.doProcess(AugmentPhase.java:236) ... 94 more Error: Invalid or corrupt jarfile /home/user/dev/private/quarkus-test/build/quarkus-test-runner.jar

@renannprado Yeah, I got the same error as well and to be honest I though it was a corrupted cache on my machine - obviously with this happening to you as well that's not the case.
But at least that error happens much further down in the process.
I am not sure what the problem is but I'll look into it soon I hope.

One more step down the rabbit hole is to add:

    compileOnly("com.oracle.substratevm:svm:1.0.0-rc12") {
        exclude("*", "*")
    }

and make all quarkus deps exclude the svm dependency like so:

    compileOnly("io.quarkus:quarkus-arc:0.11.0") {
        exclude("com.oracle.substratevm", "svm")
    }

I saw another problem after that but I'm not sure it's just me or if it's a general problem.

Again am reluctant to go any deeper at this point since the changes to bootstrapping and dependency resolution that are in the pipeline might fix things

It seems like the Error opening zip stream from artifact failure will be fixed by #1391

@geoand with this fix we will still need all the stuff we discussed so far + upgrading quarkus dependencies? or there something else we will be able to avoid?

@renannprado No, it will only fix the Error opening zip stream from artifact error, everything else we have discussed still applies (I updated my comment to make that more clear)

@renannprado @geoand FYI Gradle QuickStart (with Java, not Kotlin) in https://github.com/quarkusio/quarkus-quickstarts/issues/75 ...

I've reopened my PR regarding the Gradle documentation on this repo (#1403), without using the BOM, and using compileOnly dependencies instead of implementation dependencies.

This looks very counter-intuitive to me: given that quarkus-resteasy is what brings resteay to a project, and given that resteasy is needed at compile-time and at runtime, it is really weird to make it a compileOnly dependency. compileOnly is normally used for dependencies whish are only needed at compile-time (like for example annotations that are used by a static code analysis tool like FindBugs).

@jnizet @renannprado once you've figured this all out :smile: what could perhaps be useful for future automated non-regression would be if you were motivated to contribute a Gradle + Kotlin Quick Start (over in https://github.com/quarkusio/quarkus-quickstarts) or an Integration Test for Gradle + Kotlin here in this main quarkus repo (better).

Just FYI, in case you're interested, there is something like that for the Maven integration in https://github.com/quarkusio/quarkus/tree/master/devtools/maven/src/test/resources/projects/classic-kotlin, and in #1405 for #1396 I'm proposing an IT for Gradle (non-Kotlin, but you could follow-up to and extend that, if this topic is dear to you).

I've reopened my PR regarding the Gradle documentation on this repo (#1403), without using the BOM, and using compileOnly dependencies instead of implementation dependencies.

This looks very counter-intuitive to me: given that quarkus-resteasy is what brings resteay to a project, and given that resteasy is needed at compile-time and at runtime, it is really weird to make it a compileOnly dependency. compileOnly is normally used for dependencies whish are only needed at compile-time (like for example annotations that are used by a static code analysis tool like FindBugs).

It takes getting used to for sure, but like I said the build process uses these dependencies to create the custom jars. Also this _might_ be changing in the future

With the latest changes in master (which will be available in the next release scheduled for today) Quarkus now also runs the native/substrate tests with Gradle. - you however need to separate the substrate tests and the quarkus tests in different folders since Quarkus do not allow them being run in the same session.
We have also updated the documentation to reflect this. Also the recommended configuration for dependencies is implementation for artifacts needed for both compile and test.
I haven't tested Kotlin yet though, so I can not provide any updates on that.

馃憢 everyone !

I'm trying to give gradle & kotlin a try (quarkus-dev would be enough for me atm) and am a bit surprised by a piece of your comment @jnizet

That makes the quarkus-dev task work (sort of): it doesn't throw any error, and gives the same output as when using Java.

It doesn't for me :( (using your github reproducer here : https://github.com/jnizet/quarkustest
It indeed gives the same output as in Java, but doesn't "hang infinitely" as it would for Java.
The process simply ends with "Build succeeded".
And actually the produced -dev.jar jar file doesn't contain anything but the META-INF directory.

Is it the same for you ?

@aesteve Hi.

Have you tried applying the various fixes I documented in this issue?

I did indeed.
But my issue is not related to quarkus-native or quarkus-build but more to quarkus-dev which seems to be working for @jnizet 's project, but not for me when I'm cloning his repository :\

Here's a repo containing my experiments if you're interested : https://github.com/aesteve/quarkus-kotlin-todobackend/blob/master/build.gradle.kts

:)

I remember that I had quarkus-dev working (it seems like one of my first comments was about that). If I have time in the coming days, I will look into your sample and try to figure out what is going on

Can you please test with version 0.12 of Quarkus?

@stalep I've tried with success, BUT there's one kinda obscure issue here I think.

I've published my repository as well, which is not having a lot of differences with the one from the op.
I didn't dig further, but the catch is the following: if you return an object from the REST endpoint, the build breaks. If you simply return a string, everything works just fine.

here's the repo and a link to where you should change to break the native compilation and get the below error: https://github.com/renannprado/quarkus-test/blob/47d67ddbbdba9f9033c8bb4ef1dcd51236a28c63/src/main/kotlin/quarkus/test/GreetingResource.kt#L13

graalvm version:

openjdk version "1.8.0_202"
OpenJDK Runtime Environment (build 1.8.0_202-20190206132807.buildslave.jdk8u-src-tar--b08)
OpenJDK GraalVM CE 1.0.0-rc14 (build 25.202-b08-jvmci-0.56, mixed mode)

here's the stacktrace of the error:

Error: unsupported features in 2 methods
Detailed message:
Error: com.oracle.graal.pointsto.constraints.UnresolvedElementException: Discovered unresolved type during parsing: kotlin.jvm.internal.Intrinsics. To diagnose the issue you can use the --allow-incomplete-classpath option. The missing type is then reported at run time when it is accessed the first time.
Trace: 
        at parsing quarkus.test.Greeting.<init>(Greeting.kt)
Call path from entry point to quarkus.test.Greeting.<init>(String): 
        at quarkus.test.Greeting.<init>(Greeting.kt)
        at quarkus.test.GreetingResource.hello(GreetingResource.kt:13)
        at com.oracle.svm.reflect.GreetingResource_hello_44d9dfd85de6efeadc824ce45553f1c8b19f95c0_29.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at io.undertow.protocols.alpn.OpenSSLAlpnProvider.setProtocols(OpenSSLAlpnProvider.java:70)
        at io.undertow.server.protocol.http.AlpnOpenListener$1$1.run(AlpnOpenListener.java:296)
        at org.xnio.nio.WorkerThread.safeRun(WorkerThread.java:612)
        at org.xnio.nio.WorkerThread.run(WorkerThread.java:479)
        at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:473)
        at com.oracle.svm.core.posix.thread.PosixJavaThreads.pthreadStartRoutine(PosixJavaThreads.java:193)
        at com.oracle.svm.core.code.IsolateEnterStub.PosixJavaThreads_pthreadStartRoutine_e1f4a8c0039f8337338252cd8734f63a79b5e3df(generated:0)
--------------------------------------------------------------------------------------------
-- WARNING: The above stack trace is not a real stack trace, it is a theoretical call tree---
-- If an interface has multiple implementations SVM will just display one potential call  ---
-- path to the interface. This is often meaningless, and what you actually need to know is---
-- the path to the constructor of the object that implements this interface.              ---
-- Quarkus has attempted to generate a more meaningful call flow analysis below          ---
---------------------------------------------------------------------------------------------

Possible path to quarkus.test.Greeting.<init>(java.lang.String):v
        quarkus.test.Greeting.<init>(java.lang.String):v
        quarkus.test.GreetingResource.hello():q
        com.oracle.svm.reflect.GreetingResource_hello_44d9dfd85de6efeadc824ce45553f1c8b19f95c0.invoke(java.lang.Object, java.lang.Object[]):j
This is an implementation of sun.reflect.MethodAccessor printing path to constructors of com.oracle.svm.reflect.GreetingResource_hello_44d9dfd85de6efeadc824ce45553f1c8b19f95c0



Error: com.oracle.graal.pointsto.constraints.UnresolvedElementException: Discovered unresolved type during parsing: kotlin.jvm.internal.Intrinsics. To diagnose the issue you can use the --allow-incomplete-classpath option. The missing type is then reported at run time when it is accessed the first time.
Trace: 
        at parsing quarkus.test.Greeting.equals(Greeting.kt)
Call path from entry point to quarkus.test.Greeting.equals(Object): 
        at quarkus.test.Greeting.equals(Greeting.kt)
        at java.util.AbstractCollection.contains(AbstractCollection.java:106)
        at java.util.AbstractCollection.containsAll(AbstractCollection.java:318)
        at java.util.RegularEnumSet.containsAll(RegularEnumSet.java:199)
        at com.oracle.svm.core.amd64.AMD64CPUFeatureAccess.verifyHostSupportsArchitecture(AMD64CPUFeatureAccess.java:158)
        at com.oracle.svm.core.JavaMainWrapper.run(JavaMainWrapper.java:131)
        at com.oracle.svm.core.code.IsolateEnterStub.JavaMainWrapper_run_5087f5482cc9a6abc971913ece43acb471d2631b(generated:0)
--------------------------------------------------------------------------------------------
-- WARNING: The above stack trace is not a real stack trace, it is a theoretical call tree---
-- If an interface has multiple implementations SVM will just display one potential call  ---
-- path to the interface. This is often meaningless, and what you actually need to know is---
-- the path to the constructor of the object that implements this interface.              ---
-- Quarkus has attempted to generate a more meaningful call flow analysis below          ---
---------------------------------------------------------------------------------------------

Possible path to quarkus.test.Greeting.equals(java.lang.Object):b
        quarkus.test.Greeting.equals(java.lang.Object):b
This is an implementation of java.lang.Object printing path to constructors of quarkus.test.Greeting


Possible path to quarkus.test.Greeting.<init>(java.lang.String):v
        quarkus.test.Greeting.<init>(java.lang.String):v
        quarkus.test.GreetingResource.hello():q
        com.oracle.svm.reflect.GreetingResource_hello_44d9dfd85de6efeadc824ce45553f1c8b19f95c0.invoke(java.lang.Object, java.lang.Object[]):j
This is an implementation of sun.reflect.MethodAccessor printing path to constructors of com.oracle.svm.reflect.GreetingResource_hello_44d9dfd85de6efeadc824ce45553f1c8b19f95c0




Error: Use -H:+ReportExceptionStackTraces to print stacktrace of underlying exception
Error: Image building with exit status 1

hm, so this: com.oracle.graal.pointsto.constraints.UnresolvedElementException: Discovered unresolved type during parsing: kotlin.jvm.internal.Intrinsics. tells me that quarkus probably needs to do some extra work when we're working with kotlin... - disclamer; i know nothing about kotlin :)
@dmlloyd / @stuartwdouglas any thoughts?

@stalep suggestion: you guys might want to have a label for issues related to kotlin.

I tested this locally against master and the test @renannprado provided now works (I also asked @geoand to verify :).

Verified on my machine as well :)

Hello.

I tried upgrading https://github.com/aesteve/quarkus-kotlin-todobackend to 0.12.0 and running quarkus-dev

Upgrading dependencies only to 0.12.0 and keeping:

id("io.quarkus.gradle.plugin") version "0.11.0"

Works!

BUT

Upgrading everything to 0.12.0聽and running 聽quarkusDev (and no longer quarkus-dev) still doesn't work. I got the exact same issue I had previously: the gradle build is terminating mentioning "BUILD SUCCESS" with no "long-running process".

Not sure it's related to the quarkus versions, Gradle version, or whatever :(

There have been a lot of changes to gradle support in master since 0.12.0 so I would propose either to build from master or wait until 0.13.0 :)

Oh, OK.

And when I wrote it works, in fact the dev process is running, but navigating http://localhost:8080/hello doesn't work.

@aesteve please open a new issue with a reproducer. Thanks!

I would suggest @aesteve that you try 0.13.0 once it's out in a few days since there have been a lot of changes in this area.

0.13.0 is out but I can't seem to get it running. A working example of a Gradle + kotlin project would be greatly appreciated.

@geoand sorry for the delay, I finally tried version 0.13.1 and the bug mentioned before was solved.

@cypressious this sample is fully working: https://github.com/renannprado/quarkus-test/

@renannprado glad to hear!

@renannprado Thx for providing the repo. I can't get it to work on my Windows machine though. What OS are you on and what JDK are you using?

@cypressious I'm using debian and GraalVM 1.0.0-rc-14-grl.
But what error are you facing exactly?

@renannprado To be precise, I don't get any error at all. This is the console output

15:41:35: Executing task 'quarkusDev'...

> Task :compileKotlin UP-TO-DATE
> Task :compileJava NO-SOURCE
> Task :processResources NO-SOURCE
> Task :classes UP-TO-DATE

> Task :quarkusDev
Starting process: 
C:\Program Files\Java\jdk-11\bin\java.EXE
-Xdebug
-Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n
-XX:TieredStopAtLevel=1
-Xverify:none
-Djava.util.logging.manager=org.jboss.logmanager.LogManager
-Dquarkus-internal.runner.classes=C:\Users\Kirill\.gradle\daemon\5.2.1\build\classes\kotlin\main
-Dquarkus-internal.runner.sources=C:\Users\Kirill\.gradle\daemon\5.2.1\src\main\kotlin
-Dquarkus-internal.runner.resources=C:\Users\Kirill\Repos\quarkus-test\src\main\resources
-jar
C:\Users\Kirill\Repos\quarkus-test\build\quarkus-test-dev.jar
C:\Users\Kirill\.gradle\daemon\5.2.1\build\classes\kotlin\main
C:\Users\Kirill\Repos\quarkus-test\build\wiring-classes
C:\Users\Kirill\Repos\quarkus-test\build\transformer-cache
Args: 
C:\Program Files\Java\jdk-11\bin\java.EXE
-Xdebug
-Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n
-XX:TieredStopAtLevel=1
-Xverify:none
-Djava.util.logging.manager=org.jboss.logmanager.LogManager
-Dquarkus-internal.runner.classes=C:\Users\Kirill\.gradle\daemon\5.2.1\build\classes\kotlin\main
-Dquarkus-internal.runner.sources=C:\Users\Kirill\.gradle\daemon\5.2.1\src\main\kotlin
-Dquarkus-internal.runner.resources=C:\Users\Kirill\Repos\quarkus-test\src\main\resources
-jar
C:\Users\Kirill\Repos\quarkus-test\build\quarkus-test-dev.jar
C:\Users\Kirill\.gradle\daemon\5.2.1\build\classes\kotlin\main
C:\Users\Kirill\Repos\quarkus-test\build\wiring-classes
C:\Users\Kirill\Repos\quarkus-test\build\transformer-cache

BUILD SUCCESSFUL in 2s

As you can see, the process just exits.

@cypressious Ah, ok, so you have a problem while executing quarkusDev task.
Hmmm... have you tried to add the --stacktrace flag to the command to see if you get more information? I believe I faced this situation before and it was because I had another process listening in the same port (i.e. the quarkusDev task was swallowing the exception).
But try to run it with the --stacktrace and/or --debug.
Another idea would be to (somehow) change the flags passed into the java command so that you can change the debugger to suspend=y and debug the code to try to find the real problem. It seems to me that the application is starting and crashing, but I might be wrong.

@renannprado I managed to attach the debugger to the process using

tasks {
    "quarkusDev"(QuarkusDev::class) {
        debug = "true"
    }
}

I set it to break at any exception and I immediately got a NoSuchFileException

grafik

I think the reason are these two lines:

-Dquarkus-internal.runner.classes=C:\Users\Kirill\.gradle\daemon\5.2.1\build\classes\kotlin\main
-Dquarkus-internal.runner.sources=C:\Users\Kirill\.gradle\daemon\5.2.1\src\main\kotlin

The directories are incorrectly resolved.

In the build.gradle.kts I changed the configuration to

quarkus {
    setSourceDir(project.projectDir.resolve("src/main/kotlin").absolutePath)
    setOutputDirectory(project.buildDir.resolve("classes/kotlin/main").absolutePath)
}

Now the exception went away, but the server still doesn't run properly. Same output as before.

@cypressious now as I understand you're not getting any exception?
There's a class called GeneratedMain that is generated by quarkus, are you able to set a breakpoint there?

@renannprado I'm getting all kinds of exceptions when the debugger is attached. In fact, so many, it's impossible to know which one is the "final" one. But I think they are "expected" exceptions.

Can you tell me where the source for the file is? Otherwise I can't set a breakpoint.

@cypressious hmmm I see. It could be they're expected indeed.
I'm not sure if there is a source file written to the disk, but I'm nearly sure that you can set the breakpoint in a .class from inside of IntelliJ at least.

image

@renannprado I can't seem to find the class. Here's what the build folder looks like

grafik

Hi, to get Kotlin+Gradle working you need to add this to the build.gradle.kts file:

quarkus {
    setSourceDir("src/main/kotlin")
    resourcesDir().add(File("src/main/resources"))
    setOutputDirectory("build/classes/kotlin/main")
}

Atm the Gradle plugin do not support multiple source folders, it is something we'll try to fix asap.

@stalep I had the setOutputDirectory before, but at least in Linux I no longer need it.

@cypressious this property could help you

Same as @cypressious I tried cloning your repo @renannprado but the ./gradlew quarkusDev simply exits after 2s :(

Gradle support has received a lot of fixes in the latest release, I suggest you give 0.18.0 a try :)

I was editing my comment when you posted.
Sorry, it seems to work with 0.18.0 I'll submit a PR to @renannprado 's repository.

Thank you for your work to support Gradle + kotlin.

Great to hear!

Unfortunately no, it doesn't work, I can't figure out why :(

I'm alternating between many errors, mainly:

> Directory '/Users/Arnaud/dev/pocs/quarkus-test/src/main/java:/Users/Arnaud/dev/pocs/quarkus-test/src/main/kotlin' specified for property 'sourceDir' does not exist.

If I'm adding

quarkus {
  setSourceDir("src/main/kotlin")
}

Then I'm facing another issue :

Exception in thread "main" java.nio.file.NoSuchFileException: /Users/Arnaud/.gradle/daemon/5.3/src/main/kotlin

So I tried:

quarkus {
  setSourceDir(projectDir.absolutePath + "/src/main/kotlin")
}

But then in my build directory I get a weird directory structure.

Gonna give up for now, waiting for 0.19.0!
Thanks for your help, though!

I pushed my attempts here : https://github.com/aesteve/quarkus-test

I'll try and check it out later

Having the same problem!

Can we get the issue reopened?

Versions 0.19.0 will be released today most likely.
Once it is out please give it a try and let us know what happens.

The problem persists. You can verify that if you build this repo: https://github.com/hmarcelino/millions

There is a regression in 0.19.0 WRT Gradle and 0.19.1 will follow soon. Lets reexamine your reproducer once that is ready

This is not fixed yet.

The problem might be related with the fact that I have multiple source roots. I'm testing this with a java + kotlin. I was able to not have any problem if I set the sourceDir to:

quarkusDev {
    sourceDir '/Users/hugomarcelino/projects/myprojects/millions/src/main/java'
}

But this will ignore kotlin src directory.

I'll wait a little bit more before start using it.

@hugomarcelino-spotqa AFAIK, multiple source roots won't work in the current implementation - definitely something to be fixed

Not fixed for me neither in 0.19.1.

I pushed my latest experiments here.

The gradle clean quarkusDev聽task fails with an error:

The project has no output yet, this should not happen as build should have been executed first. Does the project have any source files?

I also pushed a working Java version

Major EDIT:
I finally got something working by hacking the Gradle conf a bit. See this branch and especially: the hack

It's hacky obviously, but works on my laptop at least.

I tried looking at the plugin source code to understand a bit how things are resolved, but unfortunately, putting a breakpoint in the plugin code in IntelliJ and running quarkusDev in debug mode doesn't hit the breakpoint :(

For sure the key lies here. I tried to find on codata how people did to not rely on JavaPluginExtension but get the real sourceSets defined in the project (and maybe the user also defined custom sourceSets btw) but can't find anything. I even tried to display sourceSets here but it only displays the Java ones.

Maybe there's another kotlin plugin to add than the JVM one. I'm confused :\

Sorry can't add more info for a while (5 days or so). Thanks for your help and work

Thanks for all the info.

Hopefully I'll take a look in a few days

Not sure it's relevant, it looks like the Kotlin plugin does this not sure when it does it, or if it does at all, but it looks like it adds a convention somehow at some time.

Hope you'll figure out either a misconception or something I did wrong.

I don't really understand how plugins work with one another. Indeed at the time the quarkusDev config block is called in my project, project.sourceSets doesn't contain anything related to kotlin.

@aesteve I was able to launch your application by adding:

quarkus {
    setOutputDirectory(project.buildDir.resolve("classes/kotlin/main").absolutePath)
}

to build.gradle.kts

Thank you.

That鈥檚 less 芦聽hacky聽禄 than what I mentioned earlier in the thread indeed.

馃憤

That said, we want to improve the Gradle support moving forward

Is there an issue / pull-request where we can follow your progress, help investigations or maybe review ?

I didn't find a lot of things while investigating, but maybe It'd help in some way (and now that I dug a bit into the source, I'm interested :D )

Let me know.

To be honest I haven't really worked on it nor I have I followed the latest developments on Quarkus - Gradle integration.

@aloubyansky would know more :)

Thank you for the workaround here
https://github.com/aesteve/quarkus-test/blob/2e59516162298c67e54d812eca2753a7a21912c1/build.gradle.kts#L21-L28
I got the same error with the newest gradle / kotlin / quarkus and this fixed it.

I did short it to

quarkus {
    setSourceDir(project.projectDir.resolve("src/main/kotlin").absolutePath)
    setOutputDirectory(project.buildDir.resolve("classes/kotlin/main").absolutePath)
}

EDIT:

Sadly including java code doesn't work.
It doesn't put the java.class into the jar and quarkusDev throws "ClassNotFound" errors.

@jnizet what's the current workaround for Quarkus 1.1.0?
The setSourceDir & setOutputDirectory don't exist anymore.

@MartinX3 I propose that you generate a project using

mvn io.quarkus:quarkus-maven-plugin:1.1.0.Final:create     -DprojectGroupId=org.acme     -DprojectArtifactId=gradle-kotlin-test     -DclassName="org.acme.GreetingResource"     -Dpath="/greeting"  -Dextensions="kotlin" -DbuildTool=gradle

to see what the proposed configuration looks like

Thank you for your response @geoand

I fixed it now in my build.gradle.kts with

sourceSets {
    main {
        java {
            setSrcDirs(listOf("src/main/kotlin/"))
            outputDir = File("build/classes/kotlin/main/")
        }
    }
}

Should I still execute this command?

Should I still execute this command?

Which command is that?

Should I still execute this command?

Which command is that?

I mean if I should still execute
mvn io.quarkus:quarkus-maven-plugin:1.1.0.Final:create -DprojectGroupId=org.acme -DprojectArtifactId=gradle-kotlin-test -DclassName="org.acme.GreetingResource" -Dpath="/greeting" -Dextensions="kotlin" -DbuildTool=gradle for you, since my new gradle commands fixed this issue for me on 1.1.0?

That command was just to create a new project that is properly configured so you can compare.

Thanks for your investigations @MartinX3 I did upgrade my example repo to 1.0.1.Final

I optimized it based on the generated quarkus example project

sourceSets {
    main {
        java {
            setSrcDirs(listOf("$projectDir/src/main/kotlin"))
            outputDir = File("$projectDir/build/classes/kotlin/main")
        }
    }
}
Was this page helpful?
0 / 5 - 0 ratings