4 Ağustos 2011 Perşembe

Arşiv Dosyaları

Java'nın kısa sürede yaygınlaşmasındaki önemli etkenlerden biri—belki de en önemlisi—Bytecode komutları içeren standardize edilmiş sınıf dosyalarının sanal makine üzerinde çalışmasıyla sağlanan makine kodu düzeyindeki taşınabilirlik özelliğidir. Java'nın doğum yeri olan Sun şirketi tarafından "Bir kez yaz, her yerde çalıştır" (İng., write once, run anywhere (WORA), write once, run everywhere (WORE)) sloganıyla tanıtılan bu özellik sayesinde, Java programlarının derlendikten sonra JSM bulunduran herhangi bir platformda çalıştırılması mümkün olmaktadır. Bunun için, gerekli sınıf dosyalarının konulduğu bir siteden indirilmek veya CD içinde verilmek suretiyle kullanıcıya sağlanması yeterli olacaktır.

  1. [Geliştirici] Geliştirilen programı derleyerek sınıf dosyası haline çevir.
  2. Sınıf dosyalarını kullanıcıya sağla.
  3. [Kullanıcı] Programı çalıştır.

Yazılımın büyümesiyle birlikte yukarıdaki 2 nolu adıma konu olan dosyaların sayısı artacak ve bu da dağıtım işini zorlaştıracaktır. Ayrıca, gereksinilen disk alanı ve indirme zamanı da olumsuz etkilenecektir. Örnek olarak, 90'ların ortalarında Microsoft'un Wintel bağımlısı çözümlerine karşı alternatif olarak ortaya çıktığında büyük heyecan yaratan uygulamacıkların (İng., applet) örün tarayıcıları tarafından çalıştırılmasına göz atalım. Kendisine bağlantı veren sayfalara dinamik içerik sağlayan ve etkisini kullanıcı tarafında çalıştırılarak gösteren uygulamacıklar işlerini şöyle görür.

  1. Kullanıcı uygulamacık bağlantısı barındıran bir sayfaya tıklar.
  2. Sayfa ile birlikte uygulamacığı oluşturan sınıf dosyaları ve diğer kaynaklar (görüntü, ses, vb.) indirilir.
  3. Uygulamacık, tarayıcıdaki JSM tarafından çalıştırılır.

Yukarıda kabaca anlatılan sürecin hızı, uygulamacığın gerçekleştiriminde seçilen algoritma ve veri yapıları seçimlerine ek olarak, 2. adımda indirilen dosyaların sayısı ve büyüklüğüne göre değişecektir. Dosyaların artması ve büyümesi performansı ve kullanıcı deneyimini olumsuz yönde etkileyecektir. İşte bundan dolayı—daha genel bir ifadeyle, yazılım dağıtımını daha etkin hale getirmek için—Java platformu tasarımcıları arşiv dosyalarını sağlamışlardır. Buna göre, geliştiricilerden beklenen, birlikte indirilecek/kurulacak dosya ve kaynakları sıkıştırarak bohçalayan arşiv dosyalarının kullanımıdır.

Arşiv Manipülasyonu


Arşiv dosyaları Yazılım Geliştirme Kutusu'nun parçası olan jar adlı arşivci komutu yardımı ile oluşturulabilir. Bu komut, ZIP-temelli formata sahip bir arşiv oluşturmanın yanısıra, verilen bir arşivin güncellenmesi, içeriğinin listelenmesi ve açılması için de kullanılabilir. Hangi işlemin kastedildiği komut adını takiben verilen ve aşağıdaki değerleri alabilen bir opsiyon ile belirtilir. Listelenenlere ek olarak, f opsiyonunun işlemin hedefi olan arşiv dosyasının adı için kullanıldığı bilinmelidir. Ayrıca, işlemin neler yaptığını daha ayrıntılı bir biçimde standart çıktıya basan v opsiyonu da kimi zaman yardımcı olabilir. Son olarak, girdi sağlanmasını gerektiren birden çok opsiyonun kullanılması durumunda, arşivcinin opsiyon sırası ile girdi sırasının aynı olduğunu varsaydığı unutulmamalıdır.1

Arşiv dosyası işlemleri
OpsiyonAnlamı
cOluşturma
uGüncelleme
tİçerik listeleme
xAçma

Buna göre, aşağıdaki komut o anki çalışma dizininin içindeki a.class ve b.class dosyalarının yanısıra images dizininin içindeki dosyalardan oluşan ArşivDosyası.jar adlı bir arşiv yaratacaktır.2 Dizin içindeki dosyaların ele alınması sırasında, altdizinlerin özyinelemeli bir biçimde işlendiği unutulmamalıdır. Yani, komutumuz images içindeki tüm dosyaları, altdizinler içindekiler de dahil olmak üzere, arşive katacaktır. Arşive nelerin girdiğini görmek isterseniz, v opsiyonu işinizi görecektir.
$ # Arşiv oluşturma
$ jar cf ArşivDosyası.jar a.class b.class images
İşlemin daha az zahmetli olmasını sağlamak için, dosya adı sağlama sırasında joker karakterinden yararlanılabilir. Örneğin, çalışma dizini içindeki sınıf dosyalarının a.class ve b.class'a sınırlı olması durumunda aşağıdaki komut yukarıdaki ile aynı işlevi görecektir.
$ jar cf ArşivDosyası.jar *.class images
Arşivin oluşturulması sırasında, girdi dosyalarının dizin yapısı korunur. Örneğin, yukarıdaki komutların icra edilmesi sonrasında a.class ve b.class arşivin kök dizininde yer alırken, görüntü dosyaları images altdizini içine konulmuş olacaktır. Bu davranışın değiştirilerek görüntü dosyalarının da sınıf dosyaları ile aynı dizine konulması istenecek olursa, -C opsiyonunun kullanılması gerekecektir. Bu opsiyon, geçici olarak kendisinden sonra sağlanan altdizine geçer ve dosya adını arşivleme sanki geçici altdizinde yapılıyormuş gibi arşive ekler. Buna göre, aşağıdaki komut o anki çalışma dizininde bulunan sınıf dosyaları ile images altdizinindeki tüm dosyaları arşivin kök dizinine yerleştirir.
$ jar cf ArşivDosyası.jar *.class -C images *
Kimi zaman, sıfırdan oluşturmak yerine ufak bir ekleme veya değişiklik yaparak var olan bir arşivi güncellemek isteyebiliriz. Oluşturmaya göre daha ucuz olan bu işlem u opsiyonu ile gerçekleştirilebilir. Arşiv oluşturma ile aynı argümanlara sahip bu işlem, kendisine geçirilen dosyanın arşivde var olması durumunda yeni dosyayı arşivdekinin üzerine yazar. Buna göre, aşağıdaki örnek kullanım ArşivDosyası.jar dosyasına c.class dosyasını eklerken, arşivde hali hazırda var olan a.class dosyasını yeni haliyle güncelleyecektir.
$ # Arşiv güncelleme
$ jar uf ArşivDosyası.jar a.class c.class
Daha önceden oluşturulmuş bir arşivin içeriği t opsiyonu ile listelenebilir. Standart çıktıya basılan listede arşivdeki dosya ve altdizinlerin kök dizine göre adları yer alır. Altdizinlerin / ile sonlandırıldığı bu listelemenin daha ayrıntılı yapılabilmesi için v opsiyonu kullanılabilir.
$ #Arşiv içeriği listeleme
$ jar tf bsh-2.0b4.jar
META-INF/
META-INF/MANIFEST.MF
bsh/
bsh/BSHAllocationExpressin.class
bsh/BSHAmbiguousName.class
...
Bir arşivin açılması arşivciye x opsiyonunun sağlanmasıyla mümkün olur. Arşiv içindeki dosya sıradüzenini disk üzerinde aynen oluşturan bu işlemin hali hazırda var olan dosyaların üzerine yazacağı unutulmamalıdır.
$ # Arşiv açma
$ jar xf bsh-2.0b4.jar

Arşiv Manifestosu


İçerik listeleme örneği farklı arşivler için denenecek olursa, META-INF dizini içindeki MANIFEST.MF dosyasının her zaman çıktıda yer aldığı görülecektir. Sakın, bunun arşiv yaratıcılarının sizi paranoyaya sürüklemek amacıyla sözleşerek uyguladığı bir komplo olduğunu düşünmeyin; nasıl ki, gemiler taşıdıkları kargonun ayrıntısını içeren bir manifesto bulundururlar, arşiv dosyaları da söz konusu arşivin sahip olduğu özellikleri belirtmek amacıyla META_INF/MANIFEST.mf dosyası içinde bir manifesto bulundurur.

Aksine bir yönlendirmede bulunmadığınız takdirde, arşiv oluşturma sırasında sizin için minimal içerikli bir manifesto oluşturulur.3 Manifest-Version: 1.0 satırından oluşan bu manifestoyu arşiv oluşturma veya güncelleme sırasında sağlanacak m opsiyonu ile isteğinize göre değiştirebilirsiniz. Yapılacak değişikliklerin üzerine yazma yerine kaynaştırarak işini gördüğü akıldan çıkarılmamalıdır. Ne demek istediğimizi bir örnekle görelim. Varsayalım ki, ArşivDosyası.jar işini görebilmek için YardımcıArşiv1.jar ve YardımcıArşiv2.jar arşivlerine ihtiyaç duyuyor. Bu durum, anılan bağımlılık bilgisini içeren bir dışsal manifesto dosyasının MANIFEST.MF'ye yamanması ile karşılanabilir.

EkManifesto.mf
Class-Path: YardımcıArşiv1.jar YardımcıArşiv2.jar
jar umf EkManifesto.mf ArşivDosyası.jar

EkManifesto.mf dosyasının MANIFEST.MF'ye yamandığı yukarıdaki satırın işlenmesi sonrasında MANIFEST.MF dosyası şu içeriğe sahip olacaktır.

MANIFEST.MF
Manifest-Version: 1.0
Class-Path: YardımcıArşiv1.jar YardımcıArşiv2.jar

İndeksleme


Dosya ve altdizin sayısının artmasıyla birlikte arşivdeki bir dosyanın bulunup kullanılması daha uzun bir zaman alacaktır. Böyle bir durumda, i opsiyonunun var olan bir arşiv ile birlikte arşivciye geçirilmesi aramayı hızlandıran bir indeks dosyası yaratarak maliyeti azaltabilir.
$ # Arşiv indeksleme
$ jar i ArşivDosyası.jar
META-INF altdizini içindeki INDEX.LIST dosyasına yazılan indeksleme bilgisinin, arşivin her güncellenmesi sonrasında yeniden yaratılması gerektiği unutulmamalıdır. Ayrıca, indekslemenin diğer işlemlerden ayrı yapılmasının zorunlu olduğu da akıldan çıkarılmamalıdır.

Arşiv Kullanımı


Edindiğiniz arşiv dosyalarından değişik şekillerde yararlanabilirsiniz. Öncelikle, arşiv dosyaları sınıf yolu üzerindeki bir dizine açılmak suretiyle kullanılır hale getirilebilir. Daha zahmetsiz bir diğer yöntem, arşiv dosyasını CLASSPATH ortam değişkenine eklemekten geçer. Örnek olarak, ArşivDosyası.jar'ı kullanan Prog.java adındaki bir dosyanın nasıl derleneceğine bakalım.
javac -cp ".:/home/tevfik/Java Paketleri/ArşivDosyası.jar:$CLASSPATH" Prog.java
Yukarıdaki komuta göre, Prog.java dosyasında ihtiyaç duyulan sınıf dosyaları öncelikle o anki çalışma dizininde, sonra /home/tevfik/Java Paketleri dizininde bulunan ArşivDosyası.jar arşivinde ve nihayet CLASSPATH ortam değişkenince işaret edilen yerlerde aranacaktır. Bu noktada, CLASSPATH ortam değişkeninin içerdiği arşiv dosyası atıflarının mutlak konum verilerek yapılması gerekirken, komut satırında yapılacak uygulamaya özel eklemelerin göreceli olarak da verilebileceği akılda tutulmalıdır.

Arşiv dosyaları, edimli kütüklere benzer şekilde bir komut gibi de kullanılabilir. Bunun için, öncelikle arşiv manifestosuna giriş noktasını içeren çalıştırılabilir sınıfın hangisi olduğunu gösteren Main-Class anahtarı ve ilişkin değerin eklenmesi gerekir. Yukarıda gösterdiğimiz şekilde manifestoya yapılacak bir değişiklikle sağlanabilecek bu bilgi, arşivciye e opsiyonu ile de bildirilebilir.
$ # Arşiv giriş noktası
$ jar cfe ArşivDosyası.jar AnaSınıf.class
Yukarıdaki komutun işlenmesi sonrasında, arşivci tarafından oluşturulacak minimal manifesto Main-Class: AnaSınıf.class satırını da içerecektir.

Giriş noktası bilgisine sahip bir arşivin çalıştırılması oldukça basittir; yapılması gereken, JSM'ye -jar opsiyonunun geçirilmesinden ibarettir. Böylesine bir kullanım, JSM'ye argümanda sağlanan dosyanın bir arşiv olduğu ve çalışmanın çalıştırılabilir sınıf adının manifestodaki Main-Class'a dair değerden öğrenilip bulunması sonrasında başlayacağı anlamına gelir.
$ # Arşiv çalıştırma
$ java -jar ArşivDosyası.jar


  1. Pek fazla kullanılmasa da, arşivciye sağlanan 0 opsiyonu arşivin sıkıştırma yapılmaksızın oluşturulacağı anlamına gelir.
  2. Unix temelli işletim dizgelerinden alışmış olanlara uyarı: opsiyon öncesinde - yok.
  3. İstenecek olursa, M opsiyonu ile minimal manifestonun oluşturulmasının önüne geçilebilir.