Maven, Transitive Dependencies ve Sürüm Yönetimi

Duygu Demirbaş
Kodcular
Published in
3 min readAug 13, 2022

Java uygulamalarında uygulamanın yazılmasından, sunucuya deploy edilmesine kadar geçen süreç bağımlılıkların düzenlenmesi, uygulamanın derlenmesi, testlerin koşulması, uygulamanın paketlenmesi gibi bir dizi işlemden oluşur. Bu işlemlerin insan eli ile yönetilmesi yerine Apache Vakfı tarafından geliştirilen Maven, Java geliştiricilerinin bu süreçleri daha iyi yönetebilmesi ve bir standart oluşturulması için geliştirilmiştir. Bu sayede Maven projelerinde çalışan biri, bir diğer projenin yapısını kolayca kavrar ve hızlıca geliştirme sürecine geçebilir.

MAVEN NEDİR ?

  • Maven bir build aracı olarak bilinse de aslında gelişmiş özelliklerinden dolayı bir proje yönetim aracı olarak da tanımlayabiliriz. Basit olarak ifade etmek gerekirse kaynak kodları derler ve bir artifact(ürün) oluşturur.
  • Standart dosya dizin yapısı sunarak, tüm Maven projelerinde geliştiricinin kolaylıkla geliştirme yapmasını, aradığını bulabilmesini sağlar.
  • Bağımlılıkları (dependency) yönetir. Bir projede kullanılan kütüphaneleri otomatik olarak Maven’ın merkez deposundan (Maven Central Repository) çekerek bilgisayarımızda bulunan local repository’e indirir ve projenizde kullanabilmenizi sağlar.
  • Maven’ın en güzel özelliklerinden biri ise kullandığınız bir kütüphane başka kütüphanelere bağımlıysa o bağımlı olduğu kütüphaneleri de indirir ve projenize otomatik olarak ekler.

MAVEN PROJE YAPISI

Yeni bir Maven projesi oluşturğunuzda aşağıdaki yapıda oluşur, projenin ana dizininde yer alan bir POM.xml oluştuğunu görürsünüz.

Maven Proje Yapısı

POM.xml Maven’ın temel yapı taşlarındandır, içinde projeye ait meta bilgileri, bağımlılıkları, pluginleri, paketleme seçeneklerini ve konfigürasyonları barındırır. Build aşamasında Maven bu pom.xml’i okur ve buradaki bilgilere göre proje derlenir, paketlenir ve target dosyası altında projenize ait .jar (default) dosyası oluşur.

MAVEN YAŞAM DÖNGÜSÜ

Maven yaşam döngüsü 8 fazdan oluşur. Fazlar sıralı olarak çalışır. Bir faz çalıştırıldığında öncesindeki fazlar da çalışır. Örneğin Package fazını çalıştırdığımızda sırası ile validate-compile-test fazları da çalışacaktır.

Maven’de bir faz çalıştırılmak istendiğinde mvn <PHASE> komutu kullanılır, örneğin : mvn clean ya da mvn package gibi.

BAĞIMLILIK YÖNETİMİ ( DEPENDENCY MANAGEMENT )

Maven pom.xml deki dependency leri okur ve projemizde kullandığımız kütüphaneler eğer lokal repomuzda yoksa Maven Central Repo’dan jar’ları çeker ve local repomuza indirir. Eğer kullandığımız kütüphanelerin de bağımlılıkları varsa ilgili jar’ları da düzgün bir şekilde local repomuza indirir ve projemizde kullanmamızı sağlar (Transitive Dependency). Bir çok geliştiricinin Maven tercih etmesinin sebebi de budur.

Peki Maven Sürüm Çakışmalarını Nasıl Çözüyor ?

Maven versiyonların sıralamasını String olarak tutar ve hangisinin daha yeni ya da eski olduğunu bilemez ve bağımlılık ağacındaki en yakın derinlikteki versiyonu bulup bunu kullanmaya başlar.

Bir örnek üzerinden gidelim :

pom dosyamızda aşağıdaki sıralamada olduğu gibi dependencyler (D1, D2, D3, D4) olduğunu varsayalım ve hepsi de dolaylı olarak DT ‘ye ve DT’nin de farklı versiyonlarına bağımlı olsun.

  • D1(v1) -> D11(v11) -> D12(v12) -> DT(v1.3)
  • D2(v2) -> DT(v1.2)
  • D3(v3) -> D31(v31) -> DT(v1.0)
  • D4(v4) -> DT(v1.5)

Bu durumda şu şekilde bir yöntem izler; öncelikle Graph Depth açısından bakar ve en yakın derinlikte olan 2 seçeneği bulur :DT(v1.2) ve DT(v1.5) Sonrasında ise pom’a eklenme sırasına Resolution Order bakar ve en üstte olanı alır. Aslında 1.5 versiyonu daha yeni olmasına rağmen bu algoritmaya göre 1.2 olan versiyonu kullanır.

Peki biz aslında daha yeni olan sürümü kullanmak istiyorsak ?

Bunun için iki seçeneğimiz var, biri bu dependency’i direk olarak pom’a eklemek, diğeri ise pom dosyasında dependencyManagementkısmına özellikle istediğimiz versiyonu yazarak override etmek.

Beğendiyseniz alkışlayarak ya da paylaşarak destek olabilirsiniz.

Kaynak : reflectoring.io

--

--