Skip to content

Commit 65a5697

Browse files
authored
Update multimodule example with module dependency (#2155)
1 parent 605238d commit 65a5697

File tree

13 files changed

+174
-43
lines changed

13 files changed

+174
-43
lines changed

examples/multi-module/README.md

+36-4
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,30 @@ This example shows how to build multiple containers for a multi-module project i
44

55
# How the example is set up
66

7-
The project consists of two microservices:
7+
The project consists of two microservices and a library:
88

99
1. `name-service` - responds with a name
10+
1. `shared-library` - a project dependency used by `name-service`
1011
1. `hello-service` - calls `name-service` and responds with a greeting
1112

1213
The **Maven** project is set up with a parent POM ([`pom.xml`](pom.xml)) that defines most of the common build configuration. The module POMs ([`name-service/pom.xml`](name-service/pom.xml) and [`hello-service/pom.xml`](hello-service/pom.xml)) just define inheritance on the parent POM. However, if needed, the module POMs can define custom configuration on `jib-maven-plugin` specific to that module.
1314

14-
The **Gradle** project is set up with a single [`build.gradle`](build.gradle) that configures both subprojects (modules). [`settings.gradle`](settings.gradle) defines which modules to include in the overall build. If needed, the subprojects can have `build.gradle` files to define custom configuration on `jib-gradle-plugin` specific to that module.
15+
The **Gradle** project is set up with a parent [`build.gradle`](build.gradle) that sets some common configuration up for all projects, with each sub-project containing its own `build.gradle` with some custom configuration. [`settings.gradle`](settings.gradle) defines which modules to include in the overall build.
16+
17+
## Reproducibility of dependency module `shared-library`
18+
19+
Since dependency module builds happen with the underlying build system
20+
(maven/gradle), we must add some extra configuration to ensure that the
21+
resulting `jar` that is built conforms to our reproducibility expectations.
22+
The module [`shared-library`](shared-library) uses the [Reproducible Build Maven Plugin](https://zlika.github.io/reproducible-build-maven-plugin/)
23+
for maven, and some special `Jar` properties ([`preserveFileTimestamps`](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.bundling.Jar.html#org.gradle.api.tasks.bundling.Jar:preserveFileTimestamps),
24+
[`reproducibleFileOrder`](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.bundling.Jar.html#org.gradle.api.tasks.bundling.Jar:reproducibleFileOrder))
25+
in gradle to achieve this. This configuration can be seen in the
26+
`shared-library`'s [`pom.xml`](shared-library/pom.xml) and [`build.gradle`](shared-library/build.gradle).
27+
28+
Care must be taken when adding custom attributes to a `MANIFEST.MF`.
29+
Attributes whose values change on every build can affect reproducibility even
30+
with the modifications outlined aboved.
1531

1632
# How to run
1733

@@ -24,13 +40,29 @@ export PROJECT_ID=$(gcloud config list --format 'value(core.project)')
2440
Run the **Maven** build:
2541

2642
```shell
27-
./mvnw compile jib:build
43+
# build everything
44+
./mvnw package jib:build
45+
46+
# build just hello-service
47+
./mvnw compile jib:build -pl hello-service
48+
49+
# build name-service (with dependency on shared-library)
50+
# you must use "package" for jib to correctly package "shared-library" with the
51+
# "name-service" container
52+
./mvnw package jib:build -pl name-service -am
2853
```
2954

3055
Run the **Gradle** build:
3156

3257
```shell
58+
# build everything
3359
./gradlew jib
60+
61+
# build just hello-service
62+
./gradlew :hello-service:jib
63+
64+
# build name-service (with dependency on shared-library)
65+
./gradlew :name-service:jib
3466
```
3567

3668
You can also run `./maven-build.sh` or `./gradle-build.sh` as a shorthand.
@@ -68,5 +100,5 @@ svc/hello-service LoadBalancer 10.19.243.223 35.237.89.148 80:30196/TCP
68100
Visit the IP in your web browser and you should see:
69101

70102
```
71-
Hello Jib Multimodule
103+
Hello Jib Multimodule: A string from 'shared-library'
72104
```

examples/multi-module/build.gradle

+5-35
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,6 @@
1-
buildscript {
2-
repositories {
3-
mavenCentral()
4-
maven {
5-
url 'https://plugins.gradle.org/m2/'
6-
}
7-
}
8-
dependencies {
9-
classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.0.3.RELEASE'
10-
classpath 'io.spring.gradle:dependency-management-plugin:1.0.6.RELEASE'
11-
classpath 'gradle.plugin.com.google.cloud.tools:jib-gradle-plugin:1.8.0'
12-
}
13-
}
14-
15-
subprojects {
16-
apply plugin: 'java'
17-
apply plugin: 'eclipse'
18-
apply plugin: 'idea'
19-
apply plugin: 'org.springframework.boot'
20-
apply plugin: 'io.spring.dependency-management'
21-
apply plugin: 'com.google.cloud.tools.jib'
22-
23-
repositories {
24-
mavenCentral()
25-
}
26-
27-
sourceCompatibility = 1.8
28-
targetCompatibility = 1.8
29-
30-
dependencies {
31-
compile 'org.springframework.boot:spring-boot-starter-web'
32-
}
33-
34-
// IMPORTANT: Set the environment variable PROJECT_ID to your own Google Cloud Platform project.
35-
jib.to.image = "gcr.io/${System.getenv('PROJECT_ID')}/${project.name}:${version}"
1+
// Define plugin versions here, but only apply them where we need to
2+
plugins {
3+
id 'org.springframework.boot' version '2.0.3.RELEASE' apply false
4+
id 'io.spring.dependency-management' version '1.0.6.RELEASE' apply false
5+
id 'com.google.cloud.tools.jib' version '1.7.0' apply false
366
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
plugins {
2+
id 'java'
3+
id 'eclipse'
4+
id 'idea'
5+
id 'org.springframework.boot'
6+
id 'io.spring.dependency-management'
7+
id 'com.google.cloud.tools.jib'
8+
}
9+
10+
sourceCompatibility = 1.8
11+
targetCompatibility = 1.8
12+
13+
repositories {
14+
mavenCentral()
15+
}
16+
17+
dependencies {
18+
implementation 'org.springframework.boot:spring-boot-starter-web'
19+
}
20+
21+
// IMPORTANT: Set the environment variable PROJECT_ID to your own Google Cloud Platform project.
22+
jib.to.image = "gcr.io/${System.getenv('PROJECT_ID')}/${project.name}:${version}"

examples/multi-module/maven-build.sh

+6-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,9 @@
33
set -ex
44

55
export PROJECT_ID=$(gcloud config list --format 'value(core.project)')
6-
./mvnw compile jib:build
6+
# if there are no intermodule dependencies, compile is enough to complete a jib build.
7+
./mvnw compile jib:build -pl hello-service
8+
9+
# multi module builds with dependencies on other modules in the build require that the
10+
# "package" phase is executed as part of the build to correctly include module dependencies.
11+
./mvnw package jib:build -pl name-service -am
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
plugins {
2+
id 'java'
3+
id 'eclipse'
4+
id 'idea'
5+
id 'org.springframework.boot'
6+
id 'io.spring.dependency-management'
7+
id 'com.google.cloud.tools.jib'
8+
}
9+
10+
sourceCompatibility = 1.8
11+
targetCompatibility = 1.8
12+
13+
repositories {
14+
mavenCentral()
15+
}
16+
17+
dependencies {
18+
implementation 'org.springframework.boot:spring-boot-starter-web'
19+
implementation project(":shared-library")
20+
}
21+
22+
// IMPORTANT: Set the environment variable PROJECT_ID to your own Google Cloud Platform project.
23+
jib.to.image = "gcr.io/${System.getenv('PROJECT_ID')}/${project.name}:${version}"

examples/multi-module/name-service/pom.xml

+9
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,13 @@
1313
<artifactId>jib-multimodule</artifactId>
1414
<version>0.1.0</version>
1515
</parent>
16+
17+
<dependencies>
18+
<dependency>
19+
<!-- a module dependency on "shared-library" -->
20+
<groupId>com.example</groupId>
21+
<artifactId>shared-library</artifactId>
22+
<version>0.1.0</version>
23+
</dependency>
24+
</dependencies>
1625
</project>

examples/multi-module/name-service/src/main/java/name/NameController.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22

33
import org.springframework.web.bind.annotation.RestController;
44
import org.springframework.web.bind.annotation.RequestMapping;
5+
import common.SharedUtils;
56

67
@RestController
78
public class NameController {
89

910
@RequestMapping("/")
10-
public String getName() {
11-
return "Jib Multimodule";
11+
public String getText() {
12+
return "Jib Multimodule: " + SharedUtils.getText();
1213
}
1314
}

examples/multi-module/pom.xml

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
<modules>
2424
<module>name-service</module>
2525
<module>hello-service</module>
26+
<module>shared-library</module>
2627
</modules>
2728

2829
<!-- Uses Java 8. -->

examples/multi-module/settings.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
rootProject.name = 'jib-multimodule'
2-
include 'name-service', 'hello-service'
2+
include 'name-service', 'hello-service', 'shared-library'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
plugins {
2+
id 'java'
3+
id 'eclipse'
4+
id 'idea'
5+
}
6+
7+
sourceCompatibility = 1.8
8+
targetCompatibility = 1.8
9+
10+
// Since this library is included as a jar in our jib projects, we want the
11+
// jar to built reproducibly.
12+
jar {
13+
preserveFileTimestamps false
14+
reproducibleFileOrder true
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
version = 0.1.0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
6+
<!-- Defines artifact information for this module. -->
7+
<artifactId>shared-library</artifactId>
8+
<version>0.1.0</version>
9+
10+
<!-- Inherits from the Jib Multimodule parent POM. -->
11+
<parent>
12+
<groupId>com.example</groupId>
13+
<artifactId>jib-multimodule</artifactId>
14+
<version>0.1.0</version>
15+
</parent>
16+
17+
<build>
18+
<plugins>
19+
<plugin>
20+
<groupId>com.google.cloud.tools</groupId>
21+
<artifactId>jib-maven-plugin</artifactId>
22+
<configuration>
23+
<!-- we don't want jib to execute on this module -->
24+
<skip>true</skip>
25+
</configuration>
26+
</plugin>
27+
<!-- we want this library to be built reproducibly -->
28+
<plugin>
29+
<groupId>io.github.zlika</groupId>
30+
<artifactId>reproducible-build-maven-plugin</artifactId>
31+
<version>0.11</version>
32+
<executions>
33+
<execution>
34+
<id>run-when-packaged</id>
35+
<goals>
36+
<goal>strip-jar</goal>
37+
</goals>
38+
<phase>package</phase>
39+
</execution>
40+
</executions>
41+
</plugin>
42+
</plugins>
43+
</build>
44+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package common;
2+
3+
public class SharedUtils {
4+
5+
public static String getText() {
6+
return "A string from 'shared-library'";
7+
}
8+
}

0 commit comments

Comments
 (0)