Seam Framework – I

Nov 20 2011 Published by under software development

Bu yazımda Seam Framework’ünden, seam-gen’le yeni proje oluşturmaktan, seam’le hot deployment’dan ve seam’in komponent modelinden bahsedeceğim. Bu yazının devamı niteliğinde olacak olan sonraki yazımda ise Seam komponentlerinin konfigürasyonundan, Event’ler Interceptorlar ve Exception Handling’den ve Seam’in kalbi olan Conversation’lardan bahsedeceğim.

1. GİRİŞ

Seam, Java ile internet uygulamaları geliştirmek için ortaya çıkmış açık kaynak kodlu bir platformdur. Çıkış amacı Ajax, JSF, Java Persistence (JPA), Enterprise Java Beans (EJB 3.0) ve Business Process Management (jBPM) teknolojilerini bir araya getiren bir çözüm sunmaktır. Seam, aşağıdaki prensiplerden ilham almıştır:

One kind of stuff: Seam uygulamanızdaki tüm iş mantığı için bir bileşen modeli sunar. Bir seam bileşeni stateful ya da stateless olabilir.

Integrate JSF with EJB 3.0: JSF ve EJB 3.0 Java EE 5’in getirdiği en iyi iki özellik olmasına rağmen JEE 5 bu iki bileşeni entegre etmek için bir standart sunmamıştır. Seam, yazılımcının entegrasyonu düşünmeden sadece iş mantığına odaklanmasını sağlar.

Integrated AJAX: Seam en iyi iki açık kaynak kodlu JSF tabanlı AJAX çözümleri olan JBoss Richfaces ve IceFaces’i destekler.

Business process as a first class construct: İsteğe göre Seam, jBPM (Java Business Process Management) ile transparan bir iş süreci yönetimi sağlar. JBPM ve Seam ile karmaşık iş akışlarını ve görev yönetimini düzenlemek çok kolaydır.

Declarative State Management: Genellikle j2ee uygulamaları state yönetimini Servlet session’larini kullanarak kendileri implement ederler. Bu state yönetimi, session temizleme sırasında veya birden fazla pencere açılarak işlem yapılırken bir çok bug’a ve memory leak’e neden olur. Seam Hibernate veya JPA’da ortaya çıkan lazy ilişkilerdeki hataları (ör: LazyInitializationException) engeller.

Bijection: “Inversion of Control” veya “Dependency Injection” JSF’te ve EJB 3’te bulunan özelliklerdir. Bu container’ların çoğu stateless servisleri implement eden componentleri inject etmek için kullanılır. Stateful componentlerin injection’ı desteklendiğinde ise (ör: JSF) uygulama state’ini ele almak kullanışlı olmaz çünkü stateful bileşenin scope’u yeteri kadar esnek tanımlanamaz. Bijection’ın Inversion of Control’den farkı dinamik, esnek ve çift yönlü olmasıdır.

Workspace management and multi-window browsing: Seam kullanıcının her biri ayrı conversation olan farklı tarayıcı tab’larında işlem yapmasını sağlar. Ayrıca kullanıcı sadece tek bir pencerede birden fazla pencere işlemi de yapabilir.

Prefere annotations to XML: JSF’te her bir management bean’i xml’de tanımlamak gerekir. Onlarca management bean olan bir uygulamada XML dosyası hayli büyük boyuta ulaşır. Seam ise tüm management bean tanımlarını ve konfigürasyonlarını annotation’larla yapmayı sağlar.

Integration testing is easy: Seam komponentleri, yani Java class’ları, unit test yazılabilir haldedir. Ama komplex uygulamalar için sadece unit test yeterli değildir. Java web uygulamarında entegrasyon testi yazmak zordur. Seam framework’ü TestNG ve JUnit ile tüm componentleri ve entegrasyonları için kolayca test yazmanızı sağlar.

The specs ain’t perfect: Java EE’nin son sürümü güzel fakat mükemmel değildir (Örneğin JSF lifecyle’ında GET istekleri için kısıtlar). Seam geliştiricileri bir sonraki JEE standartlarını belirlemek için çalışmaktadırlar.

There’s more to a web application than serving HTML pages: Günümüz web framework’leri çok basit düşünmektedirler. Kullanıcıdan girdiyi alıp bir POJO’ya bind ederler ve kalan işi size bırakırlar. Tam anlamıyla iyi bir web framework’ü Persistence, concurrency, asynchronicity, state management, security, email, messaging, PDF ve chart generation, workflow, wikitext rendering, webservisleri ve caching gibi bir çok problemi adreslemelidir.


2. SEAM-GEN’LE YENİ PROJE OLUŞTURMAK

Yeni bir seam projesi oluşturmadan önce JDK 5 veya JDK 6, JBoss 4.2 veya 5.0, Ant 1.7.0 ve Eclipse’in kurulu olması gerekmektedir. JBoss ear ve war uygulamalarının hot deployment’ını desteklediği için JBoss’un memory büyüklüğünü arttırmanız gerekmektedir. Bunun için JBOSS_HOME/bin/run.conf’a şu parametreler yazılmalıdır.

-Xms512m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=512m

İlk olarak ihtiyacımız olan seam-gen’i kendi ortamımıza göre konfigüre etmektir. (JBoss A.S. yeri, proje workspace’i, database bağlantısı..vs.). Komut satırından seam’in kurulu olduğu yere gidip proje setup’ına başlayabiliriz:

Bundan sonra gerekli bilgiler sorulacaktır ve onları doldurmanız istenecektir:

Gerekli ayarlar girildikten sonra Eclipse projesi yaratmamız gerekmektedir. Bunun için yine aynı yerde seam new-project yazıp enter’a bastığımızda seam eclipse projesi yaratılmış olur. Bu sayede seam uygulaması için gerekli tüm jar’lar ve konfigürasyon dosyaları eclipse projesine atılmış olur. Ardından tek yapmanız gereken bu projeyi Eclipse’e import etmektir.

3. SEAM’LE HOT DEPLOYMENT

Eğer seam uygulamanızı bir folder’a deploy ettiyseniz (ant explode) seam size geliştirme zamanında hot deployment desteği sunar. Bunun için projenizdeki components.xml dosyasında debug modunu açmanız gerekmektedir:

Bu modu açtığınızda tüm facelets ve pages.xml dosyaları değiştirdiğiniz an deploy edilir. Fakat Java beanlerini değiştirdiğinizde yine server’ı başlatmanız gerekir. Eğer java bean’lerinizi değiştirdiğinizde de hemen deploy olmasını istiyorsanız Seam Java bean componentlerinizin hot deployunu da destekler. Bunun için hemen deploy olmasını istediğiniz class’ları ve packege’leri dev source folder’ının altına yaratın. Bu sayede o class’lar WAR ya da EAR’ın class loader’ıyla değil Seam’in class loader’ıyla yüklenecektir. Fakat java class’larının hot deployment’ı için bazı kısıtlar bulunmaktadır:

  • Hot deploy edilecek komponentler JavaBean componenti olmalıdır. EJB3 beanler hot deploy edilemez.
  • Entity’ler hot deploy edilemez.
  • components.xml ile deploy edilen componentler hot deploy edilemez.
  • Seam’in debug modu açık olmalıdır.
  • web.xml’de seam filter’ınız olmalıdır.
  • Debug mod’da sisteme yük basarsanız hatalarla karşılaşabilirsiniz.

 

4. SEAM’İN COMPONENT MODELİ

4.1. SEAM CONTEXT’leri

4.1.1. Stateless context: State’i olmayan komponentlerdir ve nesne yönelime uygun komponentler değillerdir. Yine de seam uygulamasının önemli bir parçasını implement etmek için kullanılabilirler.

4.1.2. Event context: En dar kapsamlı stateful context’tir ve bir web isteğindeki bir çok çeşit event’i kapsar. Yine de JSF lifecyle’ıyla ilişkili event context’i bu türün en önemli ve en çok kullanılan örneğidir. Event contextine bağlı olan komponentler web request’inin sonunda yok olur. Bir seam komponentini RMI ile veya Seam Remoting ile çağırırsanız event context bir invocation’da yaratılır ve yok olur.

4.1.3. Page context: Page contexti, state’i gelen web sayfasının bir instance’ıyla ilişkilendirmenizi sağlar.

4.1.4. Conversation context: Conversation context Seam’in merkezindeki konudur. Bir conversation kullanıcı gözünden bir birimlik işe karşılık gelir. Kullanıcıyla birçok etkileşimi, bir çok isteği ve birçok veritabanı işlemini kapsayabilir. Fakat kullanıcı için conversation sadece tek bir problemi çözer. Örneğin “bir otel odası rezerve etmek”, “bir sözleşme imzalamak” ..vs. birer conversation’dır. Conversation’ı sadece bir use case’i veya bir user story’i implement etmek gibi düşünebilirsiniz. Bir conversation “kullanıcı bu pencerede şu an ne yapıyor”’un state’ini tutar. Bir kullanıcının, genellikle birçok pencerede işlem yaptığında birden fazla conversation’ı olabilir. Bazı conversation’lar tek bir istekte biterler. Bazıları birden fazla HTTP isteğiyle devam ederler. Seam eş zamanlı isteklerin işlenmesini serileştirir.

4.1.5. Session context: Bir session context’i kullanıcının bir login oturumunun state’ini tutar. Bir çok conversation’ın bir state’i paylaşmaları için kullanılır. JSR-168 standardındaki portlet geliştirmekte Session context bir portlet session’a karşılık gelir.

4.1.6. Business Process context: Bu context uzun süreli bir iş işleminin state’ini tutar. Bu state BPM motoru tarafından yönetilir. (JBoss jBPM engine) Bu işlem birden fazla kullanıcının paylaştığı state’ler için kullanılır.

4.1.7. Application context: Application context bir web uygulamasında statik olarak tutulacak konfigürasyon bilgilerini, referansları ve meta modelleri tutmak için kullanılır.

4.1.8. Context değişkenleri: Bir context değişken kümesi tanımlar. Herhangi bir değeri bir context değişkenine bind edebilirsiniz. Bir context’te bir değişkene isim verilerek tanımlanır.

4.1.9. Context arama önceliği: Tüm stateful scope’lar bir arama önceliğiyle context’te aranırlar. Arama önceliği şöyledir: Event, Page, Conversation, Session, Business Process ve Application.

4.2. SEAM KOMPONENTLERİ:

4.2.1. Stateless Session Beans: Stateless session bean’leri birden fazla istekte state’i tutamazlar. Fakat diğer stateful seam contextleri tarafından kullanılabilirler. JSF action listener olarak kullanılabilirler fakat JSF komponentlerine bir özellik sağlayamazlar. Stateless session bean’ler Components.getInstance() ile veya @In(create=true) annotationı ile yaratılabilirler.

4.2.2. Stateful Session Beans: Stateful session bean’ler sadece bir metod çağırıldğındaki state’i tutmakla kalmaz aynı zamanda bir istek geldiğindeki state’i de tutabilirler. Database’de bulunmayan uygulama state’i stateful session bean’ler tarafından tutulabilir. Bu Seam framework’ü diğer web framework’lerinden ayıran bir özelliktir. Bu bean’ler JSF action listener’lar olarak kullanılabilirler ve JSF komponentlerine formlarda gösterilmek üzere bazı özellikler sunabilirler. Stateful session bean’ler Components.getInstance() ile veya @In(create=true) annotationı ile yaratılabilirler.

4.2.3. Entity Beans: Entity bean’ler seam komponentlerine context değişkeni veya fonksiyonu olarak bind edilirler. Çünkü entity’lerin persistent id’leri vardır. Context id’leri yoktur. Instance’ları java kodu içerisinde başka componentlerde yaratılır, seam yaratmaz. Bijection’ı desteklemezler. Genellikle JSF action listener olarak kullanılmazlar. Components.getInstance() ile, @In(create=true) annotationı ile veya new ile yaratılabilirler.

4.2.4. Java Beans: Stateless veya Stateful session bean olarak kullanılabilirler fakat session bean’in özelliklerini desteklemezler. (transaction demarcation, security, cluster state replication ..vs.)

4.2.5. Message Driven Beans: Bu bean’ler bir seam komponenti gibi davranabilirler. Fakat message driven bean’ler seam komponentlerinden farklı çağrılırlar. Context değişkeni olarak çağırmak yerine JMS queue’ya gönderilen mesajları dinlerler.

4.2.6. Interception: Seam’in özelliklerini uygulaması için komponent kontrolünü elinde bulundurması gerekmektedir. Java Bean’ler için Seam instance yaratmak için tüm kontrolü elinde bulundurur ve özel bir konfigürasyona gerek yoktur. Entity bean’ler için interception gerekli değildir. Session bean’ler için EJB interceptor’ı kaydetmemiz gerekir. Şu annotation’ı kullanabiliriz:

4.2.7. Komponent İsimleri: Tüm seam komponentleri bir isme ihtiyaç duyar. Bu ismi vermezsek o komponentte hiçbir seam annotation’ını kullanamayız. İsmini hem JSF sayfalarında hem de Java kodunda kullanabiliriz. Bu ismi @Name annotation’ı ile verebiliriz:

4.2.8. Komponentin scope’unu belirleme: Bir komponentin scope’unu (context) @Scope annotation’ı ile verebiliriz:

4.2.9. Birden fazla role sahip komponentler: Bir seam komponentinin sistemde birden fazla rolü olabilir. Örneğin User sınıfını oturumu açık olan kullanıcıyı tutmak için Session scope’lu belirleriz. Ancak yeni kullanıcı eklemek isteyen admin kullanıcısı için aynı User sınıfı conversation scope’a ihtiyaç duyar. @Role annotation’ı komponente ek bir rol eklememizi sağlar. Örneğin aşağıdaki sınıf currentUser ismiyle alınırsa scope’u session user ismiyle alınırsa scope’u conversation olur.

4.2.10. Built-in komponentler: Bir çok web framework’ü gibi Seam built-in komponentler sunar. FacesMessages komponenti kullanıcıya mesaj göstermek için kullanılan bir built-in komponent örneğidir. Ör:

4.3. BIJECTION:

Dependency Injection geliştiricilerin alışık oldukları bir kavramdır. Dependency injection, bir komponente injection sayesinde bir diğer komponentin instance’ına erişebilme imkanı verir. Gördüğümüz tüm dependency injection implementasyonlarında injection komponent yaratılırken ortaya çıkar ve referans componentin hayatı boyunca aynı kalır. Seam klasik dependency injection’a alternatif olarak Bijection’ı önerir. Bijection Inversion of Controle nazaran contextli, çift yönlü ve dinamiktir. @In annotation’ı inject edilecek değeri belirler. @Out annotation’ı ise outject edilecek değeri belirler.

Comments are off for this post