diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index e6c8cbe8a41b63eb0ef6fe12fea662ed1f9c0dc3..0f9492e76948c113e4adcf875538b2da93eae4fe 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -6,6 +6,7 @@ include:
   - '/templates/activate-dind.yml'
   - '/templates/stages.yml'
   - '/templates/job/java/lint.yml'
+  - '/templates/job/java/build.yml'
   - '/templates/job/container/build.yml'
   - '/templates/job/container/lint.yml'
   - '/templates/job/container/delivery.yml'
@@ -101,6 +102,10 @@ node::test:
       - test/node/vueapp/node_modules
 
 # --------[ Java ]--------
+java:build:
+  variables:
+    working_directory: "test/java-jar"
+
 java:lint:
   variables:
     working_directory: "test/java-jar"
diff --git a/README-fr.md b/README-fr.md
index e23ce38d15ef67f7aa381d035389c5d7ce1c30dc..01437d8c97d0de8314fe0ee6e74cf9160e606c55 100644
--- a/README-fr.md
+++ b/README-fr.md
@@ -247,7 +247,7 @@ node::build:
     paths:
       - node_modules
   before_script:
-    - cd $working_directory
+    - cd ${working_directory}
   script:
     - npm ci
 ```
diff --git a/gci-templates/job/.base.yml b/gci-templates/job/.base.yml
index 0dd6af876f0f5eb2aeda00c36b8890ef6c6b944c..238cdd4715b9381727ac1ee6b027121fbe44e054 100644
--- a/gci-templates/job/.base.yml
+++ b/gci-templates/job/.base.yml
@@ -2,4 +2,4 @@
   variables:
     working_directory: "$CI_PROJECT_DIR"
   script:
-    - cd $working_directory
\ No newline at end of file
+    - cd ${working_directory}
diff --git a/gci-templates/stages.yml b/gci-templates/stages.yml
index f35c81dd7d4ce2b99cde7971f7f06041102d6745..4982edb236af07121ffd1fc68a5b93f52b6a41cd 100644
--- a/gci-templates/stages.yml
+++ b/gci-templates/stages.yml
@@ -19,14 +19,15 @@ variables:
   variables:
     working_directory: "$CI_PROJECT_DIR"
   before_script:
-    - cd $working_directory
+    - cd ${working_directory}
+
 
 .base_ansible:
   extends: .base_tpl
   variables:
     ANSIBLE_VAULT_PASSWORD_FILE: .vault_pass
   before_script:
-    - cd $working_directory
+    - cd ${working_directory}
     - test -z ${ANSIBLE_VAULT_PASSWORD} || echo ${ANSIBLE_VAULT_PASSWORD} > ${ANSIBLE_VAULT_PASSWORD_FILE}
     - test -d ansible && chmod 750 ansible
 
@@ -40,7 +41,7 @@ variables:
     ## without extra base64 encoding.
     ## https://gitlab.com/gitlab-examples/ssh-private-key/issues/1#note_48526556
     - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
-    - cd $working_directory
+    - cd ${working_directory}
 
 .node-cache-push:
   cache:
diff --git a/templates/job/.base.yml b/templates/job/.base.yml
index 0dd6af876f0f5eb2aeda00c36b8890ef6c6b944c..238cdd4715b9381727ac1ee6b027121fbe44e054 100644
--- a/templates/job/.base.yml
+++ b/templates/job/.base.yml
@@ -2,4 +2,4 @@
   variables:
     working_directory: "$CI_PROJECT_DIR"
   script:
-    - cd $working_directory
\ No newline at end of file
+    - cd ${working_directory}
diff --git a/templates/job/java/build.yml b/templates/job/java/build.yml
new file mode 100644
index 0000000000000000000000000000000000000000..d7ee6a85f7b9ea3051fbfa2c38ac1725a4f3f477
--- /dev/null
+++ b/templates/job/java/build.yml
@@ -0,0 +1,13 @@
+# Build JAVA applications using Apache Maven (http://maven.apache.org)
+# For docker image tags see https://hub.docker.com/_/maven/
+# For general lifecycle information see https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
+# L'application java est construite et tout les fichier target/*.jar sont mis dans le cache pour les jobs suivants
+
+java:build:
+  extends: 
+    - .java
+    - .java-cache-push
+  stage: build
+  script:
+    - mvn ${MAVEN_CLI_OPTS} dependency:go-offline ${MAVEN_SETTINGS}
+    - mvn ${MAVEN_CLI_OPTS} clean package -DskipTests ${MAVEN_SETTINGS}
diff --git a/templates/stages.yml b/templates/stages.yml
index 5b2a6efa37799e28d229cf13598b479f36c2f3d1..3e4c9e231d1f748c10ca7118314a0a657db1690b 100644
--- a/templates/stages.yml
+++ b/templates/stages.yml
@@ -12,8 +12,9 @@ variables:
   tpl_directory: "gci-templates"
   MAVEN_OPTS: ""
   MAVEN_CLI_OPTS: ""
-  JAVA_VERSION: "11"
+  MAVEN_SETTINGS: ""
   MAVEN_VERSION: "3"
+  JAVA_VERSION: "11"
   JDK_TYPE: "openjdk"
 
 
@@ -22,14 +23,14 @@ variables:
   variables:
     working_directory: "$CI_PROJECT_DIR"
   before_script:
-    - cd $working_directory
+    - cd ${working_directory}
 
 .base_ansible:
   extends: .base_tpl
   variables:
     ANSIBLE_VAULT_PASSWORD_FILE: .vault_pass
   before_script:
-    - cd $working_directory
+    - cd ${working_directory}
     - test -z ${ANSIBLE_VAULT_PASSWORD} || echo ${ANSIBLE_VAULT_PASSWORD} > ${ANSIBLE_VAULT_PASSWORD_FILE}
     - test -d ansible && chmod 750 ansible
 
@@ -43,7 +44,7 @@ variables:
     ## without extra base64 encoding.
     ## https://gitlab.com/gitlab-examples/ssh-private-key/issues/1#note_48526556
     - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
-    - cd $working_directory
+    - cd ${working_directory}
 
 # --------[ Node ]--------
 .node-cache-push:
@@ -67,13 +68,30 @@ variables:
   image:    node:14.15.4-slim 
 
 # --------[ Java ]--------
+.java-cache-push:
+  cache:
+    policy: push
+    key: "java-$CI_COMMIT_REF_SLUG"
+    paths:
+      - ${working_directory}/target/*.jar
+
+.java-cache-pull:
+  cache:
+    policy: pull
+    key: "java-$CI_COMMIT_REF_SLUG"
+    paths:
+      - ${working_directory}/target/*.jar
+
 .java:
-  extends: .base_tpl
+  extends:
+    - .base_tpl
+    - .java-cache-pull
   image: maven:${MAVEN_VERSION}-${JDK_TYPE}-${JAVA_VERSION}
   variables:
     MAVEN_ACTION: "-version"
   script:
-    - mvn ${MAVEN_CLI_OPTS} ${MAVEN_ACTION}
+    - mvn ${MAVEN_CLI_OPTS} ${MAVEN_ACTION} ${MAVEN_SETTINGS}
+
 
 # --------[ Container ]--------
 .container:build: