Gradle Kurulumu ve Java Projesi Derleme

Java projelerinde dependency yönetimi ve derleme süreçleri her zaman baş ağrısı olmuştur. Maven’dan sonra ortaya çıkan Gradle, Groovy ve Kotlin DSL desteğiyle hem esnek hem de güçlü bir build aracına dönüştü. Bu yazıda Gradle’ı sıfırdan kurup gerçek bir Java projesi derleyene kadar her adımı ele alacağız.

Gradle Nedir ve Neden Kullanılır?

Gradle, açık kaynaklı bir build otomasyon aracıdır. Maven’ın XML tabanlı yapılandırmasının aksine Gradle, Groovy veya Kotlin DSL kullanır. Bu sayede build script’leri çok daha okunabilir ve programatik hale gelir.

Gradle’ın öne çıkan özellikleri şunlardır:

  • Artımlı derleme: Değişmeyen dosyaları yeniden derlemez, bu da büyük projelerde ciddi zaman kazandırır
  • Build cache: Önceki build sonuçlarını önbellekte tutar
  • Paralel task çalıştırma: Bağımsız task’ları eş zamanlı çalıştırabilir
  • Plugin ekosistemi: Java, Android, Kotlin, Spring Boot gibi onlarca resmi plugin
  • Multi-project build desteği: Mikroservis projelerinde modüler yapı kurulabilir

Özellikle Android geliştirme dünyasının fiili standardı haline gelmesiyle birlikte Gradle, enterprise Java projelerinde de Maven’ın yerini almaya başladı.

Ön Koşullar: Java Kurulumu

Gradle çalışmak için JVM’e ihtiyaç duyar. Sisteminizde Java kurulu olmalı. Gradle 8.x sürümleri Java 8 ve üzerini destekler ancak Java 17 LTS kullanmanızı tavsiye ederim.

# Ubuntu/Debian için Java kurulumu
sudo apt update
sudo apt install openjdk-17-jdk -y

# Kurulumu doğrula
java -version
javac -version

# JAVA_HOME ortam değişkenini ayarla
echo 'export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64' >> ~/.bashrc
echo 'export PATH=$PATH:$JAVA_HOME/bin' >> ~/.bashrc
source ~/.bashrc
# CentOS/RHEL/Rocky Linux için
sudo dnf install java-17-openjdk-devel -y

# Java Home yolunu bul
dirname $(dirname $(readlink -f $(which java)))

Windows üzerinde çalışıyorsanız, JAVA_HOME sistem ortam değişkenini kontrol panelinden ayarlamanız gerekir. C:Program FilesJavajdk-17 gibi bir yol olmalıdır.

Gradle Kurulum Yöntemleri

Gradle’ı kurmanın birkaç farklı yolu var. Hangisini seçeceğiniz kullanım senaryonuza göre değişir.

Yöntem 1: Manuel Kurulum (Önerilen)

# Gradle 8.5 indir (güncel sürüm için gradle.org/releases kontrol edin)
wget https://services.gradle.org/distributions/gradle-8.5-bin.zip -P /tmp

# Hedef dizini oluştur
sudo mkdir -p /opt/gradle

# Arşivi aç
sudo unzip -d /opt/gradle /tmp/gradle-8.5-bin.zip

# Sembolik link oluştur (sürüm yönetimi için kullanışlı)
sudo ln -s /opt/gradle/gradle-8.5 /opt/gradle/current

# PATH'e ekle
echo 'export GRADLE_HOME=/opt/gradle/current' >> ~/.bashrc
echo 'export PATH=$PATH:$GRADLE_HOME/bin' >> ~/.bashrc
source ~/.bashrc

# Kurulumu doğrula
gradle --version

Yöntem 2: SDKMAN ile Kurulum

SDKMAN, JVM tabanlı araçları yönetmek için harika bir araçtır. Birden fazla Gradle sürümü arasında geçiş yapmak gerektiğinde işi çok kolaylaştırır.

# SDKMAN kur
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"

# Mevcut Gradle sürümlerini listele
sdk list gradle

# En son stabil sürümü kur
sdk install gradle

# Belirli bir sürüm kur
sdk install gradle 8.5

# Sürümler arasında geçiş yap
sdk use gradle 7.6.3

Yöntem 3: Homebrew ile macOS’ta Kurulum

brew install gradle
gradle --version

Yöntem 4: apt ile Ubuntu/Debian

Resmi Ubuntu depolarındaki Gradle genellikle eski sürüm içerir. Güncel sürüm için manuel kurulum veya SDKMAN tercih edin. Ama hızlıca bir şeyler denemek istiyorsanız:

sudo apt install gradle -y

Gradle Wrapper Kavramı

Sysadmin olarak bu kısmı özellikle vurgulamak istiyorum çünkü production ortamlarında çok kritik. Gradle Wrapper (gradlew), projeye dahil edilen küçük bir script’tir ve projenin gerektirdiği Gradle sürümünü otomatik olarak indirip kullanır. Sisteminizde Gradle kurulu olmasa bile çalışır.

Neden önemli?

  • CI/CD pipeline’larında ekstra kurulum adımı gerekmez
  • Takım üyeleri farklı Gradle sürümleri kullanmaz
  • Sürüm tutarsızlığından kaynaklanan “bende çalışıyor” problemleri ortadan kalkar

Wrapper kullananlar için build komutu gradle yerine ./gradlew olur. Bunu aklınızda tutun.

İlk Gradle Projesi: Hello World

Teori yeterli, artık elleri kirletelim.

# Proje dizini oluştur
mkdir -p ~/projects/hello-gradle
cd ~/projects/hello-gradle

# Gradle projesini başlat
gradle init

gradle init komutu sizi interaktif bir sihirbaza yönlendirir. Sorulara şu şekilde cevap verin:

  • Select type of project: application
  • Select implementation language: Java
  • Select build script DSL: Groovy (veya Kotlin)
  • Select test framework: JUnit Jupiter
  • Project name: hello-gradle
  • Source package: com.example

Oluşturulan yapıya bakalım:

tree .
# hello-gradle/
# ├── app/
# │   ├── build.gradle
# │   └── src/
# │       ├── main/java/com/example/App.java
# │       └── test/java/com/example/AppTest.java
# ├── gradle/wrapper/
# │   ├── gradle-wrapper.jar
# │   └── gradle-wrapper.properties
# ├── gradlew
# ├── gradlew.bat
# └── settings.gradle

Oluşturulan app/build.gradle dosyasına bakalım:

// app/build.gradle
plugins {
    id 'application'
}

repositories {
    mavenCentral()
}

dependencies {
    testImplementation libs.junit.jupiter
    implementation 'com.google.guava:guava:32.1.2-jre'
}

application {
    mainClass = 'com.example.App'
}

tasks.named('test') {
    useJUnitPlatform()
}

Şimdi projeyi derleyelim ve çalıştıralım:

# Projeyi derle
./gradlew build

# Uygulamayı çalıştır
./gradlew run

# Testleri çalıştır
./gradlew test

# Temizle ve yeniden derle
./gradlew clean build

Gerçek Dünya Senaryosu: Spring Boot Uygulaması

Basit Hello World’den çıkıp biraz daha gerçekçi bir senaryoya geçelim. Bir REST API uygulaması kuralım.

mkdir -p ~/projects/rest-api-demo
cd ~/projects/rest-api-demo
gradle init --type java-application --dsl groovy

build.gradle dosyasını Spring Boot için güncelleyelim:

// build.gradle
plugins {
    id 'java'
    id 'org.springframework.boot' version '3.2.0'
    id 'io.spring.dependency-management' version '1.1.4'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'

java {
    sourceCompatibility = JavaVersion.VERSION_17
    targetCompatibility = JavaVersion.VERSION_17
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

test {
    useJUnitPlatform()
}

// Fat JAR oluştur (tüm bağımlılıkları içeren)
bootJar {
    archiveFileName = "app.jar"
}

Projeyi derleyip JAR oluşturalım:

# Bağımlılıkları indir ve derle
./gradlew build

# Sadece JAR oluştur (testleri atla)
./gradlew bootJar -x test

# Uygulamayı Gradle üzerinden çalıştır
./gradlew bootRun

# Oluşan JAR'ı doğrudan çalıştır
java -jar build/libs/app.jar

Dependency Yönetimi

Gradle’da bağımlılık kapsamları (configurations) Maven’dan biraz farklı çalışır:

  • implementation: Compile ve runtime’da kullanılır, bağımlı modüllere aktarılmaz
  • api: implementation gibi ama bağımlı modüllere de aktarılır (library projeleri için)
  • compileOnly: Sadece derleme sırasında kullanılır, JAR’a dahil edilmez
  • runtimeOnly: Sadece runtime’da kullanılır, derleme sırasında classpath’te olmaz
  • testImplementation: Sadece test kodları için
  • testCompileOnly: Sadece test derleme aşaması için
dependencies {
    // Temel bağımlılık
    implementation 'org.apache.commons:commons-lang3:3.13.0'

    // Dinamik sürüm (dikkatli kullanın, build tekrarlanabilirliğini bozar)
    // implementation 'org.apache.commons:commons-lang3:3.+'

    // Sadece derleme için (Lombok gibi annotation processor'lar)
    compileOnly 'org.projectlombok:lombok:1.18.30'
    annotationProcessor 'org.projectlombok:lombok:1.18.30'

    // Sadece runtime için (database driver gibi)
    runtimeOnly 'com.h2database:h2'

    // Test bağımlılıkları
    testImplementation 'org.mockito:mockito-core:5.7.0'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

Bağımlılık ağacını görmek için çok kullanışlı bir komut var:

# Tüm bağımlılık ağacını göster
./gradlew dependencies

# Belirli bir configuration için
./gradlew dependencies --configuration runtimeClasspath

# Belirli bir bağımlılığı neden kullandığını araştır
./gradlew dependencyInsight --dependency spring-core --configuration runtimeClasspath

Multi-Project Build Yapısı

Mikroservis veya modüler monolith projelerinde birden fazla alt modül olur. Gradle bu yapıyı çok iyi destekler.

my-company-app/
├── settings.gradle
├── build.gradle (root)
├── core/
│   └── build.gradle
├── web/
│   └── build.gradle
└── service/
    └── build.gradle

settings.gradle dosyası:

// settings.gradle
rootProject.name = 'my-company-app'

include 'core'
include 'web'
include 'service'

Root build.gradle:

// Tüm subproject'lere ortak konfigürasyon uygula
subprojects {
    apply plugin: 'java'

    java {
        sourceCompatibility = JavaVersion.VERSION_17
    }

    repositories {
        mavenCentral()
    }

    // Tüm projelerde ortak bağımlılıklar
    dependencies {
        testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0'
    }

    test {
        useJUnitPlatform()
    }
}

web/build.gradle:

dependencies {
    // core modülüne bağımlılık
    implementation project(':core')
    implementation project(':service')

    implementation 'org.springframework.boot:spring-boot-starter-web'
}

Tüm projeyi tek komutla derlemek:

# Tüm subproject'leri derle
./gradlew build

# Sadece web modülünü derle
./gradlew :web:build

# Belirli bir modülün testlerini çalıştır
./gradlew :service:test

# Paralel build (CI'da ciddi hız kazandırır)
./gradlew build --parallel

CI/CD Pipeline Entegrasyonu

Gerçek dünyada Gradle’ı çoğunlukla CI/CD sistemleri içinde kullanırız. Birkaç pratik ipucu:

Build cache paylaşımı için gradle.properties dosyasına ekleyin:

# gradle.properties
org.gradle.caching=true
org.gradle.parallel=true
org.gradle.daemon=false  # CI ortamında daemon kapatılmalı
org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m

Jenkins veya GitLab CI için örnek bir script:

#!/bin/bash
# ci-build.sh

set -e

echo "Java sürümü:"
java -version

echo "Gradle wrapper sürümü:"
./gradlew --version

# Temiz build
./gradlew clean build 
    --no-daemon 
    --stacktrace 
    --info 
    -Penv=production

# Test raporlarını kontrol et
if [ -d "build/reports/tests" ]; then
    echo "Test raporları oluşturuldu: build/reports/tests/test/index.html"
fi

# JAR boyutunu raporla
JAR_FILE=$(find build/libs -name "*.jar" | head -1)
if [ -n "$JAR_FILE" ]; then
    echo "Oluşturulan JAR: $JAR_FILE"
    echo "Boyut: $(du -sh $JAR_FILE | cut -f1)"
fi

Sık Kullanılan Gradle Komutları

Günlük hayatta en çok kullandığım komutları derledim:

  • ./gradlew tasks: Kullanılabilir tüm task’ları listeler
  • ./gradlew build: Projeyi derler, test eder ve paketler
  • ./gradlew clean: Build dizinini temizler
  • ./gradlew test: Testleri çalıştırır
  • ./gradlew test --tests "com.example.MyTest": Belirli bir test sınıfını çalıştırır
  • ./gradlew jar: Sadece JAR oluşturur, test etmez
  • ./gradlew -x test build: Testleri atlayarak build yapar
  • ./gradlew --refresh-dependencies: Bağımlılık önbelleğini temizler
  • ./gradlew wrapper --gradle-version 8.5: Wrapper sürümünü günceller
  • ./gradlew --scan: Build scan raporu oluşturur (hata ayıklama için harika)
  • ./gradlew --profile: Performans profili çıkarır

Yaygın Sorunlar ve Çözümleri

Problem: “Could not resolve dependencies” hatası

Genellikle ağ erişim sorunu ya da yanlış repository konfigürasyonudur.

# Proxy arkasındaysanız gradle.properties'e ekleyin
systemProp.http.proxyHost=proxy.sirket.com
systemProp.http.proxyPort=8080
systemProp.https.proxyHost=proxy.sirket.com
systemProp.https.proxyPort=8080

# Bağımlılık önbelleğini temizle
./gradlew --refresh-dependencies build

Problem: Daemon sorunları

# Tüm Gradle daemon'larını durdur
./gradlew --stop

# Daemon olmadan çalıştır
./gradlew build --no-daemon

Problem: OutOfMemoryError during build

Büyük projelerde heap alanı yetersiz kalabilir.

# gradle.properties dosyasına ekle
org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=1g -XX:+HeapDumpOnOutOfMemoryError

Problem: Wrapper checksum hatası

# Wrapper'ı yeniden oluştur
gradle wrapper --gradle-version 8.5 --distribution-type bin

Performans İpuçları

Build sürelerini kısaltmak için birkaç pratik öneri:

  • Configuration cache’i etkinleştir: org.gradle.configuration-cache=true ekleyerek build konfigürasyon aşamasını önbellekleyebilirsiniz. Tekrar eden build’lerde ciddi hız kazancı sağlar.
  • Build cache kullan: org.gradle.caching=true ile değişmeyen task’ların çıktılarını yeniden kullanabilirsiniz.
  • Paralel derlemeyi aç: org.gradle.parallel=true ayarı multi-project build’lerde işe yarar.
  • Daemon’ı etkin bırakın: Development ortamında daemon kapatmayın, ilk build’den sonraki build’ler çok hızlanır. Sadece CI’da --no-daemon kullanın.
  • Gereksiz bağımlılıklardan kaçının: Her eklenen bağımlılık derleme süresini uzatır.

Sonuç

Gradle, modern Java ekosisteminin vazgeçilmez bir parçası haline geldi. Maven’ın katı XML yapısına kıyasla çok daha esnek bir build sistemi sunarken, Gradle Wrapper sayesinde ortam tutarsızlıkları da büyük ölçüde ortadan kalkıyor. Bu yazıda ele aldığımız konuları özetlemek gerekirse: SDKMAN ile kurulum production öncesi geliştirme ortamları için ideal, Gradle Wrapper ise CI/CD ve ekip projelerinde standart olmalı. Multi-project build yapısı büyüyen projelerde modülerliği korumanın en temiz yolu. Build cache ve paralel derleme gibi optimizasyonları erkenden etkinleştirirseniz büyük projelerde bunun farkını hissedersiniz.

Yeni bir Java projesine başlarken gradle init komutunun size sunduğu proje iskeletini kullanın, wrapper’ı her zaman kaynak kodunuzla birlikte commit’leyin ve gradle.properties dosyasında JVM argümanlarını optimize etmeyi unutmayın. Sorularınız olursa yorum bölümünde buluşalım.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir