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=trueekleyerek build konfigürasyon aşamasını önbellekleyebilirsiniz. Tekrar eden build’lerde ciddi hız kazancı sağlar. - Build cache kullan:
org.gradle.caching=trueile değişmeyen task’ların çıktılarını yeniden kullanabilirsiniz. - Paralel derlemeyi aç:
org.gradle.parallel=trueayarı 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-daemonkullanı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.
