Arşivler

java.evolved Nedir? Modern Java Agent Skill ile Java 8 Kodunu Java 25’e Taşımak

Eski Java kodunu java.evolved ve modern-java agent skill ile Java 25'e taşımak

Java, Java 8’den sonra önemli ölçüde değişti. Özellikle records, sealed classes, pattern matching, virtual threads ve ScopedValue gibi birçok yeni özellik dile ve JDK’ya girdi. Buna rağmen gerçek projelerde hâlâ Java 6–8 döneminden kalan kullanım şekilleriyle sıkça karşılaşıyoruz.

Bu yazıda öncelikle eski ve modern Java kullanımlarını yan yana gösteren java.evolved projesine bakacağız. Ardından projenin sunduğu modern-java agent skill’i kullanarak bilerek eski Java alışkanlıklarıyla hazırladığım bir Student API’yi Java 25’e taşıyacağız.

Ayrıca örnekte kullandığım projenin tamamına GitHub üzerinden ulaşabilirsiniz.

java.evolved Nedir?

java.evolved, eski Java kullanımlarını modern karşılıklarıyla yan yana gösteren açık kaynaklı bir proje.

Şu anda proje, 17 JDK sürümünü kapsayan 135 modern Java desenine sahip. Üstelik her örnek, eski kullanım ile modern karşılığını yan yana gösteriyor.

Örneğin klasik bir Java sınıfı ile record, eski switch kullanımı ile switch expressions veya Thread tabanlı concurrency yaklaşımı ile virtual threads arasındaki farkı doğrudan görebiliyoruz.

java.evolved Neyi Amaçlıyor?

Java’nın altı aylık sürüm döngüsüyle birlikte düzenli olarak yeni dil özellikleri ve API’ler geliyor.

Ancak bunların tamamını JEP dokümanlarından takip etmek her zaman kolay değil. Öte yandan çalışan kodlara dokunmak istemediğimiz için eski kullanımları yeni projelere de taşımaya devam edebiliyoruz.

Bu nedenle proje, örnekleri farklı kategoriler altında topluyor:

KategoriÖrnekler
LanguageRecords, sealed classes, pattern matching, switch expressions, var, unnamed variables
CollectionsImmutable factory’ler, sequenced collections, unmodifiable collector’lar
StringsText blocks, isBlank(), strip(), repeat(), formatted()
StreamstoList(), mapMulti(), takeWhile(), gatherers
ConcurrencyVirtual threads, structured concurrency, scoped values, ExecutorService
I/OFiles.readString(), Path.of(), transferTo(), HTTP Client
ErrorsrequireNonNullElse(), record tabanlı hatalar, helpful NPE
Date/Timejava.time, Duration, Period, DateTimeFormatter
SecurityTLS, SecureRandom, KDF, PEM
ToolingJShell, tek dosya çalıştırma, JFR, compact source files, AOT
EnterpriseEJB → CDI, JDBC → JPA / Jakarta Data, Spring yapılandırması

Özellikle eski bir kod tabanını incelerken elimizdeki kullanımın modern Java’daki karşılığını hızlıca görmek için oldukça kullanışlı.

modern-java Agent Skill Nedir?

Bunun yanı sıra proje, yapay zeka tabanlı kodlama araçları için modern-java isminde bir agent skill’i de sunuyor.

Skill temel olarak üç adımda çalışıyor:

  1. Detect: Maven, Gradle, toolchain, CI ve runtime gibi kaynaklardan hedef Java sürümünü tespit ediyor.
  2. Bound: Önerileri bu Java sürümü ve öncesinde final olmuş özelliklerle sınırlandırıyor.
  3. Recommend: Kodu inceliyor ve uygun modern Java karşılıklarını öneriyor.

modern-java Skill Kurulumu

Örneğin Claude Code için repository’yi indirip skill’i ekleyebiliriz:

git clone --depth 1 https://github.com/javaevolved/javaevolved.github.io.git

mkdir -p ~/.claude/skills

cp -R javaevolved.github.io/agent-plugins/modern-java-development/skills/modern-java ~/.claude/skills/
Code language: JavaScript (javascript)

Ancak sadece belirli bir projede kullanmak istersek .claude/skills/modern-java altında tutmamız yeterli.

GitHub Copilot CLI tarafında ise:

copilot plugin marketplace add javaevolved/javaevolved.github.io
copilot plugin install modern-java-development@javaevolved

kullanabiliriz.

Örnek Proje: Eski Java ile Yazılmış Student API

Ardından skill’i biraz daha gerçekçi bir proje üzerinde denemek istedim.

Bunun için framework kullanmadan, JDK’nın com.sun.net.httpserver sunucusu üzerinde çalışan bir Student API hazırladım.

Proje; öğrenci CRUD işlemleri, ders kayıtları, kredi limiti, GNO hesaplama, transkript, istatistikler, CSV kalıcılığı, yedekleme, bildirim kuyruğu ve API key doğrulaması gibi özellikler içeriyor.

Ayrıca main branch’i Java 8 hedefliyor ve bilinçli olarak eski Java kullanımları içeriyor:

  • POJO’lar ve int sabitler
  • Vector, Hashtable, Enumeration
  • Anonymous class’lar
  • SimpleDateFormat ve Calendar
  • instanceof + cast zincirleri
  • wait/notify
  • Timer/TimerTask
  • double-checked locking
  • Random ile API key üretimi
  • FileReader/FileWriter
  • Class.newInstance()

Yani amacım bunların tamamını mekanik olarak değiştirmek değil, skill’in gerçek bir kod tabanında nasıl davrandığını görmekti.

Skill Projeyi Nasıl Ele Aldı ve Ne Yaptı?

İlk olarak projenin hedef Java sürümünü tespit etti.

Makinemde JDK 26 kurulu olmasına rağmen pom.xml içerisindeki Java 8 ayarını esas aldı:

selected: Java 8
source: maven-source

runtime: Java 26
Code language: HTTP (http)

Daha sonra modernizasyon hedefini Java 25 olarak verdiğimde ise mevcut Java 8 ayarı ile çakışmayı ayrıca raporladı.

Bu bence skill’in en önemli taraflarından biri. Makinedeki JDK sürümüne bakıp rastgele modern Java özelliği önermek yerine projenin gerçek build ayarlarını dikkate alıyor.

Önce yalnızca Java hedefini 25’e yükselttim ve mevcut testleri çalıştırdım. Sonuç olarak kod tarafında hiçbir değişiklik yapmadan 19 testin tamamı geçti.

Bundan sonra modernizasyon başladı.

Skill’in Yaptığı Modernizasyonlar

Bu aşamada skill, projedeki çok sayıda eski Java kullanımını modern karşılıklarıyla değiştirdi.

Örneğin klasik Student POJO’su record haline geldi:

Benzer şekilde int ile tutulan durumlar enum yapısına dönüştü.

Ayrıca uzun instanceof ve cast zincirlerinin yerini pattern matching for switch aldı:

Bunun yanı sıra skill, exception yapısını sealed class ile yeniden düzenledi ve HTTP response’larda record pattern kullandı.

Concurrency tarafında ise en belirgin değişikliklerden biri eski wait/notify kuyruğunun ortadan kalkması oldu.

Aynı şekilde:

  • Timer/TimerTaskScheduledExecutorService
  • Fixed thread pool → Virtual Threads
  • Request context → ScopedValue
  • SimpleDateFormatjava.time
  • RandomSecureRandom
  • Elle hex üretimi → HexFormat
  • FileReader/FileWriterFiles + UTF-8
  • Class.newInstance()getDeclaredConstructor().newInstance()
  • trim().length() == 0isBlank()
  • Anonymous Comparator → Comparator.comparing()
  • JUnit 4 → JUnit 6

şeklinde dönüşümler de gerçekleşti.

Ancak burada önemli olan, her eski API’yi yenisiyle değiştirmek değil. Çünkü skill, kullanacağı özelliğin hedef Java sürümünde final olup olmadığını da dikkate alıyor.

Modernizasyon Sonrası Sonuçlar

Modernizasyon tamamlandığında iki branch arasında şöyle bir sonuç oluştu:

ÖlçümJava 8Java 25
javac -Xlint:all uyarısı2690
Java kod satırı25891963
Birim test1923

Böylece Java kodu yaklaşık %24 azaldı.

30 farklı HTTP senaryosunu iki branch üzerinde çalıştırarak sonuçlarını karşılaştırdım. Üstelik validation hataları, 401, 404, 409, transkript ve istatistik endpoint’leri dahil karşılaştırdığım HTTP çıktılarında fark oluşmadı.

Ayrıca modernizasyon sırasında eski koddaki birkaç problem de ortaya çıktı.

Örneğin başarısız bir öğrenci güncellemesinde 409 Conflict dönmesine rağmen mutable nesnenin bazı alanları değişebiliyordu. Buna karşın record tabanlı yeni yapı, nesneyi yalnızca bütün validation kuralları başarılı olduktan sonra kaydediyor.

Bunun dışında;

  • Random ile API key üretimi,
  • default locale ile toLowerCase() kullanımı,
  • platform charset’ine bağlı dosya işlemleri,
  • paylaşılan SimpleDateFormat,
  • InterruptedException‘ın yutulması

gibi problemler de modernizasyon sırasında ortadan kalktı.

Sonuç

Sonuç olarak java.evolved, eski Java kullanımlarının modern karşılıklarını hızlıca görmek için oldukça güzel bir kaynak.

modern-java agent skill ise bunun özellikle AI destekli geliştirme tarafındaki önemli bir problemini çözüyor: Kodlama asistanının önerilerini projenin gerçekten kullandığı Java sürümüne göre sınırlandırıyor.

Projenin Kaynak Kodu

Projenin Kaynak Kodlarına Ulaş

  • main: Java 8 sürümü
  • modernize/java-25: Java 25 sürümü
  • MODERNIZATION.md: modernizasyon detayları