Ringkasan Eksekutif
Saya baru baca tulisan dari dua orang di Info Support (Maarten Mulders dan Kasper van de Wetering) yang berbagi pengalaman nyata memasang Maven Build Cache Extension di pipeline Azure DevOps mereka. Yang menarik bukan "cara enable cache"-nya—itu bagian mudah—tapi daftar masalah kecil yang baru muncul setelah cache jalan, dan bagaimana mereka menyelesaikannya satu per satu.
Masalah yang Diselesaikan
Build cache ini awalnya donasi dari tim Deutsche Bank ke Apache Maven pada 2019, yang menurut mereka berhasil memangkas build dari 45-60 menit jadi 1-2 menit di lingkungan sendiri. Idenya mirip Gradle build cache: alih-alih mengandalkan timestamp file (tidak reliable lintas platform/filesystem), extension ini pakai hash non-cryptographic yang cepat seperti XX-hash untuk mendeteksi apakah input suatu modul berubah. Karena cache-nya bekerja per modul Maven—bukan per keseluruhan project—makin banyak modul kecil di project, makin besar potensi penghematannya: modul yang tidak tersentuh di satu PR bisa langsung di-restore dari cache tanpa compile/test/package ulang. Ini pas untuk pipeline PR validation yang sering men-trigger build penuh padahal cuma satu-dua modul yang berubah.
Fitur Utama dan Contoh Kode
Setup dasarnya cuma menambah extensions.xml di folder .mvn:
<extensions xmlns="http://maven.apache.org/EXTENSIONS/1.1.0">
<extension>
<groupId>org.apache.maven.extensions</groupId>
<artifactId>maven-build-cache-extension</artifactId>
<version>1.3.0</version>
</extension>
</extensions>Tapi karena Azure DevOps build agent selalu start dari workspace bersih, cache lokal di ~/.m2/build-cache hilang tiap run. Mereka pilih opsi yang lebih simpel dibanding remote repository, yaitu task Cache@2 di pipeline:
- task: Cache@2
inputs:
key: 'maven-build-cache | "$(Agent.OS)" | pom.xml'
path: $(MAVEN_BUILD_CACHE_FOLDER)
restoreKeys: |
maven-build-cache | "$(Agent.OS)"Poin yang saya catat: mereka sengaja tidak membuat cache key terlalu spesifik (misalnya memasukkan semua isi pom.xml), karena extension sudah menghitung fingerprint sendiri per modul—kalau key Azure DevOps-nya terlalu detail, itu cuma menduplikasi logika Maven dan malah menambah cache miss.
Tiga masalah konkret yang mereka temui cukup instruktif:
- Restore artifact saja tidak cukup. Default-nya cache hanya mengembalikan artifact akhir (jar/war/ear), padahal tool seperti JaCoCo dan Surefire butuh folder
target/classes,target/test-classes,target/surefire-reports,target/site/jacoco. Fix-nya menambahattachedOutputsdimaven-build-cache-config.xmlsupaya direktori itu ikut tersimpan.
- SonarCloud bentrok dengan reactor. Goal
sonar:sonaritu berdiri sendiri, bukan lifecycle phase, jadi Build Cache Extension mencoba men-restore-nya seolah phase biasa—dan gagal di build kedua. Solusinya memisahkan jadi dua taskMaven@4: satu untukpackage, satu untuksonar:sonar. Tapi ini memunculkan masalah baru: proses Maven kedua kehilangan context reactor, jadi dependency antar-modul internal tidak ketemu di local repo (muncul error "could not be resolved... but seem to be part of the reactor"). Mereka akhirnya mengganti goal pertama daripackagekeinstall, dan memaksa goalinstallselalu jalan lewatexecutionControl/runAlways(menyasarmaven-install-plugin) di config XML meski modulnya di-restore dari cache.
- OWASP Dependency Check juga dipisah. Karena plugin ini terikat ke dependency graph & data vulnerability yang berubah-ubah—bukan output build yang reusable—mereka keluarkan dari main execution dan jalankan sebagai goal terpisah
org.owasp:dependency-check-maven:aggregatedi task Maven sendiri.
Deployment pipeline-nya sengaja tidak pakai cache sama sekali—mereka mau artifact yang dideploy selalu hasil clean build.
Dampak dan Catatan Upgrade
Angka yang mereka laporkan: sebelum cache, build PR penuh makan waktu sekitar 18 menit (14 menit untuk compile/test/package, 4 menit sisanya untuk pre/post-step plus analisis SonarCloud). Build pertama di satu branch tetap full build seperti biasa (belum ada yang bisa di-restore), tapi build-build berikutnya langsung terasa bedanya—step Maven install bisa secepat 1 menit di best case, rata-rata 5-6 menit, sehingga total durasi pipeline turun sekitar 50%.
Yang perlu disadari sebelum ikut memasang ini: cache Azure DevOps bersifat immutable dan scoped per branch, jadi setiap PR branch baru tetap butuh satu full build dulu sebelum bisa menikmati cache-nya (mereka mempertimbangkan "priming" cache dari main branch agar PR pertama pun lebih cepat, tapi ini belum diimplementasikan). Tidak ada versi minimum Maven yang disebutkan selain extension 1.3.0 dan task Maven@4/Cache@2 khusus Azure DevOps—kalau stack CI-mu beda (GitLab, GitHub Actions), prinsipnya sama tapi mekanisme persist cache antar-run harus dicari sendiri. Saran praktis mereka yang menurut saya paling berguna: ukur baseline dulu sebelum mengubah konfigurasi apa pun, cek file apa saja yang dibutuhkan step-step setelah build (jangan asumsi artifact akhir saja cukup), dan hati-hati kalau build & analysis dipisah ke invocation Maven yang berbeda—reactor context-nya ikut hilang.
---
Pertama diumumkan di Foojay.io (Friends of OpenJDK). Baca sumber aslinya untuk detail lengkap.