Sansür, bir toplumun kendine olan güvensizliğini yansıtır ve otoriter rejimlerin belirgin bir özelliğidir.

--Potter Stewart

15.08.2009

SCJP, SCWCD, Spring Roo, STS, vs. vs.

Uzunca sayılabilecek bir süre blogumla ilgilenemedim. Bunun başlıca sebebi SCJP 6.0 için çalışıyor olmam ve bu sebeple merak ettiğim, ilgilenmek istediğim Spring Roo gibi teknolojilerden uzak kalmamdı. Neyseki 2 hafta önce sınava girerek sertifika almaya hak kazandım ve ardından yıllık izne çıktım.

SCJP sınavına "SCJP Sun Certified Programmer for Java 6 Exam 310-065" kitabıyla hazırlandım. Uygulama geliştirirken ezbere ya da bilmeden yaptığımız birçok konuyu öğrenmek, "bu da bu şekildeymiş" demek, örnek soruları çözmek benim için hem eğitici hem de keyifliydi. Kitabı okumanızı tavsiye ederim. Ardından bol soru çözmek sınav için yeterli olacaktır.

Sırada SCWCD var. Sınava çalışmak için ilk başta "Sun Certified Web Component Developer Study Guide" kitabını düşünsem de kitabın okuyuculardan aldığı kötü yorumlar, beni "Head First Servlet & JSP" yönlendirdi. En kısa zamanda da ikinci sertifika için çalışmaya başlamayı düşünüyorum.

İlk sertifikaya çalışırken gösterdiğim tembelliği tekrarlamamaya; Refactoring, TDD ve merak ettiğim Spring Roo, OSGi gibi konulara da tekrar eğilmeye çalışıcam. Bu sırada Eclipse 3.5 tabanlı SpringSource Tool Suite 2.1.0'ı da kullanarak getirdiği kolaylıkları gözlemlemek de istiyorum.

29.06.2009

CETURK Java Teknolojileri Etkinliği -7

Geçtiğimiz haftalarda Ankara'da gerçekleştirdiğimiz Java Teknolojileri Etkinliğinin bir benzerini bu sefer İstanbul'da, IBM Türk binasında gerçekleştireceğiz. 04.07.2009 tarihinde Java ve Kurumsal uygulamalara gönül veren İstanbullularla buluşmak dileğiyle.

Etkinliğin ayrıntılı duyurusuna http://www.ceturk.com/etkinlikkayit.asp?id=75 adresinden erişebilirsiniz.

16.06.2009

CETURK Java - Ankara Etkinliğinin Ardından..

13 Haziranda ODTÜ - KKM'de gerçekleştirilen CETURK Java Teknoloji seminerlerinin kendi açımdan heyecanlı geçmesinin yanı sıra izleyicilerin de yeni teknolojilerle tanışması açısından başarılı geçtiğini düşünüyorum.

Benim de Mustafa Demir ile "Spring Web Service" sunumuyla katıldığım etkinlikte Hasan Türksoy'un GWT ve Mehmet Gürsul'un OSGi konularına giriş düzeyindeki sunumları en azından bu iki konuya olan açlığımı bir nepze gidererek bu iki alanda biraz oyalanmam için kapıları araladı. Ayrıca Ümit Vardar Hocamızın EJB 3.1'in getirdiği yenilikler konulu sunumuyla Kenan Sevindik'in Audit sunumu da etkinliğe renk kattı.

İlk sunumum olması sebebiyle heyecanlanmanın yanında keyif de aldığımı söyleyebilirim. Yeni sunumlarda birlikte olmak dileğiyle... :)

"Spring Web Service" sunumunun yansılarına ve örnek uygulamaya http://files.getdropbox.com/u/135887/presantations/springws.rar bağlantısından erişebilirsiniz.




5.06.2009

CETURK Java Teknolojileri Ankara Etkinliği 2

CETURK'ün katılım ücretsiz olarak düzenlediği teknoloji etkinliklerinin Ankara'da 2.si 13 Haziran 2009 Cumartesi günü ODTÜ Kültür ve Kongre Merkezi (KKM) A Salonunda gerçekleştirilecek. Alanında uzman kişilerin çeşitli sunumlarla bilgilerini paylaştıkları CETURK etkinliklerinin bu ayağına "Spring Web Service" sunumuyla Mustafa Demir ile birlikte biz de konuşmacı olarak katılıyoruz. Devamının gelmesini dilerim...

Ayrıca GWT, Spring AOP, EJB 3.1 ve OSGI sunumlarının da olacağı seminerin duyurusuna ve program akışına http://www.ceturk.com/etkinlikkayit.asp?id=74 adresinden ulaşabilirsiniz.


25.03.2009

Hibernate Parameter Binding

Hibernate kullananların sıkça karşılaştığı bir durum Hibernate’in ürettiği SQL cümleciklerine geçtiği parametreleri görememektir. Hibernate’in ayar kütüğü persistence.xml’e yazılan

<properties>

...

<property name="hibernate.show_sql" value="true"/>

...
</properties>


İfadesi bile üretilen SQL cümleciğinde parametre gelecek yerleri ‘?’ ile gösteriyor. Hal böyle olunca bazen debug esnasında akışı izlemek sıkıntılı olabiliyor. Bu sıkıntıyı aşmanın bir yolu ise Hibernate Type sınıfı için Log4j 1.2.12 sürümünden itibaren kullanılmaya başlanan TRACE düzey loglama yapmak:


<logger name="org.hibernate.type">

<level value="TRACE"/>

</logger>


Her ne kadar ‘?’ yerine değerler gelmese de basılan loglardan soru işareti ile belirtilen yerlere atanan değerleri elde etmek mümkün. Dönen değerler de bonus olarak gösteriliyor


Hibernate:
/* load deneme.DovizTipi */ select doviztipi0_.ID as ID52_0_, doviztipi0_.ACIKLAMA as ACIKLAMA52_0_, doviztipi0_.KISA_ACIKLAMA as KISA8_52_0_ from DOVIZ_TIPI doviztipi0_ where doviztipi0_.ID=
?

25 Mar 2009 15:11:27,159 - TRACE - IP:127.0.0.1, ReqURI:/ips/spring/anasayfa-flow - /ips - org.hibernate.type.NullableType.nullSafeSet(151) | binding '949' to parameter: 1

25 Mar 2009 15:11:27,159 - TRACE - IP:127.0.0.1, ReqURI:/ips/spring/anasayfa-flow - /ips - org.hibernate.type.NullableType.nullSafeGet(193) | returning 'Yeni Türk Lirasi' as column: ACIKLAMA52_0_

25 Mar 2009 15:11:27,159 - TRACE - IP:127.0.0.1, ReqURI:/ips/spring/anasayfa-flow - /ips -
org.hibernate.type.NullableType.nullSafeGet(193) |
returning 'TL' as column: KISA8_52_0_

18.02.2009

Açıklama Satırı Yazmadan Kod Yazana 10 Puan Bonus

Bilgisayar Mühendisini mezun olduktan sonra, yaşadığı sanal dünyadan gerçek dünyaya hazırlayan, okuduğu teorik bilgileri pratiğe dökmesini sağlayan yegane işlev, genelde ikişer haftalık periyotlarla geliştirdiği, üstüne bir de raporun yazdığı programlama ödevleridir. 

Öğrencinin istenen programı hatasız geliştirmesinin yanı sıra yaptıklarını anlatan ödev raporu ve kodun içinde -alışkanlık olması ve asistanın okuyabilirliğini arttırmak için- kodun bakılabilirliğini kolaylaştırdığı düşünülen açıklama satırlarını yazması beklenir. Hatta kodu yazıp açıklama satırını yazmayı ihmal eden öğrencinin en az 10 puanın gideceği garanti edilir. Hal böyle olunca mühendis adayı ya kodu yazarken açıklama satırlarını da aynı anda yazmayı kendine ilke edinir ya da kod yazma işi bittikten sonra uygun gördüğü yere açıklama satırlarını serpiştirir.

İki hafta bir sürenin son 3-4 günü ödevini yapmaya başlayan öğrenci ise ödev yetiştirmeye çalışmaktan ne Martin Fowler'dan ne "Refactoring"den -kodu adam etme demeyi daha çok seviyorum- ne de o kadar çok açıklama satırı yazmaması gerektiğinden haberi vardır. İşin ilginci ödevi veren de bundan bi haberdir...

Benim de mezun olduktan sonra namını duyduğum Martin Fowler "Refactoring Improving the Design of Existing Code" kitabında güzel konulara değinirken bu açıklama satırları konusuna da değiniyor. "Açıklama satırı kötü kokan kodun üzerine sıkılmaya çalışan deodoranttır" diyor. Doğru :)

Kitapta sınıf, metot ve değişken isimlendirmelerinin üstlenilen görevi anlatacak nitelikte yapılması gerektiğinden bahsediliyor. Bir kod parçasının işlevi açıklanma gereği duyuluyorsa o kod parçasının ayrı bir metota taşınmasını ve yeni metotun isminin açıklayıcı nitelikte olması gerektiğini söylüyor. Yazılması gereken açıklama satırının "nasıl"ı değil diğer geliştiriciler için "neden" sorusuna cevap vermesi gerekliliği vurgulanıyor.

Bol açıklama satırsız kodlar... 

9.01.2009

Richfaces Editor Bileşeni

Önceki girdimde belirtiğim projede ortaya çıkan richfaces:calendar ile TinyMCE'nin IE ortamında birbirlerine yaptığı uyuzluk beni Richfaces 3.3.0 ile gelecek olan editor bileşenini denemeye yöneltti. Richfaces 3.3.0.CR3 sürümünü indirerek gerekli ayarları yapmam ve bileşeni kullanmam çok kısa sürede sonuçlandı. TinyMCE'i kullanmak için sayfaya yüklememiz gereken tiny_mce.js işlemini yapmaya gerek duymadan sadece editorconfig.properties dosyasını classpath'te hazırlayarak bileşeni kullanabilir duruma geldim.

Detaylı bir editorconfig.properties içeriği şu şekilde oluşturabilinir:

http://dl.getdropbox.com/u/135887/editorconfig.properties


TinyMCE ayarları ile ilgili detaylı bilgiyi buradan bulabilirsiniz. Bileşeni kullanmak istediğiniz yerde şu kod parçasını yazmanız yeterli:



Yukardaki kodda da görüldüğü gibi ile ayar dosyasında olan bir niteliği ezebiliyor, olmayan niteliği de ekleyebiliyorum. Sonuç bence başarılı :)




8.01.2009

Richfaces Calendar bileşeni ve TinyMCE

Richfaces sunduğu zengin JSF bileşenleriyle JSF ile geliştirilen web uygulamalarında kullanımı sıkça tercih edilen bir kütüphane. bileşeni de Richfaces'ın işe yarar özellikleri olan güzel bir takvim gerçekleştirimi.

TinyMCE ise html girdileri yapabileceğiniz popüler bir "zengin metin editörü".

Geliştirdiğimiz web uygulamalarında TinyMCE'i bir Richfaces bileşeni olarak paketlemiştik. Böylece kolay ve tekrar kullanılabilir zengin metin editörümüz oldu. Bir adım daha ileri giderek Richfaces'in dosya yükleme bileşen
i olan ve bu blogta gerçekleştirimi bir örnekle anlatılan ile zengin metin editör bileşenimizi birlikte çalışır hale getirdik.

Zengin metin editörümüzü mutlu mesut kullanırken, richfaces'ın dosya yükleme yeteneği ile kullanıcılara resimler yükletirken bugün gördüm ki rich:calendar ve tinyMCE ile birbirleriyle aynı sayfada geçinemiyor. Firefox iki bileşeni problemsiz çalıştırırken, bu uyumsuzluk bir şekilde IE'de ortaya çıkıyor ve can sıkıyor. (Uyumsuzluğu bulmak 2 saatimi alınca canlar sıkıldı elbet.)

Richfaces'in Jira'sında bununla ilgili bir hata kaydı girilmiş: https://jira.jboss.org/jira/browse/RF-3697

Kayıttan da anlaşıldığı gibi sorunu 3.3.0 ile birlikte gelecek olan ile çözmüşler. Richfaces'in TinyMCE gerçekleştirimi. TinyMCE'in var olan özelliklerinin yanısıra yeni özellikler barındırdığından da bahsediliyor. İncelediğim kadarıyla TinyMC
E'in gerek duyduğu parametreleri .properties dosyasından temin ediyor. Biz bu parametreleri bileşenin .xhtml sayfasında veriyorduk.

TinyMCE bileşenini Richfaces'tan önce geliştirdiğimize mi sevineyim, var olan sorunlar nedeniyle Richfaces'ın yeni sürümünde gelecek olan gerçekleştirime geçmek zorunda kaldığımız için harcanan emeğe mi üzüleyim bilemedim :)




14.11.2008

En Basit Tasarım Örüntüsü Singleton (mu?)

Singleton örüntüsü bir sınıfın sadece tek bir nesnesi olması gerektiği durumlarda kullanılır ve sınıfın ihtiyaç duyulduğu zaman yaratıldığı en bilindik kullanım şekli şu şekildedir:

public class DateUtils {


private static DateUtils instance = null;


private DateUtils() {}


public static DateUtils getInstance() {


if(instance == null)


instance = new DateUtils();


return instance;


}

...

}


Böyle bir kullanım çoklu işletim dizilerinde (multithreads) sorunlara neden olabilmektedir. Aynı anda iki farklı işletim dizisinin instance niteliğini kontrol etmesi ve null görmesi sonucu iki farklı olgunun yaratılma olasılığı vardır. Bunun önüne iki şekilde geçilebilir. İlki sınıfın static niteliğinin uygulama ayağa kalkarken yaratılması:


public class DateUtils {


private static DateUtils instance = new DateUtils();


private DateUtils() {}


public static DateUtils getInstance() {

return instance;

}

...

}

İkincisi ise getInstance() yönteminin synchronize hale getirilmesi. Tüm yöntemin senkron hale getirilmesi, sadece nesnenin null durumunda kontrol edilmesi gereken, nesne yaratıldıktan sonra da performansa olumsuz etki yapan bir durum olduğu için kullanımından kaçınılmaktadır. Bunun yerine instance niteliği null ise senkronu başlatan bir yöntem tercih edilmiştir:


public class DateUtils {


private static DateUtils instance;


private
DateUtils() {}

public static DateUtils getInstance () {


if(instance == null) {


synchronized(DateUtils.class)
{


if(instance == null)


instance = new DateUtils();


}


}


return instance;


}

}

Ne var ki “Double-Checked Locking” olarak bilinen bu yöntem JDK 5’ten önce çalışmıyor. Ayrıntılı bilgiye “The Double-Checked Locking is Broken Declaration” bağlantısından ulaşabilirsiniz. JDK 5 ile gelen volatile bu
sıkıntıya derman oluyor:


public class DateUtils {


private volatile static DateUtils instance;


private DateUtils() {}


public static DateUtils getInstance () {


if (instance == null) {


synchronized(DateUtils.class)
{


if (instance == null)


instance = new DateUtils();


}


}


return instance;


}

}

Singleton örüntüsünde dikkat edilmesi gereken bir başka husus ise sınıf Clonable arayüzünü gerçekleştiren bir başka sınıftan türetilmişse ortaya çıkıyor. Singleton sınıfımızın clone() yöntemi ile çoğaltılmasının önüne geçmek istiyorsak bu metodun üstüne yazmamız gerekiyor:

public Object clone() throws CloneNotSupportedException {


throw new CloneNotSupportedException();

}

13.11.2008

Hibernate Data Filtering (Süzme)

Verilerin tamamını değil de belirli kriterlerle süzülüp işimize yarayacakları veritabanından sorgulamak günlük hayatta çokça karşılaştığımız bir senaryo. Örneğin “Abone” nesnesinin belirli tarihten önceki ödenmemiş faturalarına erişmek istediğimiz zaman abone.getFaturalar()
şeklinde bir erişim, eğer bir süzme uygulanmazsa abonenin tüm faturalarını getireceği için Java kodlarıyla süzme işlemini yapmamızı gerektirecektir. Buna benzer ya da veri güvenliği (kullanıcıya sadece görmesi gereken verilerin gösterilmesi) gibi senaryolarda Hibernate Data Filtering, Java kodlarında gerçekleştirmemiz gereken süzme maliyetinden kurtulmamıza olanak sağlıyor.


Öncelikle süzme işleminde kullanacağımız süzgeci, biricik ismiyle tanımlamamız gerekiyor:

@org.hibernate.annotations.FilterDef(name="faturaOdemeFilter",


parameters={
@ParamDef(name="donem",type="integer"),
@ParamDef(name="kalanTutar",type="double"),
@ParamDef(name="durumConditions",type="long")

})


Tanımladığımız süzgecin ismi faturaOdemeFilter ve dinamik süzme işlemi yapabilmemiz için üç tane parametre alıyor. Parametrelerin kurulma işlemine birazdan değineceğiz. Bu tanım global nitelikli olduğu için herhangi bir sınıfta ya da package-info.java içerisinde yazılabilir. Yazıldığı sınıfın davranışında bir etkisi yoktur fakat uygun olan tanımın ilgili sınıfta yazılmasıdır. Süzgeç tanımımız olgusunu da süzme işleminin yapılacağı sınıfta ya da ilişkide yazılması gerekmektedir:

@Entity
@Table(name="FATURA")

@Filter(name="faturaOdemeFilter", condition="ODEME_DONEMI <= :donem and FATURA_DURUM in (:durumConditions) and KALAN_TUTAR >:kalanTutar")

public class Fatura {...}


Birden fazla süzgeç @org.hibernate.annotations.Filters ile gruplanabilir. Yukarıdaki gibi sınıf üzerine yazılmış süzgeç olgusu


List<Fatura> filteredItems = session.createQuery("from Fatura").list();


List<Fatura> filteredItems = session.createCriteria(Fatura.class).list();


Deyimlerinde çalışacaktır. Id ile sorgulamalarda (id'yi biliyorsak süzmeye de gerek yok) ve nesne niteliklerinin sorgulanmasında sınıf üzerine yapılan tanım çalışmayacaktır. abone.getFaturalar()deyimi gibi abonenin ilişkili olduğu faturaların süzülmesi için süzgeç olgusunun ilişki üzerinde tanımlanması gerekmektedir:


@Entity
@Table(name = "ABONE")


public class Abone {


@OneToMany(mappedBy="abone")
@Filter(name="faturaOdemeFilter", condition="ODEME_DONEMI <= :donem and FATURA_DURUM in (:durumConditions) and KALAN_TUTAR > :kalanTutar")


private Set<Fatura> faturalar = new HashSet<Fatura>();


...

}


Süzgeç tanımının kullanılması için Hibernate Session’ında süzgeç aktif hale getirilerek varsa aldığı parametreler kurulmalıdır. Veriler çekildikten sonra da süzgeç tekrar pasif hale getirilebilinir. (JPA API’sinde EntityManager filtrelemeye destek sağlamadığı için Hibernate arayüzü kullanılmalıdır.)


List<Long> durumConditions = new ArrayList<Long>();

durumConditions.add(FaturaDurumEnum.ODENMEMIS.getValue());
durumConditions.add(FaturaDurumEnum.
PARCALI_ODENIYOR.getValue());


Filter filter = session.enableFilter("faturaNormalOdemeFilter");


filter.setParameter("donem",donem).setParameter("kalanTutar",new Double(0)).setParameterList("durumConditions", durumConditions);


Set<Fatura> faturalar = abone.getFaturalar();


session.disableFilter(("faturaNormalOdemeFilter");