Java daki Problemler ve OSGi Teknolojisi

advertisement
Java daki Problemler ve OSGi
Teknolojisinin Getirdiği Çözümler
Mehmet Mustafa GÜRSUL
Uzman Yazılım Mühendisi
İÇERİK
ÖZET .................................................................................................................... 1
1.
Modülerlik .............................................................................................................. 1
2.
Java JAR Dosyaları ve Problemleri ..................................................................... 3
3.
Java EE Sınıf Yükleme Mekanizması .................................................................. 9
4.
OSGi Teknolojisi .................................................................................................. 11
5.
The OSGi Alliance and Standards ..................................................................... 14
6.
OSGi Implementations ........................................................................................ 15
7.
OSGi Alternatifleri .............................................................................................. 15
8.
Sonuç ve Değerlendirme ...................................................................................... 16
KAYNAKLAR ..................................................................................................... 16
Java daki Problemler ve OSGi Teknolojisinin Getirdiği Çözümler
-i-
13.06.2009
Özet
Bu dokümanda Java da dinamik modül sistemini gerçek anlamda oluşturmaya
çalışan OSGi dan bahsedilmektedir.
OSGi kavramını tam anlamak için ilk önce;
 Modülerliğin ne demek olduğunu?
 Java da bizlere nelerin nasıl sorun olduğunu anlatılarak OSGi ın
getirdiği çözümler daha iyi anlaşılır hale getirilmektedir.
Anahtar Kelimeler: OSGi, Java, Jar
1. Modülerlik
Herhangi bir büyük bir mühendislik projesinde, örneğin yeni bir köprü, gökdelen,
uçak tasarımında, aşılması gereken en önemli konu nedir acaba? Cevap herhalde
karmaşıklık (complexity) olur.
Örneğin Boeing 747-400 diğer bir adıyla “Jumbo Jet” de;
o 6 milyon parça bulunmaktadır.
o
171 mil (274 km) lik kablo
o
Orijinal tasarımı için 75000 mühendislik çizimi kullanıldı.
Çok çok karmaşık bir makina. Çok karmaşık olduğundan bir kişi Boeing 747 nin
nasıl çalıştığını tam olarak her şeyiyle bilemez. Aynı zamanda ilk olarak 1960 yılında
tasarlanmıştır ve şu anki modern hali defalarca gelişerek karmaşıklık seviyesini
daha da artırmıştır.
İnsanın bu karmaşık makineyi başarıyla tasarlayabilmesinin tek bir yolu vardır. O da
bu makineyi küçük parçalara ayırarak daha anlaşılabilir modüler halde
tasarlamasıdır.
Modülerlik birkaç önemli kazanç sağlamaktadır.

İş Bölümü (Division of labour) :
o
Kişilere ya da gruplara; ayrılmış modüller üzerinde çalışacakları işler
atanabiliyor.
o
Kişilerin sadece kendi modülleri hakkında bilgi sahibi olma gereksinimi
var diğer modüller üzerinde bilgi sahibi olmaları gereksinimi yok.
o
Örneğin uçaktaki eğlence sistemini kuracak kişiler uçağın iniş
sisteminin nasıl olacağı ile ilgili bilgi sahibi olmalarına gerek yoktur.
Eğlence sisteminin en iyi nasıl kurulacağı üzerine yoğunlaşırlar. Tersi
de geçerli tabiki.
Java daki Problemler ve OSGi Teknolojisinin Getirdiği Çözümler
-1-
13.06.2009



Soyutlama (Abstraction) :
o
Uçağı bir bütün halinde soyut bir kavram gibi düşünelim, her bir
parçasının ne işe yaradığını tam anlama ihtiyacımız yoktur.
o
Örneğin uçağın uçması için kanatların kalkmasını ve uçağın ileriye
doğru itme kuvvetinin olmasını kontrol etmeliyiz. Burada motorlara
yakıtın nasıl aktarıldığını ve kanatların açılıp kapanması için kaç tane
motora ihtiyacımız olduğunu bilmemize gerek yoktur.
Yeniden Kullanılabilirlik (Reuse) :
o
Uçağın belki de küçük bileşenlerine bile çok büyük emek harcadıktan
sonra başka bir uçak tasarımında aynı ya da benzer bir bileşene ihtiyaç
duyduğumuzda sıfırdan yeniden başlayarak tasarım yapmak herhalde
istenmeyen bir durum olur.
o
Yeni uçakta; minimum değişikliklerle yeniden kullanılabilir bileşenler
kullandığımızda işimiz kolaylaşacaktır.
Kolay Bakım ve Onarım (Ease of Maintenance and Repair) :
o
Uçağın bir tekerleğinin patlaması sonrası ya da oturulacak yerlerin
kaplamasının yırtılması sonrası tüm uçağı ıskartaya çıkarmak herhalde
istenmeyen bir durum olur.
o
Modüler tasarımla çalışmayan modülün çıkarılması, onarılması ya da
yerine yeni modülün konulmasını, bunları yaparken de diğer kalan
sistemin etkilememesi amaçlanır.
Tabi ki burada bir yazılım ürününün bir mühendislik disiplini içerisinde ele alınıp
alınmayacağı tartışılabilir. Fakat bununla birlikte yazılımın karmaşıklığı diğer alanlarla
yarışabilecek düzeydedir.
Modern yazılımlar karmaşık seviyede aynı zamanda bu karmaşıklık seviyeside gün
geçtikçe artmaktadır.
Örneğin NASA’nın eski uzay mekiğindeki bilgisayarda yaklaşık 500.000 satırlık kod
varken şimdi evimizdeki DVD oynatıcısında bile yaklaşık 1 milyon satırlık kod
bulunmaktadır.Windows XP tahmini olarak 40 milyon, Vista da 50 milyon satır kod
barındırmaktadır.
Sonuç olarak; Yazılım geliştiricileri de aynen uçak mühendisleri gibi büyük ve
karmaşık işler yapmaktadır.
Java Programlama dili, hem büyük hem de karmaşık kurumsal yazılımlar ile küçük
ama çok yaygın olan mobil uygulamalar yapabilmek için de kullanılan popüler
dillerden birisidir.
Bununla birlikte Java modülerliği tam anlamıyla desteklememektedir.
Java daki Problemler ve OSGi Teknolojisinin Getirdiği Çözümler
-2-
13.06.2009
Birazdan var olan Java mekanizmasının, biraz önce değinilen modülerlik ile ilgili 4
maddeyi gerçekleştirmede neden başarısız olduğunu görülecektir.
Bu arada Java nın en önemli gücü esnek olmasıdır. Bu sayede modül sistemini
kolayca Java nın üzerine inşa edebilmekteyiz. Bu modül sistemi OSGi olarak
adlandırılmakta.
Modül Ne Demektir?
Yazılımda modül neye benzer olmalıdır? Aşağıdaki özelliklere sahip olmalıdır.

Self-Contained : Modül bir bütün olarak mantıksaldır. Tek bağımsız bir birim
halinde install, uninstall edilebilir. Atom değildir yani daha küçük parçalardan
oluşmuştur, fakat bu parçalar kendi başlarına olamazlar. Eğer herhangi bir
parçası kaldırılırsa da modülün işlevselliği sona erebilir.

Highly-Cohesive : Cohesion, modülün sorumlulukları ile ne kadar ilgili ya da
odaklandığı ile ölçülür. Modül ilgisiz şeyler yapmamalıdır. Bir tane mantıksal
amaca bağlı kalmalı ve bu amacı tam olarak yapmaya odaklanmalıdır.

Loosely Coupled : Modül etkileşimde olduğu diğer modüllerin gerçekleştirim
(implementation) detaylarına bağımlı olmamalıdır. Loose Coupling bizlere şu
imkanı vermektedir: Bir modülün gerçekleştirimini değiştiririz. Fakat bunu
yaparken bu modülü kullanan diğer modüllerde herhangi bir güncelleme
gereksinimine ihtiyaç duymayız.
Bu üç özelliği de modülde sağlamak için modülün çok iyi tanımlanmış arayüzlere
ihtiyacı vardır.
Kararlı arayüzler;
 Modüller arasında mantıksal sınırlamaları sağlamakta

İç gerçekleştirim detaylarına erişimi engellemektedir.
İdeal olarak arayüzler;
 Her bir modülün diğer modüllere neleri sunduğunu ,

Ve her bir modülün de diğer modüllerden nelere gereksinimi olduğunu
belirtir biçimde olmalıdır.
2. Java JAR Dosyaları ve Problemleri
Java da standart deployment birimi JAR File Specification a göre belirlenmiş olan JAR
dosyalarıdır.
Birçok dosyayı bir tek dosyada toplayan Zip dosyası formatındadır. Genel olarak
derlenmiş Java ve kaynak dosyaları (images, dokümantasyon v.b.) içerir. Ek olarak
META-INF dizininde JAR ile ilgili bilgi içeren dosyalar bulunmaktadır. Bunlardan en
önemlisi MANIFEST.MF dosyasıdır.
Çok nadiren bir uygulama bir tek JAR dosyasından oluşur. Genellikle bir uygulama
birçok JAR dosyasının bir araya gelmesiyle oluşur.
Java daki Problemler ve OSGi Teknolojisinin Getirdiği Çözümler
-3-
13.06.2009
JAR dosyaları kullanıldığında karşılaşılan 4 büyük problem şunlardır:
 Çalışma zamanında (runtime da) JAR anlamlı bir kavram değil, sadece build
zamanı ve deploy zamanında anlamlı. JVM çalıştığında tüm JAR dosyalarının
içindeki dosyalar birleştirilerek bir tek liste oluşturulur ve classpath e eklenir.
 Bağımlılıklarını belirten standart bir meta-data sı içermemektedir.
 Versiyonlanmamıştır ve aynı anda JAR ın birden çok versiyonu
yüklenememektedir.
 JAR lar arasında information-hiding mekanizması yoktur.
Sınıf Yükleme ve Global Classpath
 “classpath”
o “java” komutuna parametre olarak geçmektedir.
o JAR dosyalarının listesini ve derlenmiş java dosyalarının dizinini
belirtmektedir.
o Örneğin aşağıdaki komut java uygulamasını classpath inde log4j.jar ve
classes dizinini içerecek biçimde başlatmakta. Son parametre
çalıştırılacak main metodu bulunan java sınıfı. classes dizini içerisinde
org/example/HelloWorld.class şeklinde içerisinde yer almaktadır.
java -classpath log4j.jar:classes org.example.HelloWorld
Not: UNIX için parametre ayrımı “:” ile Windows için “;” iledir.




JVM bir şekilde .class uzantısındaki dosyaları fiziksel diskte bulup Class
objesine çevirdikten sonra belleğe yükleyip static main metodunu çalıştırması
gerekiyor. Bu standart JRE de nasıl oluyor ona bakalım :
Java da sınıfları yükleyen sınıf java.lang.ClassLoader sınıfıdır ve 2 tane
sorumluluğu vardır.
o Mantıksal isimden .class dosyasının fiziksel ortamda bulunması
o Fiziksel ortamdaki bu byteların Class nesnesine bellekte çevrilmesi.
ClassLoader sınıfını ektend edip kendi gerçekleştirimimizi de yapabiliriz ayrıca.
Böylece sınıfları bir network ten ya da dosya tabanlı olmayan bir sistemden
bulup yükleyebiliriz. Ama ikinci kısım olan sınıftaki fiziksel byteların Class
nesnesine çevrim işi ClassLoader daki native ve final olan yani yeniden
implement edilemeyen (not overriden) bir method olan defineClass() ile
olmaktadır.
java -classpath log4j.jar:classes org.example.HelloWorld
bu komutu çalıştırdığımızda JRE org.example.HelloWorld sınıfını yüklemesi
gerektiğini anlar. Özel bir ClassLoader olan Application Class Loader a
yüklemesini söyler. Application Class Loader da bir üst sınıf olan Extension
ClassLoader a, o da bir üst sınıfı olana Bootstrap ClassLoader söyler. Default
olarak her classloader ilk önce bir üst sınıfına sorar. Eğer üst sınıfı bulmaz ise
kendi arayıp yüklemeye çalışır.
Java daki Problemler ve OSGi Teknolojisinin Getirdiği Çözümler
-4-
13.06.2009
HelloWorld örneğimize dönecek olursak;
JRE base de ve extension library de bulunmadığını kabul ediyoruz. Bundan dolayı
bootstrap ve extension class loader lar tarafından bulunamayacaktır ve application
class loader bulmaya çalışacaktır. Bunu yaparken
 Classpath deki sırasıyla herbir entry de bakacak ve bulur bulmaz da
aramayı durduracaktır.

Classpath deki herbir entriye bakıp bulamazsa tanıdık bir exception olan
ClassNotFoundException ı verecektir.
Özet olarak;
1.
2.
3.
4.
5.
JRE Application ClassLoaderdan sınıfı yüklemesini ister
Application ClassLoader , Extension ClassLoader dan sınıfı yüklemesini ister
Extension ClassLoader, Bootstrap ClassLoader dan sınıfın yüklenmesini ister
Bootstrap ClassLoader sınıfı bulamaz, Extension Class Loader bulmaya çalışır
Extension ClassLoader sınıfı bulamaz, Application ClassLoader classpath deki
log4j.jar dan aramaya başlar
6. Sınıf log4j.jar da bulunamayınca classes dizininde aranmaya başlar
7. HelloWorld sınıfı bulunur ve yüklenir.
Her bir sınıf istemi için tekrar 1. Adımdan başlayarak arama yapılır.
Java daki Problemler ve OSGi Teknolojisinin Getirdiği Çözümler
-5-
13.06.2009
Sınıfların Çakışması
Java da sınıf yüklemeleri çoğu zaman doğru çalışır fakat aşağıdaki durum olduğunda
neler olacağını düşünelim.
Diyelim ki yanlışıkla yardim.jar adında HelloWorld ün eski bir versiyonunu içeren
bir jar ı classpathe ekledik.
java -classpath yardim.jar:log4j.jar:classes org.example.HelloWorld
yardim.jar classes dan once geldiğinden application class loader yardim.jar içinde
HelloWorld ü bulunca aramayı durduracaktır ve bu komutla her zaman HelloWorld ün
eski versiyonu yüklenecektir. Ve bizim classes dizinimizdeki HelloWorld hiç bir zaman
kullanılmayacaktır. Bu durumda da sınıf tam olarak beklenen işlemleri yapamayacak
ya da yaptığımız değişikliklerin hiç bir etkisi olmayacaktır.
Bu durum Java daki önemli sorunlardan birisidir.
Bu senaryo pek olmayacak bir senaryo gibi gelebilir ya da sıradan basit
uygulamalarda bu durum oluşabilir ve biz de sorunu hemen bulup düzeltebiliriz
diyebiliriz. Fakat büyük çaplı Java uygulamaları onlarca bazen de yüzlerce jar
dosyasından oluşmaktadır ve bunların hepsi de classpath de gözükmek zorundadır.
Ayrıca JAR dosyaları bazen içeriği ile tam da anlamlı bir isme sahip olmayabiliyor. Bu
durumda aynı isme sahip çakışan sınıflar olma ihtimali olmaktadır. Örneğin en çok
karşılaşılan sorun aynı Jar ların farklı versiyonlarındaki sınıflarının çakışmasıdır.
Broken internal jar dependecy
JRE tum jarları bir tek liste gibi gördüğünden yukarıdaki durum oluştuğunda yine
sorun çıkacaktır.
java -classpath naughty.jar:foobar.jar… Foo
Çünkü naughty.jar foobar.jar dan once classpathe de yer aldığından Foo sınıfı
içerisinden Bar sınıfı kullanılmak istendiğinde naughty.jar daki Bar sınıfı
kullanılacaktır.
Java daki Problemler ve OSGi Teknolojisinin Getirdiği Çözümler
-6-
13.06.2009
Açıkça Bağımlılıkların Belirtilme Eksikliği (Lack of Explicit Dependencies)
Bazı JAR dosyaları diğer JAR dosyalarına bağımlı olmadan işlevlerini yerine getirirler.
Bununla birlikte çoğu JAR dosyası başka JAR dosyalarına ihtiyaç duyar. Ancak diğer
jar dosyaları da deploy edilmiş ise kullanılabilirler. Örneğin Apache Jakarta Commons
HttpClient jar ı Commons Codec ve Commons Logging jar a ihtiyaç duymaktadır.
Dolayısıyle classpath de commons-logging.jar and commons-codec.jar olmaz ise
çalışamaz.
Fakat biz bu bağımlılığı nasıl biliyoruz? Çünkü Httpclient iyi dokumente edilmiş ordan
biliyoruz. Projenin web sayfasında bağımlılıklar açık bir biçimde belirtilmiştir. Fakat
birçok library bu şekilde güzel bir biçimde dokumente edilmemiştir. Dolayısıyle belli
olmayan böyle bir Jar ı kullandığımızda ClassNotFoundException alma ihtimalimiz
yüksektir.
HttpClient daki gibi iyi dokumente edilse bile aslında yeterli değildir. Bizim
istediğimiz;
 standart bir yöntemle bağımlılıkların tanımlanması
 tercihen Jar file içinde bu tanımın yapılması
 tool larla da bu bağımlılıkların analiz edilebilmesidir.
Versiyonlama Eksikliği (Lack of Version Information)
Kütüphaneler değişmekte, geliştirilmekte ve zamanla yeni versiyonları çıkmaktadır.
Bundan dolayı bir kütüphanenin bağımlı JAR larının hangileri olduğunun yanında bu
JAR ların hangi versiyonlarına bağımlı olduğu bilgisi de gereklidir.
Örneğin bir JAR ımız, log4j jar a bağımlılığı olsun. Fakat JAR ımızın çalışması için,
log4j nin hangi versiyonuna ihtiyaç duymakdır? (En son logj nin web sayfasına
baktığımda 25 farklı versiyon gördüm 4 Haziran 2009 da). En son yani latest
versiyonu kullanalım demek de mantıklı değil, çünkü son versiyona göre JAR ımız
test edilmemiş olabilir.
JAR ımızın içerisinde “bu jar log4j nin 1.2 versionu üzerindeki jarlarla çalışabilir”
ifadesi dokumante edilmiş ise güzeldir ama genelde böyle bir bilgi nadiren vardır olsa
da toollar tarafından kullanılabilecek formatta olmayabilir.
Sonuç olarak bizim açıkça JAR ımızın hangi versiyon aralığındaki jar lara bağımlı
olduğumuzu bir şekilde belirtmemiz gerekmekte.
Versiyonlar aşağıdaki diğer bir probleme daha yol açmaktadır.
Java daki Problemler ve OSGi Teknolojisinin Getirdiği Çözümler
-7-
13.06.2009
Uygulamamızın şekildeki gibi A ve B adlı iki kütüphaneye ihtiyaç duyduğunu
düşünelim. Ayrıca A ve B kütüphanelerinin de üçüncü parti diğer bir kütüphane olan
C kütüphanesine bağımlı olsun. Fakat A, C ‘nin 1.2 , B de C nin 1.1 versiyonuyla
çalışabilsin.
Classpath=C1.2.jar:C1.1.jar
Global classpath sahip olduğumuzdan C nin iki versiyonunu da classpathe
eklediğimizde, classpath e eklediğmiz ilk versiyonu hem A hem de B kullanmak
zorunda kalacaktır.
Burada dikkat edilmesi gereken C nin büyük versiyonu, numarası yüksek olduğundan
dolayı kullanılacaktır diye bir şey yok eğer classpath de büyük versiyon öndeyse
kullanılacaktır. Eğer küçük olan versiyon classpath de önceyse o kullanılacaktır.
Bununla birlikte 1.1 deki bazı sınıflar da eğer isimleri 1.2 dekinden farklı ise yine
kullanıma açık olacaktır. Ve eğer bu sınıflardan birisi kullanılırsa bu sınıfın da
kullandığı başka bir sınıf varsa ve eğer 1.2 de bu kullandığı sınıfın yeni versiyonu
varsa onu kullanmaya çalışacak ve LinkageError gibi bir hata alma ihtimali
doğacaktır.(aşağıdaki naughty.jar da olan duruma benzer bi durum)
JAR lar arasındaki Bilgi Saklama Eksikliği (Lack of Information Hiding Across
JARs)
Bütün OOP dilleri information hiding için sınıf ve modül bazında belirli yöntemler
sunarlar.
Java; sınıftaki üyeler (alanlar ve methodlar) için 4 farklı erişim belirleyicisi sağlar.
 public üyeler tüm sınıflar tarafından erişilebilir.
 protected üyeler alt sınıflar ve aynı paketteki diğer sınıflar tarafından
erişilebilir.
 private üyeler sadece aynı sınıfın içindekiler tarafından erişilebilir.
 Yukarıdakiler erişim belirleyicilerinden herhangi birisiyle tanımlanmamış
üyeler ise varsayılan olarak “default”olarak adlandırılan erişim belirleyicisine
sahiptir. Bu üyeler aynı paketteki diğer sınıflar tarafından erişilebilirler.
Java daki Problemler ve OSGi Teknolojisinin Getirdiği Çözümler
-8-
13.06.2009
Sınıflar için ise sadece public ve default erişim belirleyicisini kullanabilmekteyiz.
public sınıflar diğer tüm paketlerdeki sınıflar tarafından erişilebilmekte, default sınıflar
ise sadece aynı paketteki diğer sınıflar tarafından erişilebilmektedir.
Burada bir eksiklik var dikkat ettiyseniz. Erişim belirleyicileri paket seviyesine göre
belirlenmekte fakat Java da deployment birimi paket değil Jar dosyasıdır. Birçok Jar
dosyası birden fazla paketten oluşmaktadır. Ve aynı jar içindeki farklı pakette
bulunan sınıflar biribirlerine erişme ihtiyacı duymaktadırlar. Bunu sağlamak için de ne
yazıkki bu sınıflar public yapılmaktadır.
Özet olarak public yapılan sınıflar Jar ın dışındaki sınıflar tarafından da
erişilebilmektedir. Bundan dolayı biz istemesek de JAR ımız public hale gelmiş oluyor.
Bu da Jar dosyaların diğer bir sorunu olarak karşımıza çımakta.
Sonuç olarak : JAR lar Modül değildir!!!
Şimdiye kadar Jar dosyalarındaki belirli sorunları gördük. Tabi ki bu gördüklerimiz
Java da modüler sistem oluşturamayacağımız anlamına gelmemekte. Sadece şu anda
Java modüler sistem amacına ulaşmak için bir yardım sunmamakta. Bundan dolayı
modüler sistem kurmak bir süreci ve disiplini gerektirmekte.
3. Java EE Sınıf Yükleme Mekanizması
Java EE specification; dağıtık ve çok katmanlı bir platform tanımlamaktadır. Java EE
mimarisinin nin merkezi özelliği bir çok uygulama bileşenini yöneten ve bu
bileşenlere transaction,security gibi kurumsal servisler sunan “uygulama sunucusu”
bölümüdür.
Uygulama sunucuları ayrıca; server ı restart etmeden ve diğer uygulamaları
etkilemeden uygulamaları deploy etmek, un-deploy etmek için bir deploymentsistemine ihtiyaç duymaktadırlar.
Bu ihtiyacı karşılamak için Java EE uygulama sunucuları her bir deploy edilen
uygulama için biraz daha karmaşık, aşağıdakine benzer bir class-loading yapısı
kullanmaktadırlar.
Java daki Problemler ve OSGi Teknolojisinin Getirdiği Çözümler
-9-
13.06.2009

Java EE uygulamaları EAR dosyaları halinde deploy edilirler. Bu EAR dosyaları
aşağıdakileri (ilki ve diğerlerinden bir ya da birkaçını) içeren zip dosyalarıdır;
o Metadata dosyası, application.xml;
o Düz Java dosyalarını içeren Jar dosyası
o EJB uygulamalarını içeren Jar dosyaları (EJB-JARs)
o Web işlevlerini yerine getiren sınıfları, Servlet-JSP gibi, içeren Web
Archive dosyası (WAR)

Düz Java dosyalarını içeren Jar dosyaları; EAR içindeki tüm EJB-JAR ları ve
WARları tarafından erişilmesi düşünülen sınıfları içermektedirler. Bu nedenle
EAR Class Loader tarafından bu sınıflar yüklenmektedir.
o Önceden anlattığımız class loading mekanizmasını bir daha
hatırlayacak olursak. Bir class loader sadece, kendisi ya da atası
tarafından tanımlanmış sınıfları yükleyebilmektedir. Yani ek olarak
kardeşlerini (siblinglerini) yükleyememektedir. Bu nedenle EJB ve WAR
tarafından paylaşılan ya da kullanılan sınıflar EAR Class Loader a
konulması gerekmektedir.
o Ayrıca eğer deploy edilen birçok uygulama tarafından bir sınıf
kullanılacaksa bu sınıfın system application loader seviyesine
konulması gerekmektedir. Bu da application server ın restart
edilmesine ve JAR dosyasının global classpath e eklenmesine neden
olmaktadır.
o system application loader seviyesine çıkarılan libraryler;

kullanabilmek için restart gerekli
Java daki Problemler ve OSGi Teknolojisinin Getirdiği Çözümler
- 10 -
13.06.2009


Biz sadece deploy edilen bir kaç uygulamanın kullanmasını
diğerlerinin kullanmamasını istediğimiz halde, deploy edilen tüm
uygulamalar için kullanılabilir hale gelecektir.
Sınıf çakışmalarına (Class conflict) neden olacaktır.
 Üst seviyede bunulan sınıflar daima alt tarafta bulunan
aynı sınıflara göre öncelikliği olduğundan alttaki sınıflar
ezilecektir.
 Serverda bulunan tüm uygulamalar üstte bulunan
kütüphanenin aynı versiyonunu kullanmak zorunda
kalacaktır.
Bu nedenlerden dolayı Java EE geliştiricileri farklı uygulamalar tarafından kullanılan
ortak sınıflar tanımlamaktan uzak durmaya çalışmaktadırlar. Birden fazla uygulama
tarafından ortak kullanılacak bir kütüphane olduğunda da bu kütüphane herbir EAR
içine ayrı ayrı konularak çoğaltılmaktadır. Sonuç olarak “boru” şeklinde düşey olarak
etkileşim kurmakta yatayda etkileşim kuramamaktadırlar.
4. OSGi Teknolojisi




OSGi, Java için bir modül sistemidir.
Gerçek anlamda bir modül oluşturmamızı ve bu modüllerin çalışma zamanında
birbirleriyle etkileşimde bulunabilmesi için yöntem sunar.
Temel olarak felsefesi basittir:
o Java da bir çok sorunun kaynağı global ve düz olan classpath ten
dolayıdır. OSGi bu nedenle tamamen farklı bir yaklaşım sunmaktadır.
 Her bir modül kendi classpath ine sahiptir. Bu birçok problemi
ortadan kaldırmaktadır.
 Peki paylaşılan sınıflar ne olacak?
 OSGi; sınıfların modüller arasında nasıl
paylaşılabileceğine dair açıkça belirtilen “import ve
export” mekanizmasını kullanmaktadır.
Peki OSGi da modüle neye benziyor? OSGi da aslında modül ismi yerine başka
bir kelime kullanılmakta: bundle . Bundle da aslında bir JAR dosyası. Yani
yeni bir standart tanımlanmıyor. Sadece, JAR dosyasına metadata eklenerek
bundle haline getirilmektedir.
o Metadata şunlardan oluşmakta:
 Bundle ın adı.
 Bundle versiyonu.
 import lar ve exportlar
 İsteğe bağlı olarak, bu bundle ın minimum hangi java versiyonu
ile çalışabileceği.
 Ve bundle ile ilgili diğer bilgiler (üretici adı, adresi, telif hakkı
v.b)

Bu bilgiler Jar dosyası içerisinde MANIFEST.MF adındaki dosyada
bulunmaktadır.
Java daki Problemler ve OSGi Teknolojisinin Getirdiği Çözümler
- 11 -
13.06.2009
Ağaçtan Çizgeye (Graph) Geçiş

Peki herbir bundle için ayrı classpath ne anlama geliyor?
o Çok basit: herbir bundle için bir classLoader sağlanmaktadır. Bu
ClassLoader JAR dosyası içerisindeki sınıfları ve kaynakları
(image v.b) görebilmektedir.
o Bununla birlikte bundle ların beraber çalışabilmesi için de bir
bundle daki ClassLoader ın gelen istemi diğer bundle ın
ClassLoader ına delege etmesi gerekmektedir.
o Java ve Java EE de ClassLoader mekanizmasının hiyerarşik bir
ağaç şeklinde olduğunu anlatmıştık. Ve burada ClassLoading
istemleri hep üst sınıfa delege edilmekte idi. Ayrıca burada
sınıflar yatay olarak paylaşılamamakta idi. Paylaşılmak için bir
üst ClassLoader ın yükleyeceği yere sınıfları koyuyorduk fakat
bu da herkesin bu sınıflara erişimine neden oluyordu.
o Sonuç olarak ağaç yanlış bir yapı classloading için. Bizim ihtiyaç
duyduğumuz şekil graph (çizge).
o İki bundle arasındaki bağımlılık hiyerarşik değil. Baba, çocuk
yapısı yok. Sadece sağlayıcılar ve kullanıcılardan oluşan bir ağ
var.
o ClassLoading istemleri; bir bundle dan diğer bundle a, bundle
lar arasındaki bağlımlılık ilişkisine (depedency relationship) göre
delege edilmektedir.
Yukarıdaki şekilde 5 adet birbiriyle bağımlılıkları da gösterilen
bundle gözükmektedir. Bundle lar arasındaki bağlar import ve
export edilen paketler üzerinde kurulmuştur.Yani java paketi
javax.swing ya da org.apache.log4j gibi.


B bundle ının org.foo adlı pakete sahip olduğunu düşünelim. Eğer bu
paketi dışarıya açmak istiyorsa MANIFEST.MF dosyasında export ile
belirtilen satırda bu paketin adını belirtir.
A bundle ı da eğer B bundle ındaki bu org.foo bundle ını kullanmak
istiyorsa MANIFEST.MF dosyasında import ile belirtilen satırda bu
paketin adını ekler.
Java daki Problemler ve OSGi Teknolojisinin Getirdiği Çözümler
- 12 -
13.06.2009





Bundan sonrası yani import takilerle export takilerin eşleşip
eşleşmediğinin kontrolünü OSGi framework yapacaktır. Bu işleme
“resolution process” denilmektedir ve çok karmaşık bir yapısı vardır.
Bundle geliştiricisi olarak bizim yapacağımız sadece import ve
exportları belirtmektir gerisini OSGi framework yapacaktır.
import daki bir değer export daki bir değer ile eşleşir eşleşmez bu
ilişkideki bundle lar belirtilen paket ismi ile birbirlerine bağlanmış
olurlar (wired). Bu ne anlama geliyor? Bundle A da, org.foo paketi
içindeki bir bir sınıfın yüklenmesi istemi geldiği zaman bu istem hemen
Bundle B deki Class Loader a delege edilir.
Aynı durum A nın ilişkide oluduğu C bundle ı için de düşünülebilir. Yani
eğer C deki org.bar paketi kulanılmakta ve Bundle A da, org.bar paketi
içindeki bir bir sınıfın yüklenmesi istemi geldiği zaman bu istem hemen
Bundle C deki Class Loader a delege edilir.
Bu durum son derece etkindir. Klasik Java da ClassLoader çok uzun bir
sınıf listesinde arama yaparken OSGi Class Loader ları; sınıfı nerede
bulacağını genellikle hemen bilmektedir, çok az arama yaparak ya da
hiç arama yapmadan.
Peki “resolution” süreci başarısız olursa ne olmaktadır? Örneğin
uygulamamıza Bundle B yi yüklemeyi unutursak? org.foo paketini
kullanan Bundle lar da ne olacaktır?
o Bu durumda A bundle ı çözümlenemeyecektir ve
kullanılamayacaktır.
o Ayrıca gayet açıklayıcı bir biçimde A Bundle ının neden
kullanılamayacağına dair bir hata mesajı alırız.
Versioning and Side-by-Side Versions
OSGi sadece paket ismine göre bağımlılıkları tanımlamamıza olanak
sağlamamaktadır. Aynı zamanda paketin versiyonuna göre de bağımlılıklar
tanımlanabilmektedir.
Export edilecek paket adları bir versiyon özelliği ile birlikte tanımlanmaktadır. Fakat
import lar versiyon aralığı ile tanımlanmaktadır. Bu bize şunu sağlamaktadır: Örneğin
bundle ımız x paketinin 1.2.0 ile 1.4.3 versiyonu arasındakilere bağımlıdır. Eğer
paketin bulunduğu bundle da bu aralıkta bir export yok ise o zaman bizim bundle
ımız çözümlenemez ve neden çözümlenemeyeceğine dair açıklayıcı bir hata mesajı
alırız.
Dikkat ettiyseniz aynı kütüphanenin farklı versiyonları uygulamamızda bu sayede
kullanabilmekteyiz.
Dinamik Modül
 OSGi, sadece Java için bir modül sistemi değildir aynı zamanda dinamik
bir modül sistemidir.
 OSGi daki bundle lar; uygulamamızın tümünü etkilemeden install, update
ya da uninstall edilebilmektedir.
 Bu bize serverdaki uygulamımızın bir parçasını değiştirmeyi, bir bug ı
çözerek ya da yeni bir özellik ekleyerek, diğer parçalar etkilenmeden
yapabilme imkanı sağlamaktadır.
 Ayrıca desktop uygulamalarımızda; server ı restart etmeden yeni
versiyonları download edebilmemizi böylece kullanıcıyı kesintiye
uğratmadan uygulamayı kullanabilmesini sağlamaktayız.
 Dinamik modül özelliğini sağlamak için OSGi lifecycle-layer a sahiptir.
Java daki Problemler ve OSGi Teknolojisinin Getirdiği Çözümler
- 13 -
13.06.2009

Birçok geliştirici OSGi ın dinamik modül özelliğine kuşkuyla bakmaktadırlar
ve OSGi ın life-cycle layer ını önemsemeyerek sadece modülerlik kazancını
önemsemektedirler. Tabi ki bu durum Java EE daki güvenilmeyen “hot
deployment” özelliğinden dolayı mantıklı görülebilir. Fakat OSGi ın dinamik
modül özelliği bir aldatmaca değildir. Gerçekten çalışmaktadır ve bazı
denemeler de bunu doğrulamaktadır.
5. The OSGi Alliance and Standards

OSGi standartları yaklaşık 40 şirketin yer aldığı bir organizasyon
tarafından tanımlanmaktadır.
 OSGi ile ilgili en çok sorulan iki soru?
o OSGi açılılımı ne demektir?
o Neden i harfi küçük?
Cevap olarak. OSGi açılım olarak bir anlamı yok. Önceden Open
Services Gateway initiative olarak adlandırılmakta idi. Küçük i harfi de
buradan gelmekte, uzun isimde i nin biçimsel olarak yeri yoktu. Fakat
uzun isim sonradan kullanım dışı oldu.
 OSGi “home gateway” yani evdeki tüm cihazları tek bir noktadan
kontrol edebilme amacıyla başta geliştirilmiş olsa da artık
genişleyerek çok daha geniş bir alanda kullanılmaktadır.
 Sonuç olarak OSGi ismi tuhaf gelebilir. Fakat anlamlı bir kelime ya
da bir kelimenin parçası olmadığından google da arama yapabilmek
için güzel bir isimlendirme
 Konuşurken de (“Oh Ess Gee Eye”) diye okunmaktadır. Ozjee diye
okunmaz.
 OSGi Alliance ın rolü;
o Specificationları tanımlamak
o Specification a göre geliştirilen gerçekleştirimleri certified
etmek (onaylamak).

Teknik işler; birçok sayıdaki Expert Group (EG) tarafından
yapılmaktadır.
o Core Platform Expert Group (CPEG),
o Mobile (MEG),
o Vehicle(VEG)
o Enterprise (EEG) Expert Groups.
Bu dokumanda , biz daha çok CPEG in yaptığı işlere değindik.
Java daki Problemler ve OSGi Teknolojisinin Getirdiği Çözümler
- 14 -
13.06.2009
6. OSGi Implementations
Günümüzde birbirinden bağımsız olarak geliştirilen birkaç tane OSGi frameworkü
bulunmaktadır. Bunlardan open-source olarak geliştirilen 4 tanesi:
 Equinox
o OSGi Specification ın 4.1 relase ini implement etmiştir.
o IBM Webshere Application Server, Lotus Notes gibi uygulamalar
kullanmıştır.
o EPL (Eclipse Public Licence)

Knopflerfish
o OSGi Release 3 ve Relase 4.1 specification ın gerçekleştirimidir.
o BSD Lisans.

Felix : Apache
o OSGi Release 4.x specificationların gerçekleştirimidir
o Apache Lisans

Concierge
o OSGi Relase 3 ün optimize edilmiş implementasyonudur.
o Optimize edildiği için kaynak kısıtlı örneğin mobil uygulamalar için
uygundur.
7. OSGi Alternatifleri
OSGi, getirdiği güzel yaklaşımlara göre karmaşıklığı basittir. Diğer bazı
gerçekleştirimler OSGi kadar olgunlaşmamış ya da yaygın kullanılmamıştır. Fakat
bazı alternatiflere bakalım ki en azından OSGi ın geliştirilirken etkilendiği güzel
fikirleri görmüş oluruz.
Build



Tools: Maven and Ivy
Maven ve Ivy modüler sistemin bazı özelliklerine sahiptir.
Fakat bu araçlar build-time araçlarıdır run-time değillerdir.
Run-time aracı olmadıklarından JAR daki Global classpath, information
hiding gibi sorunlara çözüm getirememektedirler.
 Doğrudan OSGi ile karşılaştırılamaz, aslında OSGi temelli uygulama
geliştirmek için kullanılan yardımcı araçlardır.
Eclipse Plug-in System
 Şu anda Eclipse bir OSGi implementation ı olan Equinox tabanlıdır.
 Fakat Eclipse 3.0 dan önce kendi modül sistemine sahipti. Eclipse de
modül e plug-in denilmekte idi. Plug-in ler de plugin.xml dosyasını
içermekteydi. Bu dosya OSGi daki MANIFEST.MF e çok benzer bir
yapıdaydı.
 OSGi bundle ile olan fark şurda : OSGi da bağımlılıklar paket
seviyesinde tanımlanırken, Eclipse plug-in de bağımlılıklar tüm plug-in
bazında tanımlanmaktadır. Böylece plug-in deki tüm paketlere
erişebilmektedir. OSGi da tüm bundle a bağımlılığı sağlamakla birlikte ,
bu özelliği kullanmanın bazı sakıncaları vardır.
 Eclipse plug-in sistemindeki en büyük eksiklik plug-in lerin dinamik bir
biçimde install ve uninstall edilememesidir. Plug-in graph i değişir
değişmez full restart gerekmektedir. Equinox projesiyle eclipse de
Java daki Problemler ve OSGi Teknolojisinin Getirdiği Çözümler
- 15 -
13.06.2009
dinamik olarak plug-in sistemini yapmak için uğraşmış ve sonunda bu
sistem için OSGi seçilmiştir.
1.2.3 JSR 277
 Java Specification Request 277 diğer bir adıyla “Java Modüle
System” dir.
 OSGi ın uğraştığı problemlerin aynısına JSR da çözüm getirmeye
çalışmaktadır.
 Fakat JSR bitirilmemiş bir specification ve implementation I vardır.
 Java 7 de bitirilmesi düşünülüyordu fakat henüz belli değil.
 Eclipse plug-in sistemi gibi paket seviyesinde bağımlılığı
desteklememektedir.
 Dinamik değildir, JVM nin yeniden restart edilmesi gerekmektedir.
8. Sonuç ve Değerlendirme
Java şu anki yapısıyla dinamik modül sistemini sağlamamaktadır. OSGi
teknolojisi ile dinamik bir modül sistemi oluşturulmakta ayrıca Java daki classpath,
JAR problemlerine çözüm getirilmektedir.
Kaynaklar
1. OSGi In Practice - Neil Bartlett
2. http://www.osgi.org
Java daki Problemler ve OSGi Teknolojisinin Getirdiği Çözümler
- 16 -
13.06.2009
Download