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.

Tapestry vs Spring MVC

Dalam beberapa project terakhir, saya menggunakan Spring MVC untuk membuat presentation layer. Spring sangat fleksibel dan mudah dipelajari. Ini menambah fleksibilitas dalam menyusun tim programmer. Dengan kemudahannya, programmer yang sudah pernah membuat aplikasi web –baik menggunakan Struts, PHP, Ruby on Rails, atau bahkan yang cuma mengerti servlet– dapat beradaptasi dalam hitungan hari dan langsung produktif.

Di lain pihak, saya sering sekali mendengar kehebatan Tapestry. Para pendukungnya menggembar-gemborkan peningkatan produktifitas (baca: kecepatan membuat aplikasi) yang signifikan. Harga yang harus dibayar untuk produktifitas tersebut adalah kompleksitas. Tapestry terkenal sulit. Dia menggunakan paradigma event-driven. Jadi kita harus berpikir seolah-olah kita membangun aplikasi desktop dengan Swing atau VB. Kompleksitas ini menyebabkan kita tidak bisa sembarangan menyusun tim programmer. Butuh orang yang pemahaman Java-nya menengah ke atas agar aplikasi dapat diselesaikan dengan baik.

Setelah merasa nyaman menggunakan Spring di beberapa project terakhir, saya putuskan untuk keluar dari zona aman dan belajar Tapestry. Masa depan aplikasi web nampaknya adalah component-mania. Berbagai komponen siap pakai yang tersedia di pasaran (baik gratis maupun bayar) yang tinggal kita tempelkan di aplikasi kita, akan menjadi trend. Terutama dengan maraknya penggunaan Ajax belakangan ini. Pasti akan banyak orang yang membuat komponen Ajax-ready yang bisa langsung digunakan.

Prediksi ini diperkuat dengan presentasi Chuk Mun Lee di Sun Developer Day 2006 kemarin. Dia menunjukkan bagaimana cepatnya orang bisa membuat aplikasi web. Cukup mendownload kumpulan komponen dari jMaki, dan langsung menggambar di IDE. Kalau para pesaing bekerja seperti ini, sementara kita masih secara manual memparsing request, wah … kita akan ketinggalan.

Sebagai titik awal pelajaran, saya akan mulai dari Spring Framework. Ada beberapa kegiatan utama dalam pembangunan aplikasi web yang terjadi berulang-ulang. Dalam membandingkan Spring vs Tapestry, kegiatan-kegiatan ini akan menjadi kriteria penilaian. Dalam setiap kegiatan, saya akan memberi nilai dan menyatakan pemenangnya. Masing-masing kegiatan bobotnya berbeda, tergantung frekuensi kemunculannya dalam aplikasi.

Berikut adalah kriteria penilaiannya :

  1. Hello World. Yaitu kegiatan setup pertama kali sampai Hello World muncul. Bobotnya cuma 5%, karena kegiatan ini cuma dilakukan sekali saja di awal.
  2. Form binding. Bagaimana semua variabel dalam form bisa diambil sebagai satu domain object. Bobotnya 20%, karena ini adalah kegiatan wajib, inti dari aplikasi.
  3. Validasi form. Bagaimana mencegah invalid input, baik secara server-side maupun client-side. Bobotnya 20%, saudara kembar dengan Form Binding.
  4. Web Asset. Bagaimana penanganan image, css, javascript. Bobotnya 10%.
  5. Security. Bagaimana kemudahan mengaktifkan otentikasi dan otorisasi. Bobotnya 20%. Ini juga bagian yang penting. Kalau penanganan di sisi ini tidak elegan, akan banyak duplikasi kode bertebaran di dalam kode program.
  6. Ajax readiness. Bobotnya 10%.
  7. Reusability. Bagaimana kemudahan menggunakan komponen/library yang sudah ada. Bobotnya 10%.

Disclaimer: dalam kegiatan membandingkan ini, tidak ada tujuan untuk menjelekkan yang satu terhadap yang lainnya. Ini murni adalah pekerjaan harian software designer, yaitu memilih framework dan teknologi. Berbagai saran dan masukan dari pendukung masing-masing framework sangat diharapkan.

Hello World akan dibahas di artikel selanjutnya.


Ruthless Testing 4

Database testing merupakan suatu kegiatan yang sulit, apalagi dalam dunia Java. Bayangkan saja, untuk melakukan testing database, kita harus melakukan :

  1. Membuat skema database. Skema terdiri dari dari tabel, constraint, view, dan lainnya.

  2. Mengisi sampel data.

  3. Mengeksekusi query.

  4. Periksa ke database untuk memastikan hasilnya benar.

  5. Koreksi atau lanjutkan sesuai dengan hasil di nomer 4.

Semua kegiatan di atas sangat membosankan dan melelahkan untuk diulang-ulang setiap kali melakukan perubahan kode program. Akibatnya programmer menjadi bosan dan malas mengetes kode programnya. Padahal kode akses database merupakan salah satu bagian krusial dalam aplikasi.

Pada artikel ini kita akan membahas cara membuat kode akses database yang mudah dan cepat, dilengkapi dengan testing yang menyeluruh dan menyenangkan.

Saya biasanya menggunakan kombinasi Spring Framework dan Hibernate. Dengan kombinasi ini, kita dapat membuat aplikasi dengan sangat cepat.

Kita mulai dengan struktur tabel sederhana. Misalnya kita memiliki class Siswa, sebagai berikut:

Class Siswa

public class Siswa {
  private Integer id;
  private String nama;
  private Date tanggalLahir;

  public Integer getId() { return this.id; }
  public String getNama() { return this.nama; }
  public Date getTanggalLahir() { return this.tanggalLahir; }

  // setter method  
}

class ini akan disimpan di database dengan struktur tabel (MySQL) sebagai berikut:

mysql-schema.sql

CREATE TABLE TBL_SISWA (
  id_siswa INT PRIMARY KEY AUTO_INCREMENT, 
  nama VARCHAR(255), 
  tanggal_lahir DATE
);

Dengan menggunakan Hibernate, kita tidak perlu menulis SQL query. Sebagai gantinya, kita harus memberitahu Hibernate tentang skema database kita. Caranya adalah dengan menambahkan annotation sehingga class kita menjadi seperti ini:

Siswa.java

package tutorial.hibernate;
@Entity
@Table(name="TBL_SISWA")
public class Siswa {
  private Integer id;
  private String nama;
  private Date tanggalLahir;

  @Id
  @Column(name="id_siswa")
  @GeneratedValue(strategy=GenerationType.AUTO)
  public Integer getId() { return this.id; }

  public String getNama() { return this.nama; }

  @Column(name="tanggal_lahir")
  public Date getTanggalLahir() { return this.tanggalLahir; }
}

Pembaca yang teliti segera protes, “Ada yang ketinggalan!! Di atas public String getNama() belum ada @Column”
Tidak, itu bukan kelupaan. Tapi memang Hibernate dapat dengan cerdas menebak nama kolom. public String getNama akan diterjemahkan menjadi kolom nama. Bahkan seandainya nama tabel kita SISWA (bukannya TBL_SISWA), kita tidak perlu menuliskan @Table.

Oke. Sekarang mapping sudah selesai. Saatnya membuat kode untuk mengisi record (create), membaca record (read), mengubah record (update), dan menghapus record (delete). Empat serangkai operasi database ini dikenal dengan istilah CRUD.

Pertama, kita buat interface dulu, kode yang mendefinisikan operasi CRUD ini.

SiswaDao.java

package tutorial.hibernate;
public interface SiswaDao {
  public void create(Siswa s);
  public Siswa getById(Integer id);
  public void update(Siswa s);
  public void delete(Siswa s);  
}

Pembuatan interface berguna supaya kapan-kapan kalau kita sudah bosan dengan Hibernate, kita bisa mengganti dengan implementasi yang lainnya, misalnya iBatis atau JDBC biasa.

Berikut implementasi operasi CRUD dengan Spring dan Hibernate.

SiswaDaoHibernate.java

package tutorial.hibernate;
public class SiswaDaoHibernate extends HibernateDaoSupport implements SiswaDao {
  public void create(Siswa s){
    getHibernateTemplate().save(s);
  }

  public Siswa getById(Integer id){
    return (Siswa) getHibernateTemplate().load(Siswa.class, id);
  }
  
  public void update(Siswa s){
    getHibernateTemplate().update(s);
  }

  public void delete(Siswa s) {
    getHibernateTemplate().delete(s);
  } 
}

Lagi-lagi ada yang bertanya, “Kok tidak ada kode untuk menangani koneksi database? Mana connect dan disconnect dengan database? Mana kode untuk begin dan commit transaction?”

Semua kode birokratis yang ditanyakan barusan akan diinisialisasi melalui Spring Framework. Sebenarnya kita bisa saja menginisialisasi sendiri melalui kode program biasa. Tapi akan lebih efisien dan konsisten apabila kita menggunakan Spring Framework, seperti akan kita lihat sebentar lagi.

Berikut adalah deklarasi SiswaDaoHibernate, DataSource koneksi database, dan konfigurasi transaction :

belajar.xml

<beans>
    <bean id="siswaDaoAsli" class="tutorial.hibernate.SiswaDaoHibernate">
      <property name="sessionFactory"><ref bean="sessionFactory"/></property>
    </bean> 

    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
      <property name="dataSource" ref="dataSource"/>
      <property name="annotatedClasses">
        <list>
          <value>tutorial.hibernate.Siswa</value>
    	</list>
    	</property>
    	<property name="hibernateProperties">
            <props>
                <prop key="hibernate.hbm2ddl.auto">create</prop> 
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
            </props>
    	</property>
    </bean>

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost/belajar"/>
    	<property name="username" value="belajar"/>
    	<property name="password" value="belajar"/>
    </bean>

    <bean id="siswaDao" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="transactionManager" ref="transactionManager"/>

    	<property name="target" ref="siswaDaoAsli"/>

    	<property name="transactionAttributes">

    		<props>

    			<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>

    			<prop key="create*">PROPAGATION_REQUIRED</prop>
    			<prop key="update*">PROPAGATION_REQUIRED</prop>

    			<prop key="delete*">PROPAGATION_REQUIRED</prop>

    		</props>

    	</property>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    	<property name="sessionFactory" ref="sessionFactory"/>
    </bean>
</beans>

Object yang kita gunakan adalah siswaDao. Object ini dirangkai dari berbagai object lain, diantaranya adalah koneksi database (dataSource), transaction interceptor (gunakan transaction untuk method create, update, delete*), dan transaction manager untuk mengelola transaction Hibernate.

Perhatikan kode ini:

<prop key="hibernate.hbm2ddl.auto">create</prop> 

Baris kode di atas akan men-drop seluruh tabel dan constraint di database, dan membuat ulang semuanya. Dengan demikian, database kita akan fresh seperti baru.

PERHATIAN!!! Jangan dijalankan di database production!!

Berikut adalah unit test untuk class SiswaDaoHibernate:

SiswaDaoHibernateTest.java

package tutorial.hibernate;
public class SiswaDaoHibernateTest extends TestCase {
    private static ApplicationContext ctx;
    private static SiswaDao dao;
    private static DataSource ds;
    private static Connection conn;
    
    static {
        ctx = new ClassPathXmlApplicationContext("belajar.xml");
        dao = (SiswaDao)ctx.getBean("siswaDao");
        ds = (DataSource)ctx.getBean("dataSource"););
    }

    public void setUp() throws Exception {
        conn = ds.getConnection();
    }
    
    public void tearDown() throws Exception {
        conn.close();
    }

    public void testCreate() throws Exception {
        Siswa endy = new Siswa();
        endy.setNama("Endy Muhardin");
        endy.setTanggalLahir(new SimpleDateFormat("dd-MM-yyyy").parse("17-08-1945"));
        dao.save(endy);
    
        // mari kita test
        String sql = "SELECT * FROM TBL_USER WHERE nama='Endy Muhardin'";
        
        ResultSet rs = conn.createStatement().executeQuery(sql);
        assertTrue("harusnya ada minimal satu record", rs.next());
        assertEquals("coba cek tanggal lahir", rs.getDate("tanggal_lahir"), new SimpleDateFormat("dd-MM-yyyy").parse("17-08-1945"));
    }
}

Nah, dengan adanya unit test di atas, kita tidak perlu lagi secara manual menjalankan kode test, kemudian memeriksa isi database.

Sekarang, bagaimana mengetes method getById? Apakah kita harus melakukan insert dulu baru kemudian menjalankan dao.getById(1) ?

Tidak perlu. Kita dapat menggunakan DBUnit untuk menginisialisasi sampel data. Kita buat sampel data (fixture) sebagai berikut:

siswa-fixture.xml

<?xml version="1.0" encoding="UTF-8"?>

<dataset>
    <TBL_USER id="99"
              nama="Khalisa Alayya"
              tanggal_lahir="2005-12-31"
    />
</dataset>

Sekarang, pastikan fixture di atas dijalankan sebelum setiap test dieksekusi. Caranya adalah dengan menambahkan kode berikut di method setUp:

public void setUp() {
    conn = ds.getConnection();
    
    // inisialisasi koneksi DBUnit
    DatabaseConnection dbUnitConn = new DatabaseConnection(conn);
    
    // inisialisasi fixture
    FlatXmlDataSet fixture = new FlatXmlDataSet(new File("siswa-fixtures.xml"));
    
    DatabaseOperation.CLEAN_INSERT.execute(dbUnitConn,fixture);
}

Kode ini :

DatabaseOperation.CLEAN_INSERT.execute(dbUnitConn,fixture);

akan menghapus semua data yang ada di database, dan mengisinya dengan satu record, yaitu Khalisa Alayya.

Sehingga kita dapat membuat kode test seperti ini:

public void testGetById() {
    Siswa khalisa = dao.getById(99);
    assertNotNull(khalisa);
    assertEquals("Khalisa Alayya", khalisa.getNama());
}

Berikut adalah Ant script untuk mengeksekusi test di atas:

build.xml

<project name="belajar-hibernate" default="test" basedir=".">

    <!-- silahkan lengkapi dengan target compile -->

    <target name="test" depends="compile">
		<junit haltonfailure="true" fork="true" printsummary="yes">             
            <classpath refid="project-classpath"/>
            <formatter type="xml"/>
            <batchtest todir="report/junit">
                <fileset dir="bin" includes="**/*Test.class"/>
            </batchtest>
        </junit>
	</target>

</project>

Silahkan jalankan berkali-kali sepuasnya. Rangkaian kode di atas akan dengan senang hati melakukan:

  1. Pembuatan schema

  2. Mengisi sampel data

  3. Menjalankan kode program

  4. Memeriksa hasilnya di database

Tidak perlu memelototi phpmyadmin lagi :D

Semoga bermanfaat.


Wiki

Bagi mereka yang belum tahu, wiki adalah website yang bisa diedit. Contohnya ada di Wikipedia

Biasanya wiki digunakan untuk membuat dokumentasi. Sifatnya yang bisa diedit siapa saja menyebabkan banyak orang bisa langsung berkontribusi mengisi wiki. Tidak perlu direpotkan dengan birokrasi aplikasi CMS seperti biasanya.

Ada banyak aplikasi wiki yang tersedia. Dibuat dalam berbagai bahasa pemrograman. Biasanya, aplikasi wiki diinstal di web server dan diakses oleh orang banyak.

Selain yang diinstal di web server, ada juga yang digunakan di desktop. Saya sendiri menggunakan Zim Desktop Wiki di komputer saya untuk menulis buku.

Buat yang malas (atau tidak bisa) menginstal, bisa menggunakan aplikasi wiki web based yang tidak perlu diinstal di server. Gunakan Tiddly Wiki. Wiki anda tinggal ditulis di komputer sendiri, kemudian diupload ketika sudah selesai.

Saking banyaknya orang yang membuat aplikasi wiki, akhirnya ada yang menyediakan one stop solution untuk memilih wiki. Silahkan kunjungi wikimatrix untuk membandingkan berbagai aplikasi wiki. Dia juga menyediakan wizard untuk membantu pemilihan aplikasi wiki yang sesuai.

Selamat mengeksplorasi. Semoga bermanfaat.


Technorati

Orang-orang pada rame Technorati. Pengen tau barang apa sih ini.

Buat yang udah merasakan manfaatnya, tolong kasi masukan dong.

Terima kasih.


IPK Tiarap

Disclaimer : tiap perusahaan dan interviewer beda-beda. Ini bukan patokan absolut. Yang saya tuliskan di sini hanyalah pengalaman pribadi disertai bumbu penyedap. Saya tidak bertanggung jawab atas segala rekomendasi di bawah. Penggunaan tips di bawah sepenuhnya adalah resiko pengguna.

Di milis Alumni STTTelkom, ada posting menarik, sebagai berikut:

mengapa sih perusahaan membuat rumusan sakral untuk rekrutasi pegawai yakni IPK >= 2.75 ???

Segera saja saya merasa berkompeten untuk menjawabnya. Bukan apa-apa, IPK saya yang cuma 2.69 kan termasuk yang melanggar rumusan sakral di atas :P.

Berikut jawaban saya, saya paste di sini supaya khalayak ramai bisa ikut membaca dan berkomentar.

Alasan utama membatasi IP adalah untuk menyusutkan jumlah pelamar !!!

Batasan ini biasanya ada di posisi yang demandnya dikit, tapi supplynya berlimpah ruah. Misalnya, entry level position, di mana kandidatnya adalah fresh grad semua :D.

Coba bayangkan Anda sebagai petugas penerima karyawan baru. Ada 15 tumpukan lamaran di meja Anda, masing-masing berisi 100 lamaran. Dan masih ada 23 tumpukan lagi di meja pojok ruangan. Kemudian office-boy datang dan mengantarkan 40 tumpukan lagi sambil berkata, “Di depan masih ada 4 kardus lagi Pak, sebentar saya mau ambil troli dulu .. gak kuat ngangkatnya.”

Nah, kuis singkat. Bagaimana cara memproses lamaran tersebut? Jawaban bisa dikirim ke 8080 dengan SMS KUIS

Eh, tidak perlu … akan saya jawab sendiri.

Begini caranya. Segera setelah si office-boy datang dengan troli dan 4 kardus lamaran, bilang ke dia, “Mas, tolong bantu saya ya. Coba ini lamaran dibuka, trus diperiksa satu-satu. Yang IPKnya lebih besar dari 2.75 kumpulkan di meja ini. Sisanya masukkan ke kardus kosong. Nanti kalo ada tukang loak lewat, dikiloin aja. Uangnya boleh buat Mas beli rokok.”

Beberapa jam kemudian, coba periksa hasil pekerjaan si Mas. Kalau tumpukan yang lolos masih tinggi, bilang ke dia, “Mas, revisi sedikit. Yang IPKnya lebih besar dari 3.00 kumpulkan di meja ini. Sisanya … bla .. bla … (silahkan diteruskan)”

Ulangi langkah di atas sampai jumlah lamaran < 20.

Wahh…. ternyata prosesnya begitu. Tapi, gimana kalo IPnya tiarap? Not to worry.

Dalam beberapa kesempatan sebagai decision maker rekrutmen, berikut faktor yang saya pertimbangkan:

  1. Antusiasme, atau istilah kerennya, passion. Semangat itu harus ada dan berapi-api. Namanya juga fresh-grad .. masa gak semangat. Ini juga berkaitan dengan masalah motivasi. Orang yang udah dari sananya semangat, gak sulit disuruh-suruh. Gak perlu dibujuk, ditawari insentif macam-macam. Intinya adalah, saya cari yang memang menyukai pekerjaan yang ditawarkan. Jadi tidak sekedar kerja saja.

  2. Smart. Biasanya di sini saya akan menanyakan problem solving question. Dari cara problem solvingnya, saya bisa menilai apakah seseorang smart atau tidak.

  3. Get things done. Walaupun smart, tapi kalo gak bisa kerja percuma. Saya akan minta diperlihatkan produk-produk yang sudah dihasilkan kandidat. Kebetulan bidang saya adalah software development. Biasanya saya minta didemokan software yang pernah dibuat.

  4. Inisiatif, atau ‘kemampuan mengerjakan hal yang tidak wajib atas kemauan sendiri’ Orang yang biasa ‘take extra mile’ biasanya lebih bagus pekerjaannya dan tidak butuh banyak supervisi dan motivasi.

  5. Free time, waktu luang. Ini adalah indikator penting apakah kandidat tersebut ‘bisa berkembang’ atau tidak. Orang yang berkembang akan memanfaatkan freetime nya untuk belajar hal baru, walaupun tidak disuruh.

Lebih lanjut bisa baca panduan Joel dalam interview

Atau panduan mas Mbot di sini dan di sini.

Jadi, kalo IP anda tidak besar, jangan berkecil harapan, tips dari saya :

  1. Punya koleksi portofolio hasil karya yang siap dipamerkan. Buat dalam bentuk CD yang siap didemokan.

  2. Sering-sering terima pekerjaan freelance walaupun gratisan. Selain memperluas networking, juga tambah pengalaman dan mengasah problem solving skill. Kalau pekerjaannya tangible, tambahkan di koleksi portofolio

  3. Latih inisiatif sehingga menjadi refleks. Salah satu caranya adalah dengan aktif mengerjakan pekerjaan rumah seperti membereskan kamar, mendekorasi ruang kerja, berkebun, dsb.

  4. Isi waktu luang dengan banyak belajar. Sumber bisa diperoleh di internet atau toko buku

  5. Banyak berkontribusi di komunitas, misalnya milis, forum, dsb. Ini akan membuat kita menjadi terkenal sehingga nilai jual meningkat.

  6. Jual diri anda dengan cara memiliki personal website. Pasang semua portofolio di sana. Tulis artikel yang dapat menunjukkan kapabilitas dan kompetensi kita.

  7. Giat beribadah dan berdoa. Penghasilan besar kalo korupsi percuma. Jadi berdoa supaya dapat gaji besar yang halal.

  8. Kasihanilah office boy, maksudnya petugas penerima karyawan baru. Jangan melamar ke semua lowongan. Pilih yang benar-benar disukai dan dikuasai. Kalau belum menguasai, lihat #4. Bukan cuma perusahaan yang bisa selektif, kandidat juga dong.

  9. Kalau Anda fresh graduate, jangan terlalu cerewet tentang salary. Fokus fresh graduate, apalagi yang IPKnya tiarap, adalah sesegera mungkin meninggalkan status fresh graduate. Gimana caranya? Tentu saja dengan memiliki pengalaman kerja. Carilah pekerjaan yang walaupun gajinya kecil, tapi variatif dan besar tantangannya, juga bisa membuat kita tambah pintar. Biasanya ini bisa diperoleh di perusahaan kecil di mana orang biasanya merangkap pekerjaan. Tenang saja, begitu kompetensi meningkat, salary pasti mengikuti. Keuntungan tambahan, sebagai pemilik IPK tiarap, persaingan di perusahaan kecil pasti tidak seketat di perusahaan besar yang pasang iklan di Kompas atau Republika.

Demikian, semoga bermanfaat.