Saturday, March 18, 2006

Service provider dalam file JAR

Sejak Java 1.3, suatu file JAR dapat berisi file metadata yang menspesifikasikan service provider class. File tersebut berada di direktori META-INF/services dan disebut sebagai file konfigurasi-profider (provider-configuration file)

Service disini adalah suatu set dari beberapa interface atau beberapa class, dan provider (service provider) adalah implementasi spesifik dari suatu service.

Sebuah provider biasanya sebuah class berfungsi sebagai proxy dari semua operasi yang ada pada sebuah service. Provider haruslah tidak memiliki argumen pada constructor-nya, sehingga dapat diinisialisasi saat pencarian (lookup).

Sebuah provider-configuration file harus memiliki nama sesuai dengan nama (fully-qualified name) dari abstract service class. File tersebut berisi list dari provider-class konkrit yang ada dalam file JAR. Komentar dapat ditambahakan pada file dengan karakter '#'

Sebagai contoh, mari kita membuat sebuah class service pada suatu aplikasi dengan nama com.ejlp.spi.EncryptorProvider yang

memiliki method abstract sebagai berikut:

public abstract Encryptor getEncryptor(String s);


Kita dapat membuat suatu provider dalam file JAR yang terpisah dengan aplikasi dan mengimplementasikan abstract class com.ejlp.spi.EncryptorProvider. Misalnya kita membuat class com.ic.DESEncryptor sebagi provider:

public class DESEncryptor extends com.ejlp.spi.EncryptorProvider {

   public DESEncryptor() {}

   public abstract Encryptor getEncryptor(String s) {
      //...
   }

}


Kemudian pada JAR file kita buat teks file META-INF/services/com.ejlp.spi.EncryptorProvider yang berisi line berikut

#Provider for DES encryptor
com.ic.DESEncryptor


Pada aplikasi yang akan menggunakan provider, kita bisa membuat mekanisme seperti ini:

 static {
     for (Iterator i = Service.providers(EncryptorProvider.class); i.hasNext(); ) {
         EncryptorProvider ep = (EncryptorProvider) i.next();
         registerProvider(ep.class.getName, ep);
     }
 }


 registerProvider(String name, EncryptorProvider ep) {
   //... Add provider to a Map
 }


 Encryptor getEncryptor(String providerName) {
   //... get provider by its name, otherwise get default provider
 }



Links:
JAR File Specification
Bacaan bagus tentang service framework: Introduction to Services Framework

Wednesday, March 15, 2006

JSR 160 (JMX Remoting)

JSR-160 (JMX Remoting)

JMX (JSR-3) mendefinisikan API untuk management aplikasi Java yang bersifat local.
Jika dibutuhkan client yang terkoneksi ke aplikasi Java yang mendukung JMX, maka koneksi dilakukan dengan cara yang tidak standar, biasanaya menggunakan RMI atau HTTP.
JMX remote API merupakan ekstensi dari spesifikasi JMX versi 1.2

Untuk itu dibuatlah JSR-160 yang memperluas JSR-3 yaitu memberikan sebuah standar API untuk koneksi ke suatu aplikasi JMX secara remote.
JMX remoting API terdiri dari package yang harus (mandatory) diimplementasikan dan ada bagian yang tidak mandatory.

Package yang ada pada JSR-160 adalah:

javax.management.remote
javax.management.remote.generic (optional package)
javax.management.remote.jmxmp (optional package)
javax.management.remote.message (digunakan untuk wrapping object yang dikirim dari client ke server)
javax.management.remote.rmi (mandatory package)

*** Connector
Connector (JMX API connector) adalah bagian yang bertanggung jawab untuk mentransmisikan permintaan (request) client ke sebuah remote MBean server.
Connector yang mandatory pada JSR-160 adalah yang berbasis RMI (RMI/JRMP atau RMI/IIOP)
Connector yang tidak mandatory adalah yang berbasis pada:
  • Java serialization (JMX Messaging Protocol/JMXMP) yang disebut Generic JMX API Connector
  • TCP socket protokol lainnya (disebut User-Defined Protocols Connector)
Connector merupakan class yang mengimplementasikan interface javax.management.remote.JMXConnector


*** Connector server
Connector server (JMX API connector server) disisipkan (attach) pada MBean Server (JMX agent) agar connector dapat berinteraksi dengannya.
Direpresentasikan dengan suatu super class: javax.management.remote.JMXConnectorServer
Connector server berasosiasi dengan MBean server dengan cara meregisterkannya pada MBean server atau memberikan MBean server pada constructornya.
Connector server perlu di-start() untuk mulai mendengarkan (listening) koneksi dari client.
Connector server berhenti ketika di-stop() atau akan di-unregister dari MBean Server

*** Pengalamatan
Alamat JMXConnectorServer menggunakan format URL.
URL tersebut digunakan JMXConnector untuk melakukan koneksi ke JMXConnectorServer
Bentuk pengalamannya seperti ini:

service:jmx:://[host[:port]][url-path]

protocol adalah jenis protokol yang digunakan misalnya rmi", "iiop", "jmxmp" atau yang lainnya
Representasi alamat connector adalah class javax.management.remote.JMXServiceURL

*** Contoh

Membuat connector server:

MBeanServer mbs = MBeanServerFactory.createMBeanServer();
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/server");
Map environment = null;

JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, environment, mbs);
cs.start();

Membuat connector client:

JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/server");
Map environment = null;
JMXConnector connector = JMXConnectorFactory.newJMXConnector(url, environment);
connector.connect(connectionEnvironment);

// Obtain a "stub" for the remote MBeanServer
MBeanServerConnection mbsc = connector.getMBeanServerConnection();

// Call the remote MBeanServer
String domain = mbsc.getDefaultDomain()

*** Discovery dan Lookup Service

Digunakan untuk 'mengiklankan' (advertise) dan mencari JMX agent
Infrasuktur untuk discovery dan lookup Service ini bisa menggunakan yang sudah ada seperti:
  • Service Location Protocol (SLP)
  • Java Naming and Directory Interface (JNDI)
  • Jini Network Technology


*** Referensi JMX Remote API
JavaTM Management Extensions (JMX) Remote API Overview
JavaTM Management Extensions (JMX) Remote API Tutorial
API Documentation

Semuanya bisa didownload dari pake reference implementation (RI)

Friday, March 10, 2006

Jawaban yang aneh: Maksudnya me-manage apa?

Perusahaan tempat saya bekerja memang tidak besar, maksimum jumlah pegawai yang pernah ada saja tidak pernah sampai 30 orang. Salah satu perusahaan IBM business partner. Bosnya pun mantan pegawai IBM yang mungkin termauk top level employee.

Dalam proposal-proposal yang dibuat perusahaan seringkali mengedepankan RUP (Rational Unified Process) sebagai metode project management. Entah kenapa, mungkin karena Rational sudah merupakan bagian dari IBM sekarang, atau karena mungkin hanya itu metode yang 'mereka' tahu. Yang jelas, dalam setiap proposal yang perlu menjelaskan deskripsi manajemen proyek yang akan dilakukan pasti gambar yang sangat populer ini selalu muncul.

Tapi lucunya, RUP itu hanya ada dalam proposal. Sebenarnya kita sama sekali tidak melakukan manajemen proyek. Hmm.. mungkin kata ini tidak tepat. Proyek tetap di-manage tapi tidak menggunakan framework atau metode tertentu. Kita disini hanya me-manage proyek dengan cara mmm.. susah mencari kata yang tepat. Ciri-ciri manajemen proyek disini jika saya tulis:
  • Semau gue dan semaunya tim. Tim yang berbeda akan memiliki behaviour yang sangat berbeda.
  • Tidak ada tester atau QA at all (yang menjadi tester akan didefinisikan nanti)
  • Tidak ada best practise. Best practise hanya akan ada dalam masing-masing employee. Artinya pengalaman dalam satu proyek bukan menjadi pengalaman untuk proyek yang lain, karena timnya pun sudah berbeda.
  • Kadang-kadang technology minded. Kata-kata "Kita pakai framework X?" hampir sering muncul diawal proyek.
  • Get things done. Yang penting jalan dulu, urusan lambat atau error akan dipikir belakangan.
  • Disini 1 + 1 akan selalu sama dengan 2. Seharusnya jika tim berkolaborasi 1 + 1 bisa sama dengan 4 atau 5 (Kata-kata bijak dari seseorang).
  • Buat schedule bersama-sama, tentukan mandays bersama-sama, coding sendiri-sendiri, bug fixing sendiri-sendiri, maintenance..?? "Kamu yang maintain ya" artinya "Kamu akan bertemu user/client, tau bagaimana jelek atau kurangnya software yang dibuat, tau masalah-masalah yang timbul di production, kamu harus siap diomelin client dan kamu solve semua itu, kalau ada apa-apa kita bicarakan nanti". Berutunglah orang-orang yang tidak ikut maintenance :)
  • Perlu satu atau dua orang yang akan selalu meng-upgrade skill-nya, learn emerging technologies and new product, melakukan prove of concept (POC), mendesain arsitektur software dan menjalan proyek pada saat awal. Orang ini adalah orang tipe pertama, yang setelah pekerjaan orang ini selesai akan dilempar ke orang-orang tipe kedua.
  • Perlu beberapa orang yang siap dicemplungin ditengah-tengah proyek, fixing other people codes, dan (disuruh) jadi maintainer. Orang ini orang tipe kedua yang sayangnya saya termasuk didalamnya :(
Sebagai penutup, jawaban aneh ini mungkin bisa menggambarkan bagaimana manajemen proyek software disini dilakukan: "Maksudnya me-manage apa?"

Jawaban itu terlontar ketika saya bertanya: "Siapa yang akan me-manage fase 2?" Ketika fase - akan berjalan. (Fase atau phase 2 biasanya adalah fase development setelah software dianggap selesai dan bisa dipakai user, fase ini biasanya dilakukan setelah UAT fase-1, fase-2 mempunyai ciri-ciri: kurang dokumentasi, dianggap bukan bagian penting dan tidak didesain dari awal).

Saya harus kembali bekerja. Mungkin topik berikutnya adalah "Bagaimana RUP bisa digunakan untuk proyek kecil" ini akan menarik jika RUP untuk proyek kecil ini dibadingkan dengan agile project management (agile method).

Wednesday, March 08, 2006

Membuat scheduler atau proses periodik

Kita bisa menggunakan Timer seperti ini:


int initialDelay = 30000; // start after 30 seconds
int period = 5000; // repeat every 5 seconds
Timer timer = new Timer();
TimerTask task = new TimerTask() {
public void run() {
// job code here
}
};
timer.scheduleAtFixedRate(task, initialDelay, period);


Atau menggunakan EDU.oswego.cs.dl.util.concurrent.ClockDaemon seperti ini:


static protected ClockDaemon clockDaemon = new ClockDaemon();

static
{
log.debug("Setting the clockDaemon's thread factory");
clockDaemon.setThreadFactory(new ThreadFactory()
{
public Thread newThread(Runnable r)
{
Thread t = new Thread(getThreadGroup(), r, "ThreadDaemon");
t.setDaemon(true);
return t;
}
});
}

public static ThreadGroup getThreadGroup()
{
if (threadGroup.isDestroyed())
threadGroup = new ThreadGroup("Our Threads");
return threadGroup;
}


public static void main(String[] args)
{
int period = 500; //millis
clockDaemon.executePeriodically(
period,
new Runnable() {
public void run() {
System.out.println("Running...");
}
},
true);

}


Atau menggunakan Quartz, job scheduling system.

Tuesday, March 07, 2006

Alternatif untuk Logging framework

Untuk keperluan logging kita bisa menggunakan bermacam-macam framework seperti

Jakarta Commons Logging (JCL)
Log4J
simple-log, A logging anti-framework


Untuk logging yang sederhana, kita bisa gunakan Simple Logging Facade for Java (SLF4J)
yang dibuat oleh pendiri project Log4J, Ceki Gülcü.

Sesuai namanya SLF4J merupakan facade API yang sederhana, inti dari API-nya adalah service provider interface (SPI). Dengan SLF4J, kita bisa berpindah-pindah dari logging framework satu ke logging framework yang lain hanya dengan mengganti file JAR saja.

SLF4J mirip dengan JCL atau juga LogBridge yang dapat diintegrasikan dengan logging framework lainny. Tapi yang saya suka dari SLF4J adalah caranya mengkonstruksi pesan (message) log, yaitu dengan mengubah tanda {}. Seperti kode contoh dibawah ini:

logger.debug("The new entry is {}. It replaces {}.", object, oldObject);
logger.debug("Value {} was inserted between {} and {}.",
new Object[] {newVal, below, above});

Alternatif framework lain untuk logging bisa dilihat di sini

Followers