Generics ve Reflection ile genelleştirilmiş dizi yaratma

Daha önceden buna benzer bir kodu Java 1.4 ile generics kullanmadan yazmıştım. Ancak Generics’in sağladığı özelliklerle tip dönüşümü kodunu metod içine alarak dışarıya tip güvenli bir metod sunabildim. Şimdi örnek kullanım ile metodumuzu görelim.

import java.lang.reflect.Array;

public class GenericArrayDemo {

	public static void main(String[] args) {
		System.out.println(getArray(String.class,10).getClass().getSimpleName());
		String theArray[] = getArray(String.class, 10);
	}

	@SuppressWarnings("unchecked")
	public static <T> T[] getArray(Class<T> clazz,int size) {
		T theArray[] = (T[])Array.newInstance(clazz, size);
		for(int i=0;i<size;i++)
			try {
				theArray[i]=clazz.newInstance();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		return theArray;
	}
}

Burada çıktı olarak String[] üretilmekte ve oluşan dizi direk ve yalnız String dizisine atanabilmektedir. Şimdi örneğimizi genişletelim ve metodun sadece Number sınıfının alt sınıflarını üretebilmesini sağlayalım.

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class GenericArrayDemo {

	public static void main(String[] args) {
		/* Bu satırlar artık Number altsınıfı beklediğimizden hata alacaktır.
		System.out.println(getArray(String.class,10).getClass().getSimpleName());
		String theArray[] = getArray(String.class, 10);
		*/
		System.out.println(getArray(Double.class,10).getClass().getSimpleName());
		Long theArray[] = getArray(Long.class, 10);
		for (Long long1 : theArray) {
			System.out.println(long1);
		}
	}

	@SuppressWarnings("unchecked")
	public static <T extends Number> T[] getArray(Class<T> clazz,int size) {
		T theArray[] = (T[])Array.newInstance(clazz, size);
		for(int i=0;i<size;i++)
			try {
				/* 
				 * Number alt sınıfları parametresiz constructor
				 * içermediği için 0 ile ilklendiriyoruz
				 */
				Constructor<T> constructor=clazz.getConstructor(String.class);
				theArray[i]=constructor.newInstance("0");
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
		return theArray;
	}
}

Bu metod ise Double[] ve ardından 10 adet sıfır yazdırmaktadır. Artık Number alt sınıfı beklediğinden bir önceki örnekteki satırlar çalışmamaktadır. Burada sınıfa ait String parametresi alan Constructor üretilmekte ve o şekilde ilklenmektedir.

Bunu benim kullanım amacım veritabanında çağırılan stored procedure sonuçlarını uyumlu bir sınıf dizisine eşleyebilen genel bir metod yazmak idi. Belki daha farklı kullanım amaçları da olabilir.


Yayınlandı gezegen, java

29 Nisan 2009

Posted In: Gezegen, java

AmaterasUML: Açık kaynak ve uyumluluk üzerine bir hikaye

Bytecode uyumluluğu ve API uyumluluğu

Java kodlarımızı derlerken derleyiciye -source ve -target parametrelerini vererek belli bir sürüme ait bytecode a derleyebiliyoruz. Tabi burada yeni sürüme ait DİL özelliklerinden feragat ediyoruz. Örnek olarak kodumuzu Java 1.4 için derlemek istersek Generics, Boxing gibi özellikleri kullanamayız. Ancak bu işlem aynı garantiyi JDK’nın sunduğu API için sağlamamaktadır. Örnek olarak Java6 ile yeni gelen bir sınıfı kullanıp Java5 ile çalıştırdığımızda ClassNotFoundException, Java6 ile yeni gelen metodu Java5 ile çalıştırdığımızda NoSuchMethodError hatası alırız. Bu durumda en emin yöntem geliştirirken hedef aldığımız minimum majör sürümü (Örn: Java5) kullanmamız olacaktır. Artık pek çok IDE proje bazında  kullanılan JRE/JDK sürümünü seçmemize izin vermektedir.

AmaterasUML Eclipse eklentisini Java5 ile çalıştıtırken aldığım hata

Gelelim hikayemizin gelişme bölümüne. Eclipse için geliştirilmiş açık kaynaklı bir UML eklentisi olan AmaterasUML tam olarak da bu sorundan müzdarip. Eklenti ikili dosyaları Java5 sisteminde çalışmasına rağmen UML oluşturması için sınıfları ekrana sürüklediğimizde java.lang.NoSuchMethodError: java.util.Arrays.copyOf([Ljava/lang/Object;I)[Ljava/lang/Object; hatası alıyoruz. Bunun sebebi ise Arrays.copyOf() metodunun Java6 ile yeni gelmiş olması.

Nasıl düzelttim?

Gelelim çözüme. Şanslıyız ki eklentimiz açık kaynak kodlu. Aslında bahsetmedim ama sorunun kaynağını bulabilmek için de projenin kaynak kodunu inceledim. Şimdi tek kalan şey bunu düzeltmek, test etmek ve geliştiriciye yollamak. Bunun için Proje kodunu SVN’den indirip açtım ve JDK 1.0’dan beri varolan System.arraycopy() metodunu kullandım. Daha sonra düzenlenmiş kod ile eklenti dosyasını yeniden oluşturup kendi oluşturduğum dosyadan kurdum. Ve, evet eklenti olması gerektiği gibi çalıştı ve sınıflarda UML diyagramı oluşturdu. Ardından yamayı oluşturarak projenin ulaştığım iki sitede (Sourceforge ve Java.net) yer alan hata kayıt sistemlerine bildirdim.

Hata Kayıtları


Yayınlandı eclipse, gezegen, java

20 Nisan 2009

Posted In: eclipse, Gezegen, java

Singleton Pattern üzerine

Singleton pattern kullanım amacı bir sınıfın kısıtlı nesnesini (hatta çoğunlukla tek) tek bir yerden yaratılması amacıyla kullanılmaktadır.  Şimdi bunu sağlayan Singleton sınıfı kodunu görelim. (Kod 1)

public class Singleton {
	private static Singleton theInstance = new Singleton();
	// Sınıf yüklendiğinde yaratılan tekil nesne

	public static Singleton getInstance() {
		// Dışarıdan nesne almak için bu metodu kullanacağız.
		return theInstance;
	}

	private Singleton() {
		// Constructor private tanımlansın ki dışarıdan erişilemesin.
		System.out.println("constructor");

		//Constructor 100 ms. bekleme gibi bir "iş" yapsın.
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

Burada sınıfın nesnesine sadece getInstance() metodu ile erişilebilecektir. Ccnstructor 100 ms. gibi “makul” bir süre beklemektedir. Bu sınıftan nesneleri yaratan sınıfımızın kodunu da inceleyelim. (Kod 2)

public class SingletonTest {

	private static Singleton singletona, singletonb;

	public static void main(String[] args) {
		singletona = Singleton.getInstance();
		singletonb = Singleton.getInstance();
		System.out.println(singletona == singletonb);
	}

}

SingletonTest sınıfını çalıştırdığımızda aşağıdaki gibi bir çıktı vermektedir.

constructor
true

Görüldüğü üzere kodumuz amacına ulaşmış constructor 1 defa çağırılmıştır. Ancak bu yöntemde Singleton sınıfının nesnesi sınıf yüklendiği anda ilklenmektedir. Şimdi bu ilklemeyi ihtiyaç anına bırakalım (Lazy initilization). Yeni Singleton sınıfımız şu şekilde oluşacaktır. (Kod 3)

public class Singleton {
	private static Singleton theInstance;
	// İhtiyaç anında yaratılacak nesne

	public static Singleton getInstance() {
		// Dışarıdan nesne almak için bu metodu kullanacağız.
		// Eğer nesnemiz yaratılmamış ise yaratalım.
		if (theInstance == null) {
			theInstance = new Singleton();
		}
		// Şu an ya da önceden yaratılan nesneyi döndürelim.
		return theInstance;
	}

	private Singleton() {
		// Constructor private tanımlansın ki dışarıdan erişilemesin.
		System.out.println("constructor");

		// Constructor 100 ms. bekleme gibi bir "iş" yapsın.
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

Bu şekilde de programımızı çalıştırdığımızda aynı çıktıyı vermekte ve beklenen şekilde işlemektedir. Şimdi SingletonTest sınıfını biraz değiştirelim ve getInstance() birden çok threadden çağırıldığında ne yapıyor onu görelim. (Kod 4)

public class SingletonTest {

	private static Singleton singletona, singletonb;

	public static void main(String[] args) {
		// getInstance() iki ayrı thread ile çağırılsın.
		Thread threada = new Thread() {

			@Override
			public void run() {
				singletona = Singleton.getInstance();
			}

		};
		threada.start();

		Thread threadb = new Thread() {

			@Override
			public void run() {
				singletonb = Singleton.getInstance();
			}

		};
		threadb.start();

		// Her iki thread tamamlanana kadar beklensin
		while (!(threada.getState() == Thread.State.TERMINATED && threadb
				.getState() == Thread.State.TERMINATED))
			;

		System.out.println(singletona == singletonb);
	}

}

Çıktımıza göre buu sefer sapıttı sanırım.

constructor
constructor
false

Evet constructor iki defa işledi ve bize iki ayrı nesne üretti. Şimdi ilklendirmemizi thread-safe hale getirelim. Bunu da getInstance() metodunu synchronized olarak tanımlayarak yapacağız. (Kod 5)

public class Singleton {
	private static Singleton theInstance;
	// İhtiyaç anında yaratılacak nesne

	public static synchronized Singleton getInstance() {
		// Dışarıdan nesne almak için bu metodu kullanacağız.
		// Eğer nesnemiz yaratılmamış ise yaratalım.
		// Metodu synchronized yaparak sayesinde aynı anda sadece bir yerden
		// çağırılmasını garanti ettik.
		if (theInstance == null) {
			theInstance = new Singleton();
		}
		// Şu an ya da önceden yaratılan nesneyi döndürelim.
		return theInstance;
	}

	private Singleton() {
		// Constructor private tanımlansın ki dışarıdan erişilemesin.
		System.out.println("constructor");

		// Constructor 100 ms. bekleme gibi bir "iş" yapsın.
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

Evet! Eski çıktımıza geri döndük. Ancak unutmayalım ki synchronized Java’nın bize sağladığı bir imkan onun için Wikipedia Singleton pattern başlığında gördüğüm yöntemle devam edeceğiz. Bu yöntemde ilk koddaki gibi ilkleme sınıf yükleme esnasında ancak yardımcı başka bir sınıfın yüklenmesinde gerçekleşecek. (Kod 6)

public class Singleton {
	private static class SingletonHolder {
		// İlklemeyi ilk örnekteki gibi sınıf yüklemesi esnasına taşıyacağız.
		// Ancak bu sefer ilklemeyi Singleton değil yardımcı başka bir sınıf
		// gerçekleştirecek.
		private final static Singleton INSTANCE = new Singleton();
	}

	public static Singleton getInstance() {
		// Bu kullanım SingletonHolder sınıfının yüklenmesini dolayısıyla
		// Singleton nesnesinin ilklenmesini tetikleyecek.
		return SingletonHolder.INSTANCE;
	}

	private Singleton() {
		// Constructor private tanımlansın ki dışarıdan erişilemesin.
		System.out.println("constructor");

		// Constructor 100 ms. bekleme gibi bir "iş" yapsın.
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

Yayınlandı gezegen, java, linux, yazılım

16 Nisan 2009

Posted In: Gezegen, java, linux, yazılım

Google, AppEngine Java desteğini duyurdu

Google uzun zamandır bekleneni yaptı ve AppEngine için Java (aslında JavaEE) desteğini duyurdu. JavaEE şeklinde belirmemin nedeni bunun JVM üstünde çalışabilen diğer dillere (JRuby ile Ruby, Groovy, Clojure…) ve uygulama çatılarına (Spring, GWT, JSF, Rails, Grails…) kapıyı açması.

Google bununla beraber AppEngine Java SDK ve Eclipse eklentisini de yayınladı. Proje web sitesinden kaydolup uygulama geliştirmeye başlayabilirsiniz. Java ile geliştirme ile ilgili belgeler için de aşağıdaki belgeleri inceleyebilirsiniz.

Java geliştirme belgesi: http://code.google.com/appengine/docs/java/

Java hızlı başlangıç belgesi: http://code.google.com/appengine/docs/java/gettingstarted/


Yayınlandı gezegen, Google, java, yazılım

8 Nisan 2009

Posted In: Gezegen, google, java, yazılım

64 bit önündeki bir engel daha kalktı – 2

Daha önceki yazımda Flash eklentisinin 64 bit sürümünün çıktığından bahsetmiştim. Bu sefer ki haber ise yine en beklenenlerden. Beta sürümü yayınlanan Java SE 6 Update 12 ile beraber artık Firefox 3 için (Firefox 2 desteklemeyecek) 64 bit Java eklentisi geliyor. Açıkçası baya bekleten bir hata kaydı oldu. 64 bit karnesi zayıf olan Sun Java en azından ağzımıza bir parmak bal çalmayı başardı. Evet artık  JMF, ve Wireless Toolkit için de 64 bit sürümlerini bekliyoruz. Java SE 6 Erken Erişim Programı sitesine girerek deneme sürümleri indirilip kurulabilir.

Ekleme: Şimdi farkettim ki Java Web Start da bu sürümle beraber 64 bit olarak gelmiş.

file /opt/sun-jdk-1.6.0.12_beta3/bin/javaws
/opt/sun-jdk-1.6.0.12_beta3/bin/javaws: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), for GNU/Linux 2.4.0, dynamically linked (uses shared libs), not stripped

Ekleme: Java SE 6 Update 12kararlı sürümü yayınlandı.


Yayınlandı firefox, gezegen, java, linux

20 Aralık 2008

Posted In: firefox, Gezegen, java, linux

Türkçe yerel ile hatalı çalışan programlar

Java’da daha önce pek çok kez karşılaştığım bir hatayı Python ile yazılmış olan Bazaar’da da yaşayınca buraya yazmak istedim. Java ve muhtemelen Python da büyük küçük harf çevrimlerinde aktif yerelin özelliklerini dikkate alıyor. Ancak bunun gerekmediği hatta istenmediği durumlar olabiliyor. Bunlara örnek olarak kod üreticiler verilebilir. Türkçe’deki I->ı ve i->İ çevrimi nedeniyle bazı programlar hatalı çalışıyor. Genellikle bunun için (en azından Java’da) uygulanan çözüm çevrimlerde İngilizce yereli baz almak. Eğer benzer hatalar (olmaması gereken yerlerde İ[büyük i] ya da ı[küçük I]) ile karşılaşırsanız ilk testiniz hatayı İngilizce yerel ile tekrar oluşturup oluşturamadığınızı test etmek olmalı.

Referanslar:

  • Java-Gnome’da Türkçe yerel ile karşılaştığım hata ve çözümü.
  • JAXB ve Türkçe yerel ile karşılaşılmış hata.
  • Bazaar ve Türkçe yerel ile karşılaştığım hata.
  • Rail Aliev’in Bazaar hata kaydına yazdığı yorum ile farkettiğim durumu açıklayan bir belge.

Yayınlandı bazaar, gezegen, java, linux, python

23 Ekim 2008

Posted In: bazaar, Gezegen, java, linux, python

JBoss Seam kitapları ….

Bir önceki yazımda JBoss Seam'in klasik Java Enterprise Development (JEE)'a kazandırdığı çeviklikten, programlama modeline, metodolojisine getirdiği devrim niteliğindeki özelliklerinden bahsetmeye çalıştım. Yeni bir teknoloji öğrenmenin en iyi yolunun o konu hakkında yazılmış kaliteli kitap(lar)ı okumak olduğunu düşünenlerdenim. Bu yazımda da Seam hakkında yazılmış kitapları ve bu kitaplar hakkındaki düşüncelerimi paylaşmaya çalışacağım.


"Seam in Action" Seam'i en kapsamlı şekilde anlatan, okunması rahat ve bol örnekleri olan bir kitap. Manning yayınevinin diğer kitapları gibi bu kitap da oldukça kaliteli ve çok iyi edit edilmiş. Bu kitabı Early Access seviyesinden beri takip ediyorum ve her sayfasından yeni bir şeyler öğrendim diyebilirim. Ayrıca referans kitabı olarak kullanılabilecek şekilde kapsamlı olduğu için başucu kitabı niteliğinde. Fakat kitap Seam'e ilk başlayanlar için biraz ağır gelebilir onun için biraz deneyim kazanıldıktan sonra okunmalı. (5/5)





Apress yayınevinden çıkan "Beginning JBoss Seam" özellikle yeni başlayanlar için çok yararlı diyebilirim. Özellikle Seam'in getirdiği yeniliklerden Bijection ve Web Conversation kavramının temellerini başarılı ve kolay anlaşılır bir şekilde anlatıyor.
(4/5)








Seam'in 1.x versiyonu sürecindeki geliştiricilerinden Michael Juntao Yuan'ın yazarlığını yaptığı "JBoss Seam: Simplicity and Power Beyond Java" bu kitap yine Seam'e yeni başlayanlar için güzel bir kaynak. Şu anda satışta olan versiyon Seam 1.x sürümünü kapsıyor fakat yakın zamanda Seam 2.x'i kapsayan yeni sürümü yayınlanacak.
(4/5)






Apress yayınevinden çıkan diğer bir kitap "Practical JBoss Seam Projects". Henüz bu kitabı okumaya zamanım olmadı fakat okuma listemde üst sıralarda. Okuyan arkadaşlar fikirlerini paylaşabilirlerse çok sevinirim.
(?/5)







Seam'in ve Hibernate'in yaratıcısı olan Gavin King'in yazarlığını yaptığı "Java Persistence with Hibernate"'in son ünitesi Seam'e ayrılmış. Seam'in ortaya çıkış sürecini ve temel özelliklerini yaratıcısının kaleminden okumak isteyenler mutlaka göz atmalılar.
(5/5)

16 Ekim 2008

Posted In: Gezegen, java, seam

JKota 0.4

JKota 0.4 sürümü yayınlandı.

Yeni özellikler:

  • Sayfada yeralan geçmiş dönemlere ait bilgilerin tablo ve grafik olarak gösterilmesi. (Issue #2)
  • Ayrıntılı günlük kayıtlarının sadece konsola basılması. (Issue #8)

Düzeltilen hatalar:

  • KabloNet ve ADSL kota alma kodları sitelerin yeni haline göre düzenlendi. Artık ne yazık ki KabloNet kullanıcılarının da captchakiller hesabı alması gerekecek😦

Not: Gentoo için java-overlay ve lapis depoları layman ile eklendikten sonra jkota paketi kurulabilir.


26 Temmuz 2008

Posted In: internet, java, jkota, linux

JKota 0.3

JKota 0.3 sürümü yayınlandı.

Yeni özellikler:

  • Tray menüsüne log dosyası görüntüleme seçeneği eklendi.
  • Issue #7.

Düzeltilen hatalar:

  • Ayarlar penceresi açıldığında API Key seçeneği görüntülenmesi doğru şekilde belirleniyor.
  • Issue #6 düzeltildi.
  • Tray desteği olmayan sistemlerde ana şifreyi sormadan uyarı vererek kapanıyor.

13 Nisan 2008

Posted In: internet, java, jkota, linux

WP Twitter Auto Publish Powered By : XYZScripts.com