Gradle Tooling API cannot build HierarchicalEclipseProject model for a project using appengine plugin

The Gradle project located here https://github.com/yunspace/eclipse_gradle_appengine_bug has an appengine plugin applied and it fails to import into Eclipse with Gradle Eclipse Integration plugin. The issue has something to do with the appengine plugin applied to the project.

The minimal code snippet to reproduce the issue is below. It really comes down to to creation of ProjectConnection and getting an Eclipse or HierarchicalEclipseProject model

GradleProject project = GradleCore.create(GradleTest.getTestFile(“resources/projects/appengine”));

ProjectConnection connection = ToolinApiUtils.getGradleConnector(project, new NullProgressMonitor());

EclipseProject ep = connection.getModel(EclipseProject.class);

assertTrue(ep != null);

Is this something wrong in Gradle or with app engine SDK dependency?

(Original question on GitHub: https://github.com/spring-projects/eclipse-integration-gradle/issues/79)

The exception from Gradle Core is:

Caused by: java.lang.ClassCastException: java.io.File cannot be cast to org.gradle.api.artifacts.Configuration

at org.gradle.plugins.ide.internal.IdeDependenciesExtractor.extractProjectDependencies(IdeDependenciesExtractor.java:52)

at org.gradle.plugins.ide.internal.IdeDependenciesExtractor$extractProjectDependencies.call(Unknown Source)

at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)

at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)

at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:124)

at org.gradle.plugins.ide.eclipse.model.internal.ClasspathFactory$3.update(ClasspathFactory.groovy:45)

at org.gradle.plugins.ide.eclipse.model.internal.ClasspathEntryBuilder$update.call(Unknown Source)

at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)

at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)

at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:120)

at org.gradle.plugins.ide.eclipse.model.internal.ClasspathFactory.createEntries(ClasspathFactory.groovy:76)

at org.gradle.plugins.ide.eclipse.model.internal.ClasspathFactory$createEntries.call(Unknown Source)

at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)

at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)

at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)

at org.gradle.plugins.ide.eclipse.model.EclipseClasspath.resolveDependencies(EclipseClasspath.groovy:209)

at org.gradle.plugins.ide.internal.tooling.EclipseModelBuilder.populate(EclipseModelBuilder.java:85)

at org.gradle.plugins.ide.internal.tooling.EclipseModelBuilder.buildAll(EclipseModelBuilder.java:61)

at org.gradle.plugins.ide.internal.tooling.EclipseModelBuilder.buildAll(EclipseModelBuilder.java:32)

at org.gradle.tooling.internal.provider.BuildModelAction.run(BuildModelAction.java:68)

at org.gradle.tooling.internal.provider.BuildModelAction.run(BuildModelAction.java:32)

at org.gradle.tooling.internal.provider.ConfiguringBuildAction.run(ConfiguringBuildAction.java:134)

at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:36)

at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:26)

at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:47)

at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:34)

at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)

at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:35)

at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)

at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:24)

at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)

at org.gradle.launcher.daemon.server.exec.StartStopIfBuildAndStop.execute(StartStopIfBuildAndStop.java:33)

at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)

at org.gradle.launcher.daemon.server.exec.ReturnResult.execute(ReturnResult.java:34)

at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)

at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:71)

at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:69)

at org.gradle.util.Swapper.swap(Swapper.java:38)

at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:69)

at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)

at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:60)

at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:34)

at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)

at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:70)

at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:34)

at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)

at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:45)

at org.gradle.launcher.daemon.server.DaemonStateCoordinator.runCommand(DaemonStateCoordinator.java:258)

at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy.doBuild(StartBuildOrRespondWithBusy.java:49)

at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:34)

at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)

at org.gradle.launcher.daemon.server.exec.HandleCancel.execute(HandleCancel.java:36)

at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)

at org.gradle.launcher.daemon.server.exec.HandleStop.execute(HandleStop.java:30)

at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)

at org.gradle.launcher.daemon.server.exec.DaemonHygieneAction.execute(DaemonHygieneAction.java:39)

at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)

at org.gradle.launcher.daemon.server.exec.CatchAndForwardDaemonFailure.execute(CatchAndForwardDaemonFailure.java:32)

at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)

at org.gradle.launcher.daemon.server.exec.DefaultDaemonCommandExecuter.executeCommand(DefaultDaemonCommandExecuter.java:52)

at org.gradle.launcher.daemon.server.DefaultIncomingConnectionHandler$ConnectionWorker.handleCommand(DefaultIncomingConnectionHandler.java:154)

at org.gradle.launcher.daemon.server.DefaultIncomingConnectionHandler$ConnectionWorker.receiveAndHandleCommand(DefaultIncomingConnectionHandler.java:128)

at org.gradle.launcher.daemon.server.DefaultIncomingConnectionHandler$ConnectionWorker.run(DefaultIncomingConnectionHandler.java:116)

at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:64)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

at java.lang.Thread.run(Thread.java:744)

There is an underlying bug in the appengine plugin that’s causing this exception. 
https://github.com/GoogleCloudPlatform/gradle-appengine-plugin/blob/d866b74bc648a56a50909670691b8566…

As described in the Gradle 2.0 Release Notes, there was a breaking change in Groovy 2.x which in turn affects Gradle 2.x. In Gradle 1.x, the appengine code snippet:
’’‘
plugin.model.classpath.plusConfigurations += functionalTestRuntimeConfiguration
’’‘
would have added the ‘functionalTestRuntimeConfiguration’ to the ‘plusConfigurations’ collection. In Gradle 2.x, this results in each of the files in the configuration being incorrectly added to the collection. Since we assume that all of the entries in the ‘plusConfigurations’ collection are in fact ‘Configuration’ instances, you see a ‘ClassCastException’ when Gradle encounters a ‘File’.

The simple fix for the ‘appengine’ plugin is to replace the offending line with:
’’‘
plugin.model.classpath.plusConfigurations += [functionalTestRuntimeConfiguration]
’’’