Living life and Make it Better

life, learn, contribute

Endy Muhardin

Software Developer berdomisili di Jabodetabek, berkutat di lingkungan open source, terutama Java dan Linux.

Migrasi Linux

Di kantor saya sekarang sedang terjadi euforia Linux. Hmm…. bukan euforia. Tampaknya histeria lebih tepat. Karena semua orang tampak histeris dan ingin sampai di kantor besok harinya dan menemukan semua Windows sudah tidak ada, dan semua orang bekerja normal dan gembira.

Ini semua dipicu oleh razia software bajakan yang marak terjadi beberapa bulan ini. Beberapa perusahaan bahkan menerima surat dari Pak Sutanto yang gambar sampulnya saja sudah menakutkan. Bukannya kantor saya pakai bajakan, tapi dengan sekian ratus orang karyawan, masing-masingnya menggunakan paling tidak satu komputer, siapa yang tau kalau mereka instal ulang komputernya dengan aplikasi GPL (Glodok Public License) ??

Jadilah akhirnya job desc saya bertambah satu, konsultan migrasi Linux, karena kebetulan di komputer dan notebook saya sudah tidak ada Windowsnya lagi. Berikut beberapa pengalaman yang bisa dibagi berkaitan dengan histeria migrasi ini. Siapa tau berikutnya kantor Anda yang dilanda demam pinguin.

Siapkan Install Server

Satu kali diminta instal, no problem. Dua kali, yah mau gimana lagi. Tiga kali?? That’s enough. Ubuntu memang mudah diinstal, tapi distro lain seperti OpenSuSE tidak senyaman Ubuntu. Untuk OpenSuSE, kita harus menunggui proses instalasi, dan mengganti CD pada waktunya.

Bila Anda mengantisipasi akan menginstal lebih dari tiga komputer, segera deploy fitur instalasi melalui jaringan. Ini adalah investasi beberapa jam yang akan menyelamatkan beberapa puluh jam dari masa remaja Anda di kemudian hari.

Semua distro Linux mendukung instalasi melalui jaringan, walaupun caranya berbeda-beda. Saya menyiapkan repository di jaringan lokal untuk beberapa distro utama, untuk kasus saya, Ubuntu dan OpenSuSE.

Repository Ubuntu dapat dibuat dengan mudah menggunakan DVD Repository yang bisa didonlod di kandang anak kambing. Segera setelah DVD repository selesai didownload, aktifkan webserver Apache dan mount ISOnya ke folder yang dapat diakses orang banyak. Cara yang sama bisa dilakukan untuk distro OpenSuSE.

Sebagai contoh, semua ISO tersebut saya mount ke folder /home/endy/tmp/UbuntuRepo dan /home/endy/tmp/OpenSuSE. Kemudian kedua folder tersebut saya publish melalui Apache. Berikut adalah konfigurasi /etc/fstab agar ISO tersebut dimount pada saat booting.

# Ubuntu Repository DVDs
/media/sdb2/ISO/Ubuntu/UbuntuDVD/ubuntu-7.04-repository-i386-1_contrib.iso  /home/endy/tmp/UbuntuRepo/DVD1 iso9660 loop,auto 0 0 
/media/sdb2/ISO/Ubuntu/UbuntuDVD/ubuntu-7.04-repository-i386-2_contrib.iso  /home/endy/tmp/UbuntuRepo/DVD2 iso9660 loop,auto 0 0 
/media/sdb2/ISO/Ubuntu/UbuntuDVD/ubuntu-7.04-repository-i386-3_contrib.iso  /home/endy/tmp/UbuntuRepo/DVD3 iso9660 loop,auto 0 0 
/media/sdb2/ISO/Ubuntu/UbuntuDVD/ubuntu-7.04-repository-i386-4_contrib.iso  /home/endy/tmp/UbuntuRepo/DVD4 iso9660 loop,auto 0 0 

# OpenSuSE CD
/media/sdb2/ISO/openSUSE-10.2-GM-i386-CD1.iso  /home/endy/tmp/OpenSuSE/CD1 iso9660 loop,auto 0 0 
/media/sdb2/ISO/openSUSE-10.2-GM-i386-CD2.iso  /home/endy/tmp/OpenSuSE/CD2 iso9660 loop,auto 0 0 
/media/sdb2/ISO/openSUSE-10.2-GM-i386-CD3.iso  /home/endy/tmp/OpenSuSE/CD3 iso9660 loop,auto 0 0 
/media/sdb2/ISO/openSUSE-10.2-GM-i386-CD4.iso  /home/endy/tmp/OpenSuSE/CD4 iso9660 loop,auto 0 0 
/media/sdb2/ISO/openSUSE-10.2-GM-i386-CD5.iso  /home/endy/tmp/OpenSuSE/CD5 iso9660 loop,auto 0 0 

Semakin banyak ISO yang dimount, semakin banyak juga loop device yang dibutuhkan. Instalasi Ubuntu standar cuma menyediakan 8 device loop, sehingga tidak cukup untuk memuat 4 ISO Ubuntu dan 5 ISO OpenSuSE. Untuk memeriksa berapa device loop yang tersedia, lihat di dalam /dev/

Untuk itu, device loop perlu ditambahkan. Di Ubuntu, tambahkan baris berikut di file /etc/modprobe.d/options

options loop max_loop=32 

agar pada saat booting kernel menyediakan 32 device loop.

Selanjutnya, kita lakukan mapping agar folder /home/endy/tmp tersebut dipublish di http server. Cara termudah adalah dengan membuat symlink ke folder DocumentRoot (untuk keluarga Debian adalah /var/www).

ln -s /var/www/UbuntuRepo /home/endy/tmp/UbuntuRepo
ln -s /var/www/OpenSuSE /home/endy/tmp/OpenSuSE

Berikutnya, buat boot CD atau boot USB agar pada saat instalasi kita cukup mengarahkan ke jaringan. Saya biasanya memulai instalasi pada sore hari agar bisa ditinggal pulang.

Migrasi Email

Arsip email merupakan harta yang sangat penting di kehidupan perkantoran modern. Dia bisa digunakan sebagai amunisi audit, bahan berkelit, ataupun mencari referensi. Oleh karena itu, setelah migrasi biasanya user akan menanyakan, “Email lama saya mana??”.

Email dari Outlook Express bukanlah masalah besar. Hampir semua mail client Linux seperti KMail, Thunderbird, dan Evolution sudah menyediakan fitur import. Yang paling bermasalah adalah Outlook 2003. Native import belum ada di semua mail client Linux pada saat tulisan ini dibuat. Jadi, kita harus lebih dalam menggali isi perut Google.

Saya menemukan tiga metode yang bisa digunakan:

  1. Menggunakan Thunderbird

  2. Menggunakan File Sharing

  3. Menggunakan IMAP Server

Cara mana yang dipilih tergantung dari ketersediaan ahli Linux di sekitar Anda. Kalau tidak ada ahli Linux sama sekali, gunakan cara pertama. Berikut adalah langkah-langkahnya.

Kebutuhan Software

  • MS Windows. Ya Anda membutuhkan komputer yang masih ada Windowsnya

  • Mozilla Thunderbird untuk Windows

  • Linux. Kalau Anda sudah menjadi korban migrasi, harusnya komputer Anda sudah terinstal Linux pada saat ini.

  • Mozilla Thunderbird untuk Linux

Cara migrasi

Cara memindahkan email sangat mudah. Pembaca yang teliti tentunya sudah bisa menebak langkah-langkahnya hanya dengan melihat kebutuhan software di atas.

  1. Buka Thunderbird di Windows

  2. Import file *.pst Anda

  3. Buka setting Thunderbird, cari tahu di mana dia menyimpan emailnya

  4. Copy folder tersebut ke komputer Linux Anda

  5. Jalankan Thunderbird Linux, arahkan folder penyimpanan email ke folder hasil copy

  6. Restart Thunderbird

  7. Setelah ini, Anda bisa import hasilnya ke Evolution atau KMail, sesuai dengan pilihan

Cara kedua melibatkan pembuatan folder sharing di suatu tempat. Pada dasarnya cara ini adalah otomasi dari cara pertama di atas, sehingga bisa digunakan untuk memigrasi banyak user sekaligus. Saya kurang merekomendasikan cara ini karena relatif sulit dan tidak intuitif. Bagi yang ingin tahu bisa langsung lihat di websitenya.

Buat saya, instalasi Thunderbird berkali-kali kurang menyenangkan. Lagipula, terkesan kurang hi-tech. Berikut adalah cara ketiga. Untuk melakukan ini, Anda butuh ahli Linux yang mampu mengkonfigurasi email server berprotokol IMAP. Sebenarnya IMAP server ini bisa di mana saja, termasuk di Windows. Yang penting IMAP. Cara setting IMAP server tidak dibahas pada artikel ini.

Berikut adalah langkah-langkah migrasi.

  1. Sebelum komputer Windows diformat, jalankan dulu Outlook 2003 untuk terakhir kalinya

  2. Buat akun email baru di Outlook, menggunakan akun yang sudah dibuatkan di IMAP server

  3. Copy email dari Local Folder Outlook ke folder IMAP

  4. Silahkan format Windowsnya dan install Linux

  5. Setelah berada di Linux, jalankan mail client apapun yang Anda sukai

  6. Buat akun email menggunakan akun di IMAP server

  7. Email Anda akan hadir tanpa suatu cacat apapun. Silahkan pindahkan ke folder lokal

Saya sangat menyukai cara ketiga ini. Bisa memigrasi email orang banyak dengan singkat, dan user bisa diajari untuk melakukannya sendiri.

Demikianlah beberapa tips singkat tentang migrasi Linux. Semoga bermanfaat.


vnStat

Sekarang sedang marak layanan internet berbasis paket. Artinya, kita dikenakan biaya berdasarkan besar data yang kita konsumsi, baik kirim (uplink) maupun terima (downlink).

Perbedaan cara penagihan tentunya juga mempengaruhi perilaku berinternet kita. Dengan layanan berbasis waktu, kita dapat membatasi pengeluaran dengan cara membatasi durasi berinternet. Nah, kalau berbasis paket, bagaimana cara mengendalikan pemakaian?

Berbagai aplikasi open source dapat digunakan untuk memonitor pemakaian internet, salah satunya adalah vnStat. Aplikasi kecil ini sangat mudah digunakan. Cukup instal, inisialisasi databasenya, dan lihat laporannya.

Instalasi vnStat

Instalasi, seperti biasa, sangat mudah. Di Ubuntu, cukup dengan satu baris. sudo apt-get install vnstat

Setelah terinstal, kita harus menginisialisasi database tempat data monitoring diletakkan. Di komputer saya, ada dua antarmuka jaringan, WiFi (eth1) dan kabel (eth2). Nantinya bila menggunakan modem ADSL, biasanya saya akan menggunakan antarmuka kabel (eth2) yang terhubung ke modem ADSL.

Untuk menginisialisasi database, lakukan perintah berikut, sesuai dengan nama antarmuka yang akan dimonitor.

<code>sudo vnstat -u -i eth1
sudo vnstat -u -i eth2</code>

vnStat akan mengeluarkan pesan error tentang file database yang tidak ditemukan. Biarkan saja, karena filenya belum ada.

Setelah itu, vnStat sudah bekerja di belakang layar. Untuk melihat pemakaian internet, kita harus menginstal satu aplikasi lagi, yaitu vnStat Front End. Aplikasi ini kerjanya membaca database yang dihasilkan vnStat dan menampilkannya di web. Karena berbasis PHP, seharusnya tidak sulit untuk diinstal.

Instalasi vnStat FrontEnd

Instalasinya tidak sulit. Cukup download dari websitenya, dan extract di folder yang dikenali oleh Apache HTTPD. Di komputer saya, saya gunakan folder /opt/lampp/htdocs/vnstat.

Edit file config.php sehingga menjadi seperti ini.

<code>
// list of network interfaces monitored by vnStat
$iface_list = array('eth1', 'eth2');
$iface_title['eth1'] = 'Wireless';
$iface_title['eth2'] = 'Wired';
</code>

Selanjutnya, browse ke http://localhost/vnstat. Kita akan mendapati data penggunaan jaringan kita seperti gambar di bawah. vnStat Front End Screenshot

Selamat mencoba


Lowongan Programmer

Di tempat saya bekerja saat ini (BaliCamp), saya sedang membutuhkan anggota tim. Tidak butuh yang terlalu canggih, saya justru cari fresh graduate. Nantinya kandidat yang lolos akan ditempatkan di tim saya, mengembangkan aplikasi untuk mengelola software development process.

Ada banyak nilai tambah yang bisa diperoleh dari pekerjaan ini, selain tentunya gaji dan fasilitas standar seperti layaknya karyawan lainnya. Biar saya jelaskan sedikit.

Pertama, yang akan kita buat di sini adalah aplikasi manajemen proyek yang spesifik untuk software development. Artinya, kita nanti akan melihat secara langsung bagaimana proyek software dikelola dengan mengikuti kaidah CMMI. Pengetahuan yang selama ini hanya dipelajari (sambil ngantuk) di kelas tentang RUP, XP, Waterfall, dsb akan dilihat langsung implementasinya di lapangan. Dan dibuatkan softwarenya. Jadi, dengan membuat aplikasi ini, kita jadi memahami bagaimana best-practices dalam pengelolaan proyek.

Kedua, kita akan bekerja dengan menggunakan Spring Framework dan Hibernate. Ini adalah dua framework utama dalam dunia Java. Anggota tim (yang nota bene adalah fresh graduate) akan mengikuti training tentang kedua teknologi ini. Saya sendiri yang akan memberikan trainingnya.

Ketiga, dalam proses pembuatan aplikasi ini, kita akan menggunakan teknologi tercanggih yang tersedia di dunia open source. Kita akan menyimpan source-code dan dokumentasi proyek dalam Subversion. Semua best-practices yang saya tulis di buku Subversion akan diimplementasikan dalam proyek. Issue atau bug akan dikelola dengan bug tracker. Testing akan dilakukan di segala lini, sesuai dengan artikel yang pernah saya tulis di sini, sini, sini, dan sini. Secara harian, CruiseControl akan mengambil semua source code terbaru dan melakukan daily build. Singkatnya, semua persenjataan proyek akan kita gunakan secara optimal.

Jangan khawatir kalau merasa asing dengan berbagai teknologi tersebut. Akan ada sesi training khusus untuk itu. Lagi-lagi saya yang akan memberikan trainingnya.

Baiklah, sekarang apa persyaratannya?

Pelanggan blog ini tentunya sudah tahu kalau saya sangat pemilih dalam menentukan anggota tim. Jadi, persiapkan diri dengan baik.

Tidak seperti lowongan lainnya yang biasa Anda lihat di milis atau portal tenaga kerja, saya tidak mempermasalahkan latar belakang pendidikan. SMU ke atas boleh daftar. IPK Anda Tiarap?? Jangan khawatir, silahkan layangkan lamaran Anda. Tidak akan didiskriminasi.

Persyaratan yang wajib dimiliki oleh peminat adalah:

  1. Konsep dasar OOP

  2. Dasar-dasar Java

  3. Pernah menggunakan minimal 2 (dua) bahasa pemrograman

  4. Konsep struktur data, misalnya tree, list

  5. Konsep relasional termasuk join dan subquery

  6. Mengerti SQL untuk minimal satu produk database

  7. HTML dan CSS

  8. Dasar-dasar jaringan komputer

  9. Bahasa Inggris (minimal membaca)

  10. Pernah membuat minimal satu aplikasi utuh (dari tampilan depan sampai ke database, lengkap dengan validasi) dengan minimal 4 (empat) tabel yang berelasi.

Seperti layaknya lowongan pekerjaan yang lain, ada beberapa hal yang masuk kategori lebih diutamakan bila menguasai atau dalam istilah programmer, nice to have. Berikut daftarnya:

  • Bisa menulis Ant buildfile

  • Memiliki personal website (blog)

  • Sehari-hari menggunakan Linux

Lokasi kerja saat ini di Menara Dea, Kawasan Mega Kuningan, 10 menit berjalan kaki dari Mal Ambassador. Ada sedikit kemungkinan tim akan pindah ke Desa Sigma di German Centre, Bumi Serpong Damai.

Berminat?? Silahkan klik Compose New Mail di aplikasi email Anda, dan attach resume dalam format PDF. Kemudian kirimkan ke endy [at] artivisi [dot] com atau emuhardin [at] balicamp [dot] com.

Bila resume Anda meyakinkan, saya akan panggil untuk interview. Siapkan aplikasi yang pernah dibuat dalam CD, paket sedemikian rupa sehingga mudah diinstal. Sertakan semua file yang dibutuhkan. Nantinya saya akan sediakan PC kosong yang hanya berisi sistem operasi agar Anda bisa mendemokan aplikasi tersebut.

Kalau ada pertanyaan, silahkan langsung posting komentar di bawah tulisan ini.


Remoting dengan Spring

Aplikasi yang kita buat, tidak hanya digunakan oleh manusia. Ada kalanya aplikasi yang kita buat akan diakses oleh aplikasi orang lain. Jadi, user atau pengguna aplikasi kita bukanlah orang, melainkan mesin. Dalam hal ini, aplikasi kita dapat disebut dengan aplikasi server yang menyediakan service bagi aplikasi client.

Bagaimana caranya agar aplikasi kita dapat digunakan oleh aplikasi lain? Caranya tentunya dengan menyediakan antarmuka yang sesuai bagi masing-masing aplikasi client. Ada banyak bahasa yang dijadikan patokan dalam komunikasi antar aplikasi. Beberapa protokol yang umum digunakan adalah:

  • CORBA

  • RMI (khusus Java)

  • SOAP

  • XML-RPC

  • Hessian

  • Burlap

  • dan masih banyak yang lainnya

Dengan cara tradisional, menyediakan antarmuka untuk masing-masing protokol ini cukup rumit. Selain harus mengerti protokolnya, kita juga harus menulis banyak kode untuk memformat data kita mengikuti aturan yang ditetapkan protokol tersebut. Kita juga harus menulis kode program agar dapat menerima data dalam protokol yang kita ingin sediakan.

Spring Framework menyediakan library pembantu bagi kita agar kita dapat menyediakan akses dalam protokol tersebut dengan mudah. Bagaimana caranya, mari kita bahas dalam artikel ini.

Sebagai contoh sederhana, misalnya kita ingin menyediakan layanan untuk mengambil data Person. Untuk menyederhakan masalah, Person hanya mengandung data nama dan email saja.

Person.java

package tutorial.remoting;

public class Person implements java.io.Serializable {
    private String name;
    private String email;
    
    public Person() {
        this("", "");
    }
    
    public Person(String name, String email){
        this.name = name;
        this.email = email;
    }
    
    public String getName(){
        return name;
    }
    
    public String getEmail(){
        return email;
    }
    
    public String toString(){
        return name + " : " + email;
    }
}

Perhatikan bahwa kita harus mendefinisikan Person sebagai object yang Serializable. Ini penting agar object ini bisa ditransfer melalui jaringan.

Kemudian, kita sediakan interface yang mendefinisikan layanan yang ingin kita sediakan bagi aplikasi lain. Kita sebut saja interface ini sebagai PersonService.

PersonService.java

package tutorial.remoting;

import java.util.List;
 
public interface PersonService {    
    public Person get(int id);
    public List getAllPerson();
} 

PersonService ini nantinya bisa kita implementasi sesuai dengan kebutuhan. Kita bisa mengambil datanya dari database, dari phonebook handphone, atau bahkan dari aplikasi lain. Agar contoh kodenya lebih sederhana, kita buat saja implementasinya dengan ArrayList. Para pembaca nanti bisa mencoba dengan implementasi lain yang lebih hi-tech seperti Hibernate atau OpenJPA.

Berikut adalah implementasi dari PersonService, kita sebut saja PersonServiceImpl.

PersonServiceImpl.java

package tutorial.remoting.remote;

import java.util.List;
import java.util.ArrayList;

import tutorial.remoting.Person;
import tutorial.remoting.PersonService;

public class PersonServiceImpl implements PersonService {

    private List allPerson = new ArrayList();
    
    public PersonServiceImpl(){
        Person p = new Person("Endy Muhardin", "endy@artivisi.com");
        Person p1 = new Person("Maya Mujawati", "moedja@yahoo.com");
        allPerson.add(p);
        allPerson.add(p1);
    }
    
    public Person get(int id){
        if (id >= allPerson.size()) return null;
        return (Person) allPerson.get(id);
    }

    public List getAllPerson(){
        return allPerson;
    }
} 

Seperti kita lihat di atas, tidak ada yang istimewa dengan kode program di atas. Bahkan validasi untuk field id pun tidak kita sediakan. Tentu saja kalau kita berikan masukan angka 2 atau lebih pada method public Person get(int id) akan terjadi ArrayIndexOutOfBoundException.

Selesai sudah … sekarang kode tersebut dapat diakses oleh aplikasi lain.

Apa?? Saya mendengar ada suara-suara kurang puas dari penonton.. Coba lebih keras??

Bagaimana cara mengaksesnya dari aplikasi client? Nampaknya belum ada kode program apa-apa untuk menyediakan layanan webservice. Mana bisa dibilang selesai?

Ok .. baiklah, memang ada satu langkah lagi. Yaitu mempublikasikan interface tersebut agar bisa diakses orang banyak. Kita akan sediakan akses melalui tiga protokol, yaitu:

  1. RMI

  2. Hessian

  3. Burlap

Tiga protokol?? Apa tidak terlalu ambisius? Nanti saya pusing baca kode sekian banyak.

Demikian terdengar komentar dari penonton. Hmm … penonton Indonesia memang terlalu banyak protes.

Tenang saja. Kita akan gunakan Spring untuk mempublikasikan aplikasi kecil kita ini. Saya akan buktikan bahwa kodenya sedikit dan mudah dipahami. Sekarang, mari kita mulai dengan mempublikasikan protokol RMI. Di masa lalu, untuk menyediakan layanan ini, paling tidak kita harus:

  1. mengkompilasi stub

  2. mengkompilasi skeleton

  3. mengkonfigurasi Security setting

  4. menjalankan RMIRegistry

  5. mendaftarkan objek PersonServiceImpl ke RMIRegistry

  6. memberikan stub ke aplikasi client

Sekarang tidak lagi. Kita cukup mendaftarkan interface PersonService, implementasi PersonServiceImpl di konfigurasi Spring. Berikut adalah isi file remote-ctx.xml

remote-ctx.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
    <bean id="personServiceTarget" class="tutorial.remoting.remote.PersonServiceImpl"/>
    
    <bean class="org.springframework.remoting.rmi.RmiServiceExporter">        
        <property name="serviceName" value="PersonRmiService"/>
        <property name="service" ref="personServiceTarget"/>
        <property name="serviceInterface" value="tutorial.remoting.PersonService"/>  
        <property name="registryPort" value="4321"/>
    </bean>
</beans>

Hanya dengan membaca file XML di atas, kita sudah bisa menduga apa yang terjadi. Kita mempublikasikan layanan yang didefinisikan pada interface PersonService pada port 4321 dengan nama layanan PersonRmiService. Di sisi server, layanan ini akan disediakan oleh objek personServiceTarget yang merupakan instan dari class PersonServiceImpl. Kita memanfaatkan class RmiServiceExporter yang dimiliki Spring.

Untuk menjalankan aplikasi kecil kita, buat sebuah class sederhana untuk mengaktifkan Spring Framework. Berikut adalah kode programnya.

PersonRmiService.java

package tutorial.remoting.server;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class PersonRmiService {
    public static void main(String[] xx) {
        ApplicationContext ctx = 
        new FileSystemXmlApplicationContext("webapp/WEB-INF/remote-ctx.xml");
    }
}

Silahkan jalankan class di atas. Asal classpath sudah disetting dengan benar, kita siap mengaksesnya dari client. Kita juga akan menggunakan bantuan dari Spring Framework untuk menemukan dan menginisialisasi layanan RMI yang berada di port 4321. Berikut adalah konfigurasi Spring di sisi client.

client-ctx.xml

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>    
    <bean id="personServiceRmi" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
        <property name="serviceUrl" value="rmi://localhost:4321/PersonRmiService"/>
        <property name="serviceInterface" value="tutorial.remoting.PersonService"/>
    </bean>
</beans>

Berikut adalah kode program untuk mengakses RMI service kita.

Main.java

package tutorial.remoting.client;

import java.util.List;

import tutorial.remoting.PersonService;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class Main {
    public static void main(String[] args){
        // initialize application context
        ApplicationContext ctx = new FileSystemXmlApplicationContext("client-ctx.xml");
    
        // accessing RMI service
        System.out.println("======= Accessing RMI Service ==========");
        PersonService ps1 = (PersonService) ctx.getBean("personServiceRmi");
        List all1 = ps1.getAllPerson();
        for(int i=0; i<all1.size(); i++) {
            System.out.println(all1.get(i));
        }
}

Perhatikan konsol, dan saksikan RMI service kita sudah dieksekusi dengan sukses.

Sekarang, kita publikasikan melalui protokol Hessian dan Burlap. Protokol ini adalah hasil karya Caucho untuk mempublikasikan service di atas protokol HTTP. Hessian menggunakan format binary, sedangkan Burlap menggunakan format XML.

Karena berbasis HTTP, maka kita perlu menggunakan HTTP Server yang mendukung Java (khususnya Servlet). Kita bisa gunakan Tomcat atau Jetty. Yang jelas, kita perlu mendeklarasikan servlet untuk melayani client. Deklarasi dibuat di dalam file web.xml sebagai berikut.

web.xml

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app PUBLIC
	"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
	"http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>

	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			/WEB-INF/remote-ctx.xml
		</param-value>
	</context-param>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<servlet>
		<servlet-name>remoting</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<load-on-startup>2</load-on-startup>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>remoting</servlet-name>
		<url-pattern>/remoting/*</url-pattern>
	</servlet-mapping>

	<session-config>
		<session-timeout>10</session-timeout>
	</session-config>


</web-app>

Kita membutuhkan satu file konfigurasi untuk mengkonfigurasi layanan Hessian dan Burlap. Berikut adalah isi file remoting-servlet.xml.

remoting-servlet.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
    <bean name="/PersonHessianService" class="org.springframework.remoting.caucho.HessianServiceExporter">
        <property name="service" ref="personServiceTarget"/>
        <property name="serviceInterface" value="tutorial.remoting.PersonService"/>          
    </bean>
    
    
    <bean name="/PersonBurlapService" class="org.springframework.remoting.caucho.BurlapServiceExporter">
        <property name="service" ref="personServiceTarget"/>
        <property name="serviceInterface" value="tutorial.remoting.PersonService"/>          
    </bean>
    
    <bean name="/PersonHttpInvokerService" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
        <property name="service" ref="personServiceTarget"/>
        <property name="serviceInterface" value="tutorial.remoting.PersonService"/>          
    </bean>
    
    
</beans>

Letakkan file remoting-servlet.xml ini di sebelah web.xml. Kita juga perlu mengikutkan file remote-ctx.xml yang kita buat untuk RMI di atas, karena deklarasi objek PersonServiceImpl ada di sana. Bila kita tidak ingin mengikutkan file ini, kita bisa memindahkan deklarasi objek tersebut ke dalam file remoting-servlet.xml.

Sekarang kita bisa mengkompilasi dan mendeploy aplikasi webnya. Untuk mengaksesnya, ubah sedikit kode program di aplikasi client menjadi sebagai berikut.

Main.java

package tutorial.remoting.client;

import java.util.List;

import tutorial.remoting.PersonService;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class Main {
    public static void main(String[] args){
        // initialize application context
        ApplicationContext ctx = new FileSystemXmlApplicationContext("client-ctx.xml");
    
        // accessing RMI service
        System.out.println("======= Accessing RMI Service ==========");
        PersonService ps1 = (PersonService) ctx.getBean("personServiceRmi");
        List all1 = ps1.getAllPerson();
        for(int i=0; i<all1.size(); i++) {
            System.out.println(all1.get(i));
        }
        
        // accessing Hessian Service
        System.out.println("======= Accessing Hessian Service ==========");
        PersonService ps2 = (PersonService) ctx.getBean("personServiceHessian");
        List all2 = ps2.getAllPerson();
        for(int i=0; i<all2.size(); i++) {
            System.out.println(all2.get(i));
        }
        
        // accessing Burlap Service
        System.out.println("======= Accessing Burlap Service ==========");
        PersonService ps3 = (PersonService) ctx.getBean("personServiceBurlap");
        List all3 = ps3.getAllPerson();
        for(int i=0; i<all3.size(); i++) {
            System.out.println(all3.get(i));
        }
        
        // accessing Http Invoker Service
        System.out.println("======= Accessing Http Invoker Service ==========");
        PersonService ps4 = (PersonService) ctx.getBean("personServiceHttpInvoker");
        List all4 = ps4.getAllPerson();
        for(int i=0; i<all4.size(); i++) {
            System.out.println(all4.get(i));
        }
    }
} 

Demikian juga dengan konfigurasi Spring di sisi client. Kita perlu menambahkan beberapa objek tambahan untuk mengakses layanan di berbagai protokol tersebut. Berikut adalah isi lengkap dari client-ctx.xml.

client-ctx.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>    
    <bean id="personServiceRmi" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
        <property name="serviceUrl" value="rmi://localhost:4321/PersonRmiService"/>
        <property name="serviceInterface" value="tutorial.remoting.PersonService"/>
    </bean>
    
    <bean id="personServiceHessian" class="org.springframework.remoting.caucho.HessianProxyFactoryBean">
        <property name="serviceUrl" value="http://localhost:9090/remoting/PersonHessianService"/>
        <property name="serviceInterface" value="tutorial.remoting.PersonService"/>
    </bean>
    
    <bean id="personServiceBurlap" class="org.springframework.remoting.caucho.BurlapProxyFactoryBean">
        <property name="serviceUrl" value="http://localhost:9090/remoting/PersonBurlapService"/>
        <property name="serviceInterface" value="tutorial.remoting.PersonService"/>
    </bean>
    
    <bean id="personServiceHttpInvoker" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
        <property name="serviceUrl" value="http://localhost:9090/remoting/PersonHttpInvokerService"/>
        <property name="serviceInterface" value="tutorial.remoting.PersonService"/>
    </bean>
</beans>

Aplikasi kecil kita sudah selesai. Setelah mendeploy aplikasi tersebut ke Servlet Container (Tomcat atau Jetty), kita dapat mengaksesnya melalui aplikasi client. Dengan tetap menggunakan remote-ctx.xml tanpa perubahan, selain menyediakan protokol Hessian dan Burlap, protokol RMI akan tetap tersedia.

Bonus

Pembaca yang teliti akan menemukan satu protokol tambahan pada contoh di atas, yaitu HttpInvoker. Ini adalah protokol khusus yang disediakan oleh Spring.

Protokol Hessian dan Burlap tidak mendukung struktur objek secara sempurna. Dia akan mengalami kesulitan apabila objek yang kita kirim tidak sesederhana Person, misalnya memiliki List yang berisi objek lain. Agar bisa mengirim struktur objek yang sempurna, kita harus menggunakan RMI.

Tetapi sayangnya, protokol RMI kurang lazim. Dia membutuhkan port tersendiri yang mungkin saja diblok oleh administrator jaringan, sehingga tidak sefleksibel HTTP.

SpringHttpInvoker menjembatani keterbatasan ini. Kita bisa mengirim objek kompleks secara utuh di atas protokol HTTP dengan menggunakan SpringHttpInvoker.

Demikian … semoga bermanfaat.


Nyambi, bolehkah??

Posting ini saya tulis karena di milis JUG sedang rame membahas tentang boleh tidaknya karyawan nyambi. Sepanjang karir saya, urusan nyambi telah menjadi bagian hidup tak terpisahkan dari perkembangan pribadi saya. Jadi baiklah mari kita bahas sedikit tentang urusan nyambi ini.

Disclaimer : Pernyataan di bawah ini merupakan opini pribadi dan bukan merupakan sikap resmi perusahaan yang saat ini mempekerjakan saya.

Mari pertama kita bedakan antara masalah legal dan masalah etis.

Yang menurut saya tidak legal (haram) :

  • Nyambi di jam kantor (ngerjain project lain2 di kantor)

  • Pakai resource kantor untuk project lain (telp, internet, komputer, dsb), tanpa sepengetahuan atasan

Yang menurut saya legal :

  • Pagi datang ontime, sore tenggo, sampe rumah ngerjain project lain.

Nah, kalo urusan etis, ini rada sulit juga, soalnya urusan kepantasan ini tergantung pendidikan yang diberikan orangtua masing-masing.

Yang menurut saya kurang etis:

  • Berebut pasar dengan kantor. Misal: kantornya terima project dengan kisaran nilai 100-500 juta, eh kita juga terima project dengan nilai 150jt. Lebih tidak etis lagi kalo ikut tendernya saingan.

  • Ngerjain project sampingan sampe begadang, akibatnya pas ngantor ngantuk dan gak konsen.

  • Yang ini dari sisi kantor. Mempekerjakan karyawan lembur sampai nginap, tanpa uang lembur. Padahal kalo si karyawan pulang, dia bisa dapat tambahan uang dari waktu miliknya.

Yang menurut saya etis:

  • Mengerjakan produk/project yang sama, tapi beda segmen. Misalnya kantor terima project Java 100-500 jt. Kalo dibawah itu dia gak terima karena gak nutup biaya. Nah, kita terima project 10 jt, yang kalo dikasi ke kantor pun gak diterima. It’s fine … asal tidak ilegal.

  • Mengkomersilkan sisi lain teknologi, misalnya di kantor coding, di luar ngasi training atau nulis buku.

Sebenarnya kalo kita tanpa ada unsur paranoid, karyawan nyambi ada juga untungnya bagi perusahaan.

Misalnya, di kampus tempat saya ngajar dulu, dosen itu dianjurkan untuk nulis buku, walaupun dikerjakan menggunakan resource kantor (waktu, komputer, internet). Saya tanya kenapa? Teman saya sesama dosen bilang,

kalo ada buku yang ditulis dosen, maka itu bisa meningkatkan image kampusnya.

Demikian juga apabila kita sering nulis blog, aktif di milis, banyak ngarang buku, sering masuk e-lifestyle, dsb. Perusahaan yang berpikiran maju akan dapat melihat manfaat dari ini, misalnya menggunakan resume karyawan tersebut untuk tender, atau diiklankan pada waktu pitching project.

Nah, menurut saya, selain yang legal/ilegal, tidak ada hitam putih di sini. Yang paling penting adalah saling keterbukaan dan kesepakatan.

Saya sendiri selama ini berterus terang pada perusahaan tentang kegiatan komersil lain yang saya lakukan. Bila ada konflik kepentingan ya kita rundingkan. Bila setelah dirundingkan tidak ada titik temu, ya mungkin sudah saatnya berpisah untuk menjalani hidup masing-masing.

Untungnya selama ini saya tidak mengalami masalah dengan keterbukaan ini. Pada perusahaan sebelumnya, bahkan saya bisa nyambi ngajar di kampus di jam kantor, dengan dispensasi khusus.

Jadi, jangan dulu pesimis bahwa nyambi itu haram. Coba saja diskusikan dengan kantor Anda. Siapa tau boleh, dengan kompromi tertentu :D.

Demikian pendapat saya …