Build dependencies on jar task

Hello

My Application consists of a server and a client part. Additionally there is a shared part which contains classes used by both server and client. All these different parts of my application are represented by sub-projects in my Gradle configuration. The settings.gradle for my root project looks like this:

rootProject.name = 'my-awesome-project'
include 'client'
include 'server'
include 'shared'

The server and the client have dependencies to the shared project:

dependencies {
    compile project(':shared')
}

This works all fine when I build and run my project using Gradle. When I try to build a JAR-File using ./gradlew jar in the root project I get an error though. The error message reads as follows:

FAILURE: Build failed with an exception.

* What went wrong:
Failed to capture snapshot of input files for task ':server:jar' property 'rootSpec$1' during up-to-date check.                                                                                            
> Failed to create MD5 hash for file '/path/to/my-awesome-project/shared/build/libs/shared-1.0-SNAPSHOT.jar'. 

The Stack-trace looks like this:

* Exception is:
org.gradle.api.UncheckedIOException: Failed to capture snapshot of input files for task ':server:jar' property 'rootSpec$1' during up-to-date check.
	at org.gradle.api.internal.changedetection.state.CacheBackedTaskHistoryRepository.snapshotTaskFiles(CacheBackedTaskHistoryRepository.java:333)
	at org.gradle.api.internal.changedetection.state.CacheBackedTaskHistoryRepository.createExecution(CacheBackedTaskHistoryRepository.java:154)
	at org.gradle.api.internal.changedetection.state.CacheBackedTaskHistoryRepository.access$100(CacheBackedTaskHistoryRepository.java:61)
	at org.gradle.api.internal.changedetection.state.CacheBackedTaskHistoryRepository$1.getCurrentExecution(CacheBackedTaskHistoryRepository.java:114)
	at org.gradle.api.internal.changedetection.changes.DefaultTaskArtifactStateRepository$TaskArtifactStateImpl.getStates(DefaultTaskArtifactStateRepository.java:201)
	at org.gradle.api.internal.changedetection.changes.DefaultTaskArtifactStateRepository$TaskArtifactStateImpl.isUpToDate(DefaultTaskArtifactStateRepository.java:86)
	at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:53)
	at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:54)
	at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:60)
	at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:97)
	at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:87)
	at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:52)
	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
	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.run(DefaultTaskGraphExecuter.java:248)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:241)
	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:230)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.processTask(DefaultTaskPlanExecutor.java:123)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.access$200(DefaultTaskPlanExecutor.java:79)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:104)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:98)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.execute(DefaultTaskExecutionPlan.java:626)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.executeWithTask(DefaultTaskExecutionPlan.java:581)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.run(DefaultTaskPlanExecutor.java:98)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
Caused by: org.gradle.api.UncheckedIOException: Failed to create MD5 hash for file '/path/to/my-awesome-project/shared/build/libs/shared-1.0-SNAPSHOT.jar'.
	at org.gradle.internal.hash.DefaultFileHasher.hash(DefaultFileHasher.java:45)
	at org.gradle.api.internal.changedetection.state.CachingFileHasher.snapshot(CachingFileHasher.java:88)
	at org.gradle.api.internal.changedetection.state.CachingFileHasher.snapshot(CachingFileHasher.java:75)
	at org.gradle.api.internal.changedetection.state.CachingFileHasher.hash(CachingFileHasher.java:61)
	at org.gradle.api.internal.changedetection.state.DefaultFileSystemSnapshotter.fileSnapshot(DefaultFileSystemSnapshotter.java:190)
	at org.gradle.api.internal.changedetection.state.DefaultFileSystemSnapshotter.access$600(DefaultFileSystemSnapshotter.java:54)
	at org.gradle.api.internal.changedetection.state.DefaultFileSystemSnapshotter$FileVisitorImpl.visitFile(DefaultFileSystemSnapshotter.java:224)
	at org.gradle.api.internal.file.collections.SingletonFileTree.visit(SingletonFileTree.java:42)
	at org.gradle.api.internal.file.archive.ZipFileTree.visitTreeOrBackingFile(ZipFileTree.java:199)
	at org.gradle.api.internal.file.collections.FileTreeAdapter.visitTreeOrBackingFile(FileTreeAdapter.java:125)
	at org.gradle.api.internal.file.AbstractFileTree$FilteredFileTreeImpl.visitTreeOrBackingFile(AbstractFileTree.java:196)
	at org.gradle.api.internal.changedetection.state.DefaultFileSystemSnapshotter.snapshotTree(DefaultFileSystemSnapshotter.java:159)
	at org.gradle.api.internal.changedetection.state.AbstractFileCollectionSnapshotter$FileCollectionVisitorImpl.visitTree(AbstractFileCollectionSnapshotter.java:92)
	at org.gradle.api.internal.file.AbstractFileTree.visitRootElements(AbstractFileTree.java:149)
	at org.gradle.api.internal.file.CompositeFileCollection.visitRootElements(CompositeFileCollection.java:185)
	at org.gradle.api.internal.changedetection.state.AbstractFileCollectionSnapshotter.snapshot(AbstractFileCollectionSnapshotter.java:53)
	at org.gradle.api.internal.changedetection.state.DefaultGenericFileCollectionSnapshotter.snapshot(DefaultGenericFileCollectionSnapshotter.java:38)
	at org.gradle.api.internal.changedetection.state.CacheBackedTaskHistoryRepository.snapshotTaskFiles(CacheBackedTaskHistoryRepository.java:331)
	... 32 more
Caused by: java.io.FileNotFoundException: /path/to/my-awesome-project/shared/build/libs/shared-1.0-SNAPSHOT.jar (No such file or directory)
	at org.gradle.internal.hash.DefaultFileHasher.hash(DefaultFileHasher.java:38)
	... 49 more

What I can gather from this is that in order to build the client JAR Gradle needs the shared JAR which is not available since the shared JAR was not built yet. When I first build the shared JAR using ./gradlew :shared:jar and then execute ./gradlew jar everything works perfectly fine. This confirms my theory that the error comes from the fact that Gradle cannot find the shared JAR when building the client JAR.

I thought Gradle automatically handles this dependency since I specified the dependency from the client to the shared project in the Gradle configuration. Apparently that is not the case. So how can I define a dependency when building a JAR? I want to be able to say that the shared JAR should be built first.

Thanks

Hi Aaron,

what is your :server:jar task trying to pack? It shouldn’t use shared-1.0-SNAPSHOT.jar at all, right? Only the classes of the server should go into the jar, not the content of any dependent projects, right?

Cheers,
Stefan