Forced :jar task execution in included-builds

buildship
eclipse

(Pascal Wölfle) #1

Currently, we rebuild the buildsystem of our enterprise software to use Gradle 3.2.1+ and Buildship 2.0.0+. We want to use the composite-build for simplifying the developer’s life. But we have unexpected jar-task executions of the included builds, when we import our projects with Buildship.

I reduced our multi-project structure for reproducing the problem for both approaches that we tried:
https://github.com/pwoelfle/gradle-composite-build

Approach one

The project-lib is used as included-build in project-application. I import project-lib into a new workspace with Buildship and then I also import project-application. Everything looks as expected, but when I check project-lib, I saw that the jar of this project was created. My expectation was that the binary dependency to project-lib in project-application is simply substituted as project dependency without building the project-lib.

With the current behaviour the workspace setup would have the duration of the build-time of each included-build. This is irrelevant in small projects, because the jar is created quickly. But in our case the built-time for the library project is about 2 minutes. And some more of our projects use bigger projects with build-times about 12 minutes.

Moreover after importing all projects (which forces the :jar execution of all included-builds), the whole workspace must be build with Eclipse again. This doubled the duration until a developer can start working.

I debugged the import and found out that the method org.gradle.plugins.ide.internal.IdeDependenciesExtractor#resolvedExternalDependencies forces the :jar task execution, because the dependency is resolved as external dependency.

Stacktrace

java.lang.Thread.State: RUNNABLE
at org.gradle.composite.internal.IncludedBuildArtifactBuilder.execute(IncludedBuildArtifactBuilder.java:58)
at org.gradle.composite.internal.IncludedBuildArtifactBuilder.build(IncludedBuildArtifactBuilder.java:52)
at org.gradle.composite.internal.CompositeProjectArtifactBuilder.build(CompositeProjectArtifactBuilder.java:39)
at org.gradle.api.internal.artifacts.ivyservice.projectmodule.AggregatingProjectArtifactBuilder.build(AggregatingProjectArtifactBuilder.java:33)
at org.gradle.api.internal.artifacts.ivyservice.projectmodule.CacheLockReleasingProjectArtifactBuilder$1.run(CacheLockReleasingProjectArtifactBuilder.java:36)
at org.gradle.internal.Factories$1.create(Factories.java:25)
at org.gradle.cache.internal.DefaultCacheAccess.longRunningOperation(DefaultCacheAccess.java:239)
at org.gradle.cache.internal.DefaultCacheAccess.longRunningOperation(DefaultCacheAccess.java:310)
at org.gradle.cache.internal.DefaultPersistentDirectoryStore.longRunningOperation(DefaultPersistentDirectoryStore.java:137)
at org.gradle.cache.internal.DefaultCacheFactory$ReferenceTrackingCache.longRunningOperation(DefaultCacheFactory.java:183)
at org.gradle.api.internal.artifacts.ivyservice.DefaultCacheLockingManager.longRunningOperation(DefaultCacheLockingManager.java:48)
at org.gradle.api.internal.artifacts.ivyservice.projectmodule.CacheLockReleasingProjectArtifactBuilder.build(CacheLockReleasingProjectArtifactBuilder.java:33)
at org.gradle.api.internal.artifacts.ivyservice.projectmodule.ProjectDependencyResolver.resolveArtifact(ProjectDependencyResolver.java:105)
at org.gradle.api.internal.artifacts.ivyservice.resolveengine.ComponentResolversChain$ArtifactResolverChain.resolveArtifact(ComponentResolversChain.java:103)
at org.gradle.api.internal.artifacts.ivyservice.CacheLockingArtifactResolver$3.run(CacheLockingArtifactResolver.java:61)
at org.gradle.internal.Factories$1.create(Factories.java:25)
at org.gradle.cache.internal.DefaultCacheAccess.useCache(DefaultCacheAccess.java:179)
at org.gradle.cache.internal.DefaultCacheAccess.useCache(DefaultCacheAccess.java:162)
at org.gradle.cache.internal.DefaultPersistentDirectoryStore.useCache(DefaultPersistentDirectoryStore.java:129)
at org.gradle.cache.internal.DefaultCacheFactory$ReferenceTrackingCache.useCache(DefaultCacheFactory.java:191)
at org.gradle.api.internal.artifacts.ivyservice.DefaultCacheLockingManager.useCache(DefaultCacheLockingManager.java:56)
at org.gradle.api.internal.artifacts.ivyservice.CacheLockingArtifactResolver.resolveArtifact(CacheLockingArtifactResolver.java:59)
at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.ErrorHandlingArtifactResolver.resolveArtifact(ErrorHandlingArtifactResolver.java:56)
at org.gradle.api.internal.artifacts.ivyservice.resolveengine.artifact.DefaultArtifactSet$LazyArtifactSource.create(DefaultArtifactSet.java:93)
at org.gradle.api.internal.artifacts.ivyservice.resolveengine.artifact.DefaultArtifactSet$LazyArtifactSource.create(DefaultArtifactSet.java:80)
at org.gradle.api.internal.artifacts.DefaultResolvedArtifact.getFile(DefaultResolvedArtifact.java:90)
at org.gradle.api.internal.artifacts.ivyservice.DefaultLenientConfiguration$1$1.isSatisfiedBy(DefaultLenientConfiguration.java:136)
at org.gradle.api.internal.artifacts.ivyservice.DefaultLenientConfiguration$1$1.isSatisfiedBy(DefaultLenientConfiguration.java:133)
at org.gradle.util.CollectionUtils.filter(CollectionUtils.java:137)
at org.gradle.util.CollectionUtils.filter(CollectionUtils.java:105)
at org.gradle.api.internal.artifacts.ivyservice.DefaultLenientConfiguration$1.create(DefaultLenientConfiguration.java:133)
at org.gradle.api.internal.artifacts.ivyservice.DefaultLenientConfiguration$1.create(DefaultLenientConfiguration.java:131)
at org.gradle.cache.internal.DefaultCacheAccess.useCache(DefaultCacheAccess.java:179)
at org.gradle.cache.internal.DefaultPersistentDirectoryStore.useCache(DefaultPersistentDirectoryStore.java:125)
at org.gradle.cache.internal.DefaultCacheFactory$ReferenceTrackingCache.useCache(DefaultCacheFactory.java:187)
at org.gradle.api.internal.artifacts.ivyservice.DefaultCacheLockingManager.useCache(DefaultCacheLockingManager.java:52)
at org.gradle.api.internal.artifacts.ivyservice.DefaultLenientConfiguration.getArtifacts(DefaultLenientConfiguration.java:131)
at org.gradle.api.internal.artifacts.ivyservice.ErrorHandlingConfigurationResolver$ErrorHandlingLenientConfiguration.getArtifacts(ErrorHandlingConfigurationResolver.java:84)
at org.gradle.plugins.ide.internal.resolver.DefaultIdeDependencyResolver.getExternalArtifacts(DefaultIdeDependencyResolver.java:237)
at org.gradle.plugins.ide.internal.resolver.DefaultIdeDependencyResolver.getIdeRepoFileDependencies(DefaultIdeDependencyResolver.java:132)
at org.gradle.plugins.ide.internal.IdeDependenciesExtractor.resolvedExternalDependencies(IdeDependenciesExtractor.java:181)
at org.gradle.plugins.ide.internal.IdeDependenciesExtractor.extractRepoFileDependencies(IdeDependenciesExtractor.java:77)
at org.gradle.plugins.ide.eclipse.model.internal.EclipseDependenciesCreator.createLibraryDependencies(EclipseDependenciesCreator.java:82)
at org.gradle.plugins.ide.eclipse.model.internal.EclipseDependenciesCreator.createDependencyEntries(EclipseDependenciesCreator.java:58)
at org.gradle.plugins.ide.eclipse.model.internal.ClasspathFactory.createDependencies(ClasspathFactory.java:69)
at org.gradle.plugins.ide.eclipse.model.internal.ClasspathFactory.createEntries(ClasspathFactory.java:46)
at org.gradle.plugins.ide.eclipse.model.EclipseClasspath.resolveDependencies(EclipseClasspath.java:304)
at org.gradle.plugins.ide.eclipse.model.EclipseClasspath.mergeXmlClasspath(EclipseClasspath.java:311)
at org.gradle.plugins.ide.eclipse.GenerateEclipseClasspath.configure(GenerateEclipseClasspath.java:43)
at org.gradle.plugins.ide.eclipse.GenerateEclipseClasspath.configure(GenerateEclipseClasspath.java:28)
at org.gradle.plugins.ide.api.XmlGeneratorTask$1.configure(XmlGeneratorTask.java:40)
at org.gradle.plugins.ide.api.XmlGeneratorTask$1.configure(XmlGeneratorTask.java:32)
at org.gradle.plugins.ide.api.GeneratorTask.generate(GeneratorTask.java:81)
at sun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethodAccessorImpl.java:-1)
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)

Is this the expected behavior? In my opinion, dependencies that could be satisfied by an included build as project dependency, could be directly declared as project dependency. As well because the dependency is only used for creating the .classpath file.

#Approach two
The composite-build project uses the project-lib and project-application as included builds. I import composite-build into a new workspace with Buildship and then both included-build projects.
This time no :jar task is executed, but there is also no substitution of the included build dependency that could be satisfied by a project dependency.

Thanks for your help, you doing a great job :slight_smile:


(Stefan Oehme) #2

Composite build support in the IDE only works properly with the Gradle 3.3 nightlies, please give them a try and let us know if there are still any problems :slight_smile:


(Pascal Wölfle) #3

I tried both approaches with Gradle 3.3 nightly and now it works as expected. Thanks for the advice.