Serkan Kaba

Karalama Defteri

‘java’ Kategorisi için Arşiv

JAX-WS ile WsGen kullanmadan web servisi oluşturma

Yazan: Serkan Kaba 10 Haziran 2009

Yakın zamanda farkettiğim bu özellik basit web servislerinin oluşturulmasını ve test edilmesini oldukça kolaylaştırıyor. Araştırdığımda çok daha eskiden beri JAX-WS sürümlerinde var olduğunu öğrendiğim bu özelliği şans eseri 1.6u14 sürümüne girdikten sonra fark ettim. Bu şekilde artık @WebService ile işaretlediğimiz sınıfları Endpoint.publish() ile direk sunabilmekteyiz. Örnek olarak aşağıdaki kodu direkt çalıştırdığımda ws erişilebilir ve kullanılabilir hale gelmekte. Ayrıca çalıştırılırken gerekli sınıfların çalışma anında oluşturulduğuna dair log mesajları oluşturmakta.

package service;

import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.xml.ws.Endpoint;

@WebService
public class Hello {

	@WebMethod
	public String hello() { return "Hello"; }

	public static void main(String[] args) {
		Endpoint.publish("http://localhost:8080/hello", new Hello());
	}

}

Referanslar

Yazı kategorisi: gezegen, java, yazılım | 2 Yorum »

@Override annotation ve Java5 ile Java6 arasındaki farkı

Yazan: Serkan Kaba 7 Mayıs 2009

Java5 ile gelen annatationlardan biri olan @Override bir metodun eskisini geçersiz kıldığını (override) ifade eder. Ancak Gentoo’da bir hata nedeniyle farkettiğim üzereanlamı Java5 ile Java6 arasında farklılık göstermektedir. Java6′dageçersiz kılınan ve gerçekleştirilen metodlar için @Override kullanılabilirken Java5′te sadece ilk kullanımı geçerlidir. Bu bir hata olarak Sun hata kayıt sistemine defalarca raporlanmıştır. (Benzer ve çift hata kayıtlarından anlaşıldığı üzere) Benim hataların yorumlarından anladığım amacın Java5 için de her iki durumu desteklemek olduğu ancak derleyicideki hata sebebiyle Java5 spesifikasyonunun revize edilerek sadece ilk kullanımın desteklendiği ve Java6′da her iki kullanımım geçerli sayıldığı yönünde. Bunun sebebi ise hatalı da olsa Java5 için uyumluluğu korumak.

Şimdi bu durumu bir örnek üzerinden inceleyelim.

interface Interface {
	public abstract void b();
}

abstract class Base {
	public abstract void a();
}

public class Sub extends Base implements Interface {

	@Override
	public void a() {
	}

	@Override
	public void b() {
	}

}

Bu kod Java6 ile gelen derleyici ile derlenmekte ancak Java5′teikinci @Override için şu hatayı vermektedir.

Sub.java:15: method does not override a method from its superclass
	@Override

İşin ilginç yanı Java6 derleyicisi ile -source 1.5 -target 1.5 parametreleri verildiğinde de hata vermemekte 1.5 ile olan uyumsuzluğu ancak ecj (Eclipse Java derleyicisi) yakalayabilmektedir. Bu sebepten ötürü arayüz metodları gerçekleştirilirken @Override kullanılmaması başka amaçla illa Java6 gerekmiyorsa kodun uyumluluğunu arttıracaktır.

Yazı kategorisi: gentoo, gezegen, java | » yorum bırak;

Generics ve Reflection ile genelleştirilmiş dizi yaratma

Yazan: Serkan Kaba 29 Nisan 2009

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.

Yazı kategorisi: gezegen, java | » yorum bırak;

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

Yazan: Serkan Kaba 20 Nisan 2009

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ı

Yazı kategorisi: eclipse, gezegen, java | 1 Yorum »

Singleton Pattern üzerine

Yazan: Serkan Kaba 16 Nisan 2009

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();
		}
	}
}

Yazı kategorisi: gezegen, java, linux, yazılım | 6 Yorum »

Seminer mevsimi

Yazan: Serkan Kaba 9 Nisan 2009

Baharın gelmesi ile Açık Kaynak ve Linux ile ilgili seminerler artmaya başladı. Bilgi Üniversitesi’nde FreeDays ve 8. Linux ve Özgür Yazılım Şenliği, Yıldız Teknik Üniversitesi’nde 3. Açık Kaynak Günleri düzenleniyor. Ben de 14 Nisan saat 14:00′te Yeditepe Üniversitesi Mühendislik Fakultesi B-316 sınıfında “Açık Kaynak Kodlu Yazılım Geliştirme”, 18 Nisan saat 13:00′te de YTÜ Açık Kaynak Günleri kapsamında “Zemberek Projesi ve Geliştirme Süreci” başlıklı 2 seminer vereceğim.

Yazı kategorisi: gezegen, linux, seminer, zemberek | 2 Yorum »

Google, AppEngine Java desteğini duyurdu

Yazan: Serkan Kaba 8 Nisan 2009

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/

Yazı kategorisi: Google, gezegen, java, yazılım | » yorum bırak;

İki Kule

Yazan: Serkan Kaba 19 Mart 2009

Dolaşan haberlere[1][2] göre IBM uzun süredir ekonomik sıkıntı yaşayan Sun Microsystems’i 6.5 milyar dolar gibi bir rakama almak için kolları sıvamış durumda. Bundan dolayı da herkes geleceğin ne getireceği konusunda düşünmeye başladı. IBM ve Java pek çok alanda rekabet içinde ürünlere sahip. Donanım alanından çekilmeye başlayan IBM’in Sun’ın donanımdan çok yazılım teknolojilerine göz diktiği söylenmekte.

Şimdi düşündüğümüzde daha kararsız olduğunu gözlemlediğim ancak daha çok platformda çalışan IBM JDK ile Sun JDK’nın birleşmesi ile OpenJDK/IcedTea’nin boşlukları tamamen kapanabilir ve gerçekten pek çok platformda çalışan özgür bir JDK’e kavuşabiliriz. Unutmayalım ki IBM temel platformun özgür olmasını destekliyor. Ama bence Openoffice o kadar şanslı gibi durmuyor. Açık kaynak kodlu olduğundan yokolmasa da IBM Lotus Symphony’ye karşı Openoffice’e destek vermeyebilir. (Zemberek Symphony entegrasyonunu araştırmalı mıyız ne?) Bir de Eclipse platformuna karşılık Netbeans var. Görsel geliştirme ortamı daha iyi olmasına rağmen (ancak hiçbir zaman görsel geliştirme ortamlarının ürettiği kod optimum değildir) yarattığı ekosistemle Eclipse daha geniş bir destek bulmayı başardı. Bu sebepten muhtemelen üstün yanları Eclipse’e entegre edilerek yokolacaklar listesinde yerini alacak. Hatta Adobe Flex’e karşı JavaFX de kaybedenler arasına girebilir.

Bakalım haber gerçekleşir ve iki kule güçlerini birleştirirse neler olacak? Bence en önemli etkisi .Net ve Java kutuplaşmasının derinleşmesi olacak.

1: http://www.nytimes.com/2009/03/19/technology/companies/19sun.html?_r=2&ref=technology
2: http://online.wsj.com/article/SB123735124997967063.html

Yazı kategorisi: eclipse, gezegen, linux, lotus symphony, netbeans, openoffice, yazılım | » yorum bırak;

Tez çalışmam ve bulduğum hatalar

Yazan: Serkan Kaba 17 Ocak 2009

Tez çalışmamın yazımını çoğu Openoffice programını (Writer, Draw, Math) ve kmplot (ilk Google sonucu) kullanarak tamamladım (son rötuşlar olur tabi). Bu esnada Zemberek tarafından tanınamayan bazı kelimeler keşfettim ve hata kayıt sistemine raporladım. Ancak karşılaştığım hataların en ilginci Openoffice’te çıkandı. Çıktıyı (Neyse ki ciltli kopya değildi) bile aldıktan sonra arkadaşın gözle farkettiği formüllerim. Openoffice PDF çevrimi yaparken formüllerin bazılarında rakamları Arap alfabesindeki rakamlara çevirmişti. Araştırdığımda bunun bilinen ve uzun zamandır açık olan bir hata olduğunu öğrendim. Üstelik de yazılanlar gibi rasgele oluyor, bozulan rakamlar her seferinde değişiyordu. Şimdilik yazdırma için PDF’ye aktarmayı tercih edeceğim (Oysa kı yazıtipi, kayma gibi sorunlar olmasın diye özellikle PDF tercih etmiştim). Ancak PDF’ye çevirirken (CD’de PDF olarak da vermem gerekiyor sanırım) muhtemelen CUPS-PDF kullanmam gerekecek.

Ekleme: Tarık Zengin’in tavsiyesi ile dosyaya yazdır ile postscript dosyası oluşturup ghostscript ile beraber gelen ps2pdf ile pdf oluşturmaya karar verdim. Gayet de rahat oldu. Teşekkürler Tarık.

Yazı kategorisi: gentoo, gezegen, linux, openoffice, zemberek | 13 Yorum »

Zemberek Firefox eklentisi layman ile kurulabilir

Yazan: Serkan Kaba 28 Aralık 2008

Rail ALİEV’ in geliştirdiği Zemberek Firefox eklentisinin SVN paketini kişisel depoma ekledim. Layman ile depoyu ekledikten sonra portage ile mozzemberek paketi kurulabilir. Ben de bu satırları Firefox’tan yazım denetimi yaparak yazıyorum. Sanırım artık benden daha hatasız günlük yazıları okuyabilirsiniz :P

Yazı kategorisi: gentoo, linux, zemberek | 5 Yorum »