question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[gradle] Support for multi-project builds

See original GitHub issue

I think a part of this would be also thinking about the layering - I guess project dependencies should go in a separate layer on top of upstream dependencies, or maybe even together with the app.

Description of the issue:

Repro: https://github.com/anuraaga/gradle-jib-multiproject-example

When trying to run jibExportDockerContext for a gradle project with multiple subprojects that depend on each other, I found that the project dependency only has compileJava run, not jar. Because of this, jibExportDockerContext fails when trying to copy the jar with

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':server:jibExportDockerContext'.
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:110)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:77)
        at org.gradle.api.internal.tasks.execution.OutputDirectoryCreatingTaskExecuter.execute(OutputDirectoryCreatingTaskExecuter.java:51)
        at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:59)
        at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:54)
        at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:59)
        at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:101)
        at org.gradle.api.internal.tasks.execution.FinalizeInputFilePropertiesTaskExecuter.execute(FinalizeInputFilePropertiesTaskExecuter.java:44)
        at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:91)
        at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:62)
        at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:59)
        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.api.internal.tasks.execution.EventFiringTaskExecuter$1.run(EventFiringTaskExecuter.java:51)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
        at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:46)
        at org.gradle.execution.taskgraph.LocalTaskInfoExecutor.execute(LocalTaskInfoExecutor.java:42)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareWorkItemExecutor.execute(DefaultTaskExecutionGraph.java:273)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareWorkItemExecutor.execute(DefaultTaskExecutionGraph.java:258)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$ExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:135)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$ExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:130)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$ExecutorWorker.execute(DefaultTaskPlanExecutor.java:200)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$ExecutorWorker.executeWithWork(DefaultTaskPlanExecutor.java:191)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$ExecutorWorker.run(DefaultTaskPlanExecutor.java:130)
        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.GradleException: Export Docker context failed, perhaps you should check if the command-line option `--jibTargetDir` is set correctly
        at com.google.cloud.tools.jib.gradle.DockerContextTask.generateDockerContext(DockerContextTask.java:144)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)
        at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:46)
        at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:39)
        at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:26)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:786)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:753)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$1.run(ExecuteActionsTaskExecuter.java:131)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:120)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:99)
        ... 31 more
Caused by: java.nio.file.NoSuchFileException: C:\tools\msys64\home\Anuraag\git\gradle-jib-multiproject-example\lib\build\libs\lib.jar
        at com.google.cloud.tools.jib.filesystem.FileOperations.lambda$copy$0(FileOperations.java:43)
        at com.google.cloud.tools.jib.filesystem.FileOperations.copy(FileOperations.java:50)
        at com.google.cloud.tools.jib.docker.DockerContextGenerator.generate(DockerContextGenerator.java:209)
        at com.google.cloud.tools.jib.gradle.DockerContextTask.generateDockerContext(DockerContextTask.java:128)
        ... 48 more

Expected behavior:

jar task should be run for project dependencies

Steps to reproduce:

In a multi-project build, where server depends on lib, run

$ git clone https://github.com/anuraaga/gradle-jib-multiproject-example
$ cd gradle-jib-multiproject-example
$ ./gradlew :server:jibExportDockerContext --stacktrace --info

There will be a NoSuchFileException for lib.jar

Environment:

Windows 10+ Msys2, Gradle 4.9, Java 10

jib-gradle-plugin Configuration:

Adapted:

jib {
  from {
    image = 'openjdk:10-jre-slim'
  }
  to {
    image = 'gcr.io/test-project/test-image'
  }
  container {
    mainClass = 'Main'
  }
}

Log output:


Additional Information:

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:8 (8 by maintainers)

github_iconTop GitHub Comments

2reactions
anuraagacommented, Aug 26, 2018

I found that the problem happens when the jib project is evaluated before a dependency project, which is allowed by Gradle as it evaluates projects in an alphabetical way, not a dependency graph one (since it has no dependency graph available during evaluation).

Sent #880 to fix and add a regression test (my repro repository in the original post is also updated to exercise this behavior)

0reactions
coollogcommented, Aug 27, 2018

@anuraaga Thanks for filing the fix!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Executing Multi-Project Builds - Gradle User Manual
Gradle supports this scenario through multi-project builds. ... To identify the project structure, you can use gradle projects command.
Read more >
Gradle - Multi-Project Build - Tutorialspoint
Gradle can handle smallest and largest projects easily. Small projects have a single build file and a source tree. It is very easy...
Read more >
4 Benefits Of Using Gradle Multi-Project Builds - Tom Gregory
Parallel build. With a multi-project build in place, you can use Gradle's parallel build features for even better performance. This allows tasks ...
Read more >
Getting Started With Gradle: Creating a Multi-Project Build
Create the build.gradle file to the root directory of the app project. · Create a Java project by applying the Java plugin. ·...
Read more >
Multi-Project Build in Gradle - Javatpoint
Gradle supports multi -project build for the rapid development of the projects. It helps to modularize the project. It allows us to concentrate...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found