groovy / groovy-android-gradle-plugin

A Gradle plugin to support the Groovy language for building Android apps
Apache License 2.0
850 stars 116 forks source link

Kotlin Support #139

Closed tehras closed 7 years ago

tehras commented 7 years ago

Hey team, When using Kotlin version 1.0.4 or higher (1.0.3 worked) during the :app:compileDebugGroovyWithGroovyc i get the following error:

error: package {package name where kotlin class is in} does not exist

Any ideas if there's something i can do to get this working?

AndrewReitz commented 7 years ago

Could you provide a failing test or a project where this is occurring?

tehras commented 7 years ago

It's an enterprise project, so can't really show it, but, let me give you some more information.

This happens when I just press the play button to deploy to a device, not during any of the testing tasks, which is weird that it runs groovyc command?

My Android Studio version is 2.2.3

Error:Execution failed for task ':app:compileDebugGroovyWithGroovyc'.
> Compilation failed; see the compiler error output for details.

Have you tried running the newest Kotlin stuff with Groovyx yet? What surprises me is that it works fine with Kotlin 1.0.3, but stopped after 1.0.4.

AndrewReitz commented 7 years ago

I do not need access to your project. If you could create a sample project or create a failing test in the functional tests section of the source code I can help. If these aren't provided there isn't much I can do.

eldae commented 7 years ago

Hi, I'm having similar issues. I've created sample project: https://github.com/eldae/java-kotlin-groovy.

Hope it will help you with resolving this issue.

xklakoux commented 7 years ago

Any updates on this? Did anybody take a look at the sample project?

tehras commented 7 years ago

I still haven't been able to figure any workaround out, and I don't know how Groovy compilation happens, so not sure where to go from here.

AndrewReitz commented 7 years ago

The groovy compiler is unable to see the kotlin sources. The way groovy and java interact to overcome this issue is the groovy compiler generates stubbed java code so that java can compile then the groovy source can compile. If there is a way for kotlin to generate stubbed out java files then it may be possible to solve this issue. I am not familiar with how kotlin and java interact but they must have something similar, especially since there are claims that this use to work with 1.0.3.

tehras commented 7 years ago

Just for additional info i posted the stack trace. And I just tried 1.0.3 in the sample project, and it worked.

org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:compileDebugGroovyWithGroovyc'.
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:84)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:55)
        at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:62)
        at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
        at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:88)
        at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:46)
        at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:51)
        at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54)
        at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
        at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:34)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker$1.execute(DefaultTaskGraphExecuter.java:236)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker$1.execute(DefaultTaskGraphExecuter.java:228)
        at org.gradle.internal.Transformers$4.transform(Transformers.java:169)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:61)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:228)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:215)
        at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:77)
        at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:58)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:32)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:113)
        at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:37)
        at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
        at org.gradle.execution.DefaultBuildExecuter.access$000(DefaultBuildExecuter.java:23)
        at org.gradle.execution.DefaultBuildExecuter$1.proceed(DefaultBuildExecuter.java:43)
        at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
        at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
        at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:30)
        at org.gradle.initialization.DefaultGradleLauncher$3.execute(DefaultGradleLauncher.java:196)
        at org.gradle.initialization.DefaultGradleLauncher$3.execute(DefaultGradleLauncher.java:193)
        at org.gradle.internal.Transformers$4.transform(Transformers.java:169)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:56)
        at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:193)
        at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:119)
        at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:102)
        at org.gradle.launcher.exec.GradleBuildController.run(GradleBuildController.java:71)
        at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:28)
        at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:41)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:26)
        at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:75)
        at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:49)
        at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:44)
        at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:29)
        at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:67)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:47)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
        at org.gradle.util.Swapper.swap(Swapper.java:38)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:60)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:72)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
        at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
        at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
Caused by: org.gradle.api.internal.tasks.compile.CompilationFailedException: Compilation failed; see the compiler error output for details.
        at org.gradle.api.internal.tasks.compile.ApiGroovyCompiler.execute(ApiGroovyCompiler.java:183)
        at org.gradle.api.internal.tasks.compile.ApiGroovyCompiler.execute(ApiGroovyCompiler.java:60)
        at org.gradle.api.internal.tasks.compile.daemon.AbstractDaemonCompiler$CompilerWorkerAdapter.execute(AbstractDaemonCompiler.java:73)
        at org.gradle.api.internal.tasks.compile.daemon.AbstractDaemonCompiler$CompilerWorkerAdapter.execute(AbstractDaemonCompiler.java:64)
        at org.gradle.process.internal.daemon.WorkerDaemonServer.execute(WorkerDaemonServer.java:28)
        at org.gradle.api.internal.tasks.compile.daemon.AbstractDaemonCompiler$CompilerDaemonServer.execute(AbstractDaemonCompiler.java:91)
        at org.gradle.process.internal.worker.request.WorkerAction.run(WorkerAction.java:87)
        at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
        at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
        at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:377)
        ... 2 more
AndrewReitz commented 7 years ago

@tehras When I run the sample project that was provided I get a compilation error not a stack trace. Are you using a different project?

tehras commented 7 years ago

Same one, i ran ./gradlew assembleDebug --stacktrace

AndrewReitz commented 7 years ago

@tehras what is the desired result in this situation? If it's just to allow spock tests on the JVM, skipping groovyc during the main source compilation might do the trick, but if we want kotlin, java, and groovy to all play nicely with each other that might be a lot more work.

tehras commented 7 years ago

i think ideally i'd like it to all work together, for for short term, how would i be able to skip groovyc compile during main source compilation?

tehras commented 7 years ago

Hey @AndrewReitz. Added - tasks.whenTaskAdded { task -> if (task.name == "compileDebugGroovyWithGroovyc") { task.enabled = false } } Seemed to have fixed my issue during run.

Also found https://discuss.gradle.org/t/kotlin-groovy-and-java-compilation/14903/8 post. Is it possible to reorder to something like this? compileGroovy.dependsOn = compileGroovy.taskDependencies.values - 'compileJava' compileKotlin.dependsOn compileGroovy compileKotlin.classpath += files(compileGroovy.destinationDir) classes.dependsOn compileKotlin

AndrewReitz commented 7 years ago

I think #119 will help with skipping tasks easier. I'll look into using what was provided and buttoning up tests.

As for kotlin + java + groovy all working together nicely, I'm not entirely sure that's possible with this plugin (or with the regular java + groovy + kotlin plugins outside of the android realm). I'm more than happy to add configurations to allow support for specific cases such as being able to use Spock, but a "It Just Works" solution seems unlikely.

AndrewReitz commented 7 years ago

@tehras Once #143 is merged would you want to test out the snapshot and see if this fixes the issue you are seeing?

tehras commented 7 years ago

@AndrewReitz will do!

AndrewReitz commented 7 years ago

@tehras did this fix the issue you were seeing?

tehras commented 7 years ago

Using classpath "org.codehaus.groovy:groovy-android-gradle-plugin:1.2.0-SNAPSHOT" I still got the same exact error. Tried Kotlin 1.0.4 and 1.1.1 (Latest).

AndrewReitz commented 7 years ago

Alright, guess it's time to dig out the Kotlin source and see what they changed.

AndrewReitz commented 7 years ago

Looks like the way the classpaths are handled changed. When using newer versions of the Android Gradle Plugin ( > 2.5.0 according to the source) it should be fixed by this line https://github.com/JetBrains/kotlin/blob/master/libraries/tools/kotlin-gradle-plugin/src/agp25/kotlin/org/jetbrains/kotlin/gradle/plugin/android/Android25ProjectHandler.kt#L70

Until then the Groovy Android Plugin will need to have a reference to the class files output by the Kotlin Plugin. Looks like this can be done by using the syncTask ( a task for moving all Kotlin files into the Java output folder). Hopefully, I'll have a fix done this weekend, and I take back my comment about getting them to work nicely together.

AndrewReitz commented 7 years ago

Available in the Snapshot! Please try it out.

JcMinarro commented 7 years ago

it works on 1.2.0-SNAPSHOT. When are you going to release this new version?

AndrewReitz commented 7 years ago

Soon, there are a few things I'm cleaning up for the release and want to make sure those work out.

gabrielhuff commented 7 years ago

Will this work with Kotlin v1.1.3?

Execution failed for task ':<project>:compileDebugAndroidTestGroovyWithGroovyc'.
> Cannot get property 'kotlinOutputDir' on null object

Considering the following lines from the groovyx.GroovyAndroidPlugin class (source here):

def kotlin = project.plugins.findPlugin('kotlin-android')
if (kotlin != null) {
  def kotlinCopyTask = project.tasks.findByName("copy${variantName.capitalize()}KotlinClasses")
  return kotlinCopyTask.kotlinOutputDir
}

In my case the kotlin plugin was found but no task called copy<VariantName>KotlinClasses was defined.

Also, Kotlin v1.1.2 is being used on functional tests

The build script dependencies I'm using:

AndrewReitz commented 7 years ago

@gabrielhuff I'm not sure if it will work for that version of Kotlin. You can easily test it out by changing this line to that version https://github.com/groovy/groovy-android-gradle-plugin/blob/master/groovy-android-gradle-plugin/src/test/groovy/groovyx/functional/KotlinSupportSpec.groovy#L41 and running the tests.

As for the 3.0.0 version of the Android Gradle Plugin, I'm fairly confident that it will not work with the Groovy Android Plugin. I don't plan to start working on support for it until after it's out of beta since I can not keep up with all the changes an entire team is making.