Wednesday, December 14, 2005

Java decompiler


Dari kesimpulan hasil test yang dilakukan pada 9 java decompiler,
JODE merupakan Java decompiler terbaik.

Lihat detail testnya disini

http://www.program-transformation.org/Transform/JavaDecompilerTests

Java decompiler wiki page
http://www.program-transformation.org/Transform/JavaDecompilers


http://blog.technoetic.com/jode-eclipse-plugin/

JAD http://www.kpdus.com/jad.html

Object serialization


Java Serialization

- Object disimpan di memory dan dapat digunakan lagi selama JVM masih running
- Bagaimana menyimpan object agar masih bisa digunakan dilain waktu

- Object serialization adalah proses penyimpanan suatu object pada kondisi
tertentu dalam bentuk deretan byte (sequence of bytes) atau proses
kebalikannya yaitu membuatnya kembali dari deretan byte menjadi object real
dalam JVM

- Object serialization hanya menyimpan object's state. File class dari object
serta method-method-nya tidak disimpan.

- Deretan byte tersebut dapat kemudian kita simpan menjadi suatu file atau
dalam database atau ditransfer lewat jaringan.

- Suatu object yang dapat disimpan dan dibuat lagi (persist) harus dibuat
menjadi persistance object.

- Object yang dapat disimpan dengan mekanisme object serialization disebut
serializable object atau object tersebut bersifat serializable

- Untuk membuat object menjadi serializable, maka object tersebut ditandai
dengan cara mengimplementasikan interface java.io.Serializable baik secara
langsung ataupun tidak langsung (maksudnya secara hirarki object tersebut


- Contoh :

import java.io.Serializable;
import java.util.Date;
import java.util.Calendar;
public class PersistentTime implements Serializable {
private Date time;
public PersistentTime() {
time = Calendar.getInstance().getTime();
}

public Date getTime() {
return time;
}
}

- Object diatas, karena telah mengimplementasikan interface Serializable,
dapat disimpan sebagai object persistence

- Interface Serializable merupakan interface kosong yang hanya sebuah
interface penanda (marker)

- Untuk menyimpan atau mentransfer serializable object kita dapat
menggunakan mentod ObjectOutputStream.writeObject(Object obj).

- ObjectOutputStream merupakan sebuah filter stream class yang dapat kita
gunakan untuk menyimpan byte stream yang disimpan di memori atau disimpan
menjadi file di disk atau ditransfer lewat network

- Contoh menyimpan object menjadi suatu file:

import java.io.ObjectOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FlattenTime {
public static void main(String [] args) {
PersistentTime time = new PersistentTime();
FileOutputStream fos = null;
ObjectOutputStream out = null;
try {
fos = new FileOutputStream("time.obj");
out = new ObjectOutputStream(fos);
out.writeObject(time);
out.close();
} catch(IOException ex) {
ex.printStackTrace();
}
}
}


contoh diatas akan menyimpan object menjadi suatu file bernama time.obj

- Contoh untuk membuat object dari persistance object

import java.io.ObjectInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Calendar;

public class InflateTime {
public static void main(String [] args) {
PersistentTime time = null;
FileInputStream fis = null;
ObjectInputStream in = null;
try {
fis = new FileInputStream("time.obj");
in = new ObjectInputStream(fis);

// Recreate object
time = (PersistentTime)in.readObject();
in.close();
} catch(IOException ex) {
ex.printStackTrace();
} catch(ClassNotFoundException ex) {
ex.printStackTrace();
}
}


contoh diatas membuat object dari file bernama time.obj

- Proses untuk mendapatkan object dari sequence of bytes disebut proses
deserialization

- Untuk mendapatkan real object kita harus melakukan casting menggunakan
class aslinya dari object tersebut. Dalam contoh diatas adalah
PersistentTime.

Karena sebenarnya persistance object hanya menyimpan state/property
dari object itu saja

- Tidak semua object serializable, contohnya Thread, Socket, OutputStream
dan subclass-nya.

- Bagaimana jika object yang serializable memiliki object yang tidak
serializable?

Object tersebut harus ditandai dengan deklarasi "transient"

- Ketika object di-deserialize (dilakukan casting setelah byte stream
dibaca) constructor dari object tersebut tidak dipanggil.
Bagaimana jika ada proses yang penting yang ada di constructor object
tersebut?

- Kita dapat membuat method tersendiri dan constructor memanggil method
tersebut. Jika object di-deserialize maka kita harus secara manual
memanggil method tersebut.

- Proses tersebut dapat diotomatisasi dengan mengimplementasikan method
spesial berikut :

private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException;

- Contoh :

public class MyObject implements Serializable {

public MyObject() {
initialization();
}

private void initialization() {
// code constructor disini
}

private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException {
//
in.defaultReadObject();

initialization();
}
}


- Kita dapat melakukan hal yang sama untuk proses serialization
menggunakan method spesial berikut:

private void writeObject(java.io.ObjectOutputStream out)
throws IOException

- Method spesial readObject() dan writeObject() juga dapat digunakan untuk
memastikan suatu proses dilakukan pada saat serialize atau deserialize.

Misalnya untuk keperluan security pada object yang disimpan maka setiap
proses serialization object akan dienkrip terlebih dahulu dan didekrip
saat proses deserialization

Contoh lain misalnya pada kasus suatu class serializable merupakan
subclass dari class yang non-serializable. Untuk memastikan field dari
parent class tersimpan dalam byte stream kita bisa menambahan code untuk
menyimpan field dari parent class pasa method writeObject().
Lihat contoh code di:

http://java.sun.com/j2se/1.4.2/docs/guide/serialization/examples/nonserialsuper/sources.html


- Bagaimana jika suatu object yang merupakan subclass dari object
yang Serializable tidak ingin bisa di-serialize atau di-deserialize?
Gunakan method spesial tadi untuk menglemparkan Exception throw misalnya :

throw new NotSerializableException("This object cannot be serialize");

- Saat object di-serialize, maka dibuat sebuah "fingerprint" yang disebut
serialVersionUID berupa 64-bit data.

- Kita dapat membuat serialVersionUID sendiri dari awal pada serializable
object dengan menambahkan field long bernilai sembarang seperti ini:

static final long serialVersionUID = 4070409649129120458L;

- Jika suatu file dari persistance object disimpan kemudian object tersebut
mengalami perubahan kecil, misalnya penambahan field (java code berubah),
dan kita dapat mengatakan bahwa file dari persistance object yang
disimpan masih kompatibel dengan object yang baru maka object baru
tersebut harus diberikan serialVersionUID yang sama object yang lama.

Jika hal ini tidak dilakukan proses deserialization akan menghasilkan
exception java.io.InvalidClassException.

- Untuk mengetahui serialVersionUID dari byte stream file, dapat digunakan
tool "serialver" yang ada di JDK.

- Serialization menggunakan algoritma rekursif, semua object yang dimiliki object
serializable akan di serialize.
Jika class serializable A tersebut memiliki class serializable B yang memiliki
class serializable C, maka proses serialization pada object A akan juga men-
serialize object B dan C

- Proses serialization menggunakan reflection

[http://java.sun.com/docs/books/tutorial/reflect/]


- The Externalizable Interface

package java.io;

public interface Externalizable extends Serializable {
public void writeExternal(ObjectOutput out) throws IOException;
public void readExternal(ObjectInput in) throws IOException,
java.lang.ClassNotFoundException;
}


- Interface Externalizable memiliki 2 method yang memberikan kontrol kepada
implementor saat melakukan serialization, misalnya kita dapat menuliskan
kode yang menspesifikasikan atribut mana saja yang dimiliki object tersebut
yang akan disimpan dalam persistent object.

- Contoh:

import java.io.*;

public class User implements Externalizable {
long userID;
String firstName;
String lastName;
java.util.Date createdDate;
String password;

public void writeExternal(ObjectOutput stream) throws java.io.IOException {
stream.writeLong(userID);
stream.writeUTF(firstName);
}

public void readExternal(ObjectInput stream) throws java.io.IOException {
userID = stream.readLong();
firstName = stream.readUTF();
}

}

- Dengan interface Externalizable kita dapat membuat proses serialization
menjadi lebih efisien.


- Links :
http://java.sun.com/developer/technicalArticles/Programming/serialization/
http://www.jguru.com/faq/subtopic.jsp?topicID=3341

Saturday, August 13, 2005

Mengenal protokol Hessian/Burlap

Hessian
  • Protokol binary yang sederhana (lightweight) untuk menghubungkan web services.
  • Menggunakan HTTP sebagai protokol transport
  • Karena sederhana/kecil hessian dapat digunakan pada J2ME
  • Spesifikasinya bersifat terbuka, dapat dilihat di http://www.caucho.com/resin-3.0/protocols/hessian-1.0-spec.xtp

  • Dikembangkan oleh Caucho Technology
  • Implementasi library java dari Caucho Tech. berlisensi Apache License

  • Implementasi Hessian server berupa servlet
  • Tidak memerlukan intermediate definition language (IDL) atau schema eksternal
  • Cukup menggunakan interface

  • Implementasi service untuk server hanya perlu meng-extend com.caucho.hessian.server.HessianServlet
  • Service pada server juga dapat berupa POJO yang kemudian menggunakan IoC
  • Contoh:
   import com.caucho.hessian.server.HessianServlet;

public class BasicService extends HessianServlet implements BasicAPI {
private String _greeting = "Hello, world";

public void setGreeting(String greeting) {
_greeting = greeting;
}

public String hello() {
return _greeting;
}
}
  • Sedangkan client hanya memerlukan com.caucho.hessian.client.HessianProxyFactory untuk memanggil service di server
  • Contoh:
   import com.caucho.hessian.client.HessianProxyFactory;
public class BasicClient {

public static void main(String[] args) {
// Setting jika menggunakan proxy
System.getProperties().put("proxySet", "true");
System.getProperties().put("http.proxyHost", "10.0.0.1");
System.getProperties().put("http.proxyPort", "8080");

String url = "http://www.caucho.com/hessian/test/basic";
HessianProxyFactory factory = new HessianProxyFactory();
BasicAPI basic = null;
try {
basic = (BasicAPI) factory.create(BasicAPI.class, url);
} catch (MalformedURLException e) {
e.printStackTrace();
}
System.out.println("hello(): " + basic.hello());
}
}
  • Client dan server menggunakan interface yang sama yaitu:
   public interface BasicAPI {
public String hello();
}
Burlap

Friday, August 05, 2005

CAPTCHA

Saat ini, ketika kita mencoba registrasi ke suatu sistem dalam aplikasi web di internet, kita mendapatkan pertanyaan verifikasi seperti menjawab suatu tulisan pada suatu gambar yang sedikit dikaburkan tapi masih bisa terbaca, atau menjawab suatu operasi matematik sederhana.

Proses verifikasi seperti itu dilakukan untuk menghindari registrasi otomatis (screen scraping) yang dilakukan program komputer. Jadi sistem registrasi mencoba memverifikasi bahwa yang register adalah orang, bukan mesin.

Program untuk dapat membuat dan melakukan grade test sehingga banyak orang/manusia dapat melewati (pass) sedangkan program komputer saat ini tidak dapat melewatinya, bisa kita sebut sebagai CAPTCHA. (Kata "banyak" dan "saat ini" didefiniskan kemudian).

CAPTCHA singkatan dari "Completely Automated Public Turing Test to Tell Computers and Humans Apart". Public berarti kode program harus diberi komentar dan mudah untuk dimengerti, dan semua data yang digunakan pada sebuah CAPCHA haruslah bersifat publik. Turing test adalah test menebak sesuatu oleh manusia, dalam hal ini 'lawan'-nya adalah program komputer.

Metode untuk mendistorsi karakter pada gambar biasanya adalah:
  • tipe font
  • penambahan latar belakang (pattern, gradasi warna)
  • penambahan object lain yang sedikit menutupi karakter/huruf
  • perbedaan warna tiap-tiap huruf, atau border dari huruf
  • mengubah karakter dengan menggunakan algoritma distrosi misalnya
    - pembelokan garis sehingga karakter jadi meliuk-liuk (shadowgimpy)
    - memperesar bagian tertentu dengan kesan cermin cembung (FishEye)


LINKs:

CAPTCHA homepage
Salah satu implementasi Java - JCAPTCHA

Wednesday, July 27, 2005

commons-dbutils little hacks

commons-dbutils-1.0

1. Mapping nama kolom ke bean properties
Untuk merubah mapping nama kolom ke bean properties, dari standar penulisan field tabel di database yaitu dengan separator underscore "_" menjadi standar penulisan object field di java class yaitu tanpa separator dengan huruf kapital di awal kata. Misalnya: CUSTOMER_NAME menjadi customerName.

Ubah method mapColumnsToProperties pada class BeanProcessor pada line 365 yaitu:

String columnName = rsmd.getColumnName(col);
menjadi
columnName = StringUtils.replace(columnName, "_", "");
Referensi ini ternyata lebih baik dari apa yang saya buat disini.

2. QueryRunner yang bersifat scrollable.
Kita biasanya perlu berpindah-pindah cursor (scrollable) dari suatu result set dengan menggunakan method afterLast(), beforeFirst() dan lain-lain.

Default class QueryRunner dalam commons-dbutils adalah menghasilkan ResultSet yang bersifat TYPE_FORWARD_ONLY dan CONCUR_READ_ONLY. Untuk mengubah agar ResultSet dapat kita perlu membuat subclass dari class QueryRunner yang implementasinya seperti ini:

/*
* Created on Sep 23, 2004
*
*/

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.sql.DataSource;
import org.apache.commons.dbutils.QueryRunner;

public class QueryRunnerScrollable extends QueryRunner {

public QueryRunnerScrollable() {
super();
}

public QueryRunnerScrollable(DataSource ds) {
super(ds);
}

protected PreparedStatement prepareStatement(Connection conn, String sql)
throws SQLException {
return conn.prepareStatement(
sql,
ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_READ_ONLY);
}
}

Monday, June 06, 2005

Java basic: Protected modifier and default modifier

Protected modifier dari suatu field dalam suatu class berarti selain dirinya sendiri yang dapat mengakses field tersebut, class lain yang bisa mengakses field tersebut adalah:
  • class yang satu package dengan class tersebut
  • class yang merupakan subclass dari class tersebut walaupun berbeda package

Default modifier agak berbeda dengan protected modifier, karena

  • subclass di package yang berbeda tidak dapat mengakses field tersebut

Java Network Launching application

Ini beberapa alternatif aplikasi untuk lauching java program lewat network:

Karakteristik RIA

Karakteristik RIA (Rich Internet Applications) :

  • Poses di server dan komunikasi client-server (network traffic) direduksi dengan sebisa mungkin melakukan proses di client
  • Mendukung cross platform (operating system, device) di client
  • Richness of the media (audio, grphics, video/animation)
  • Bisa membuat grafik atau media file lainya secara on the fly
  • Membutuhkan plugin
  • Data dapat dicache di client- Responsive
  • Control yang lebih bervariasi dan responsif seperti pada aplikasi desktop biasa (date picker, gauges, slider, dan lain-lain)
  • Tampilan dan proses konsisten karena dapat dibuat tidak tergantung browser.
  • Beberapa masih menggunakan browser dengan teknologi HTML + javascript
  • Dapat menyimpan state/data yang lebih besar di client (teknologi cookie dan session pada web bisa ditinggalkan)

Beberapa teknologi RIA:

Kekurangan apliksi WEB (diambil dari majalah SDAAsia versi Indonesia) :

  • Mekanisme pemnyimpanan data di client sangat terbatas, biasanya memanfaatkan cookie dan session dari mekanisme HTTP.
  • Tiap pemrosesan logika biasanya dilakukan di server sehingga respon aplikasi menjadi lambat, selain itu menambah beban di server dan memperbesar data bandwidth jaringan.
  • Tiap alur proses dari aplikai menghasilkan respon halaman web terdiri dari code HTML yang harus di kirim ke client secara lengkap berulang kali, meskipun masih menampilkan halaman yg sama.
  • Validasi dan proses logika di client biasanya memanfaatkan JavaScript, yang dapat diutak-atik atau dinonaktifkan sehingga tidak berfungsi.
  • Efek-efek tampilan atau proses logika di client sering kali mendayagunakan DHTML atau JavaScript yang terkadang tidak compatible dengan browser tertentu. Misalnya menu pop-up muncul di Internet Explorer tetapi tidak tampak atau tidak berfungsi dengan baik di Mozilla.
  • Komponen GUI dari web form terbatas.

Wednesday, June 01, 2005

Apa spring framework memiliki feature AOP?

Spring menggunakan istilah interceptor untuk melakukan mekanisme AOP. Memang dalam dokumentasi spring disebutkan bahwa AOP pada spring framework dibuat sederhana dan tidak memiliki semua kemampuan seperti layaknya AOP framework.

Interceptor/interception ternyata merupakan istilah yang lebih cocok untuk enterprise framework seperti disebutkan dalam buku "Pattern of Software Architecture" karya Schmidt, dijelaskan

The Interceptor architectural pattern allows services to be added transparently to a framework and triggered automatically when certain events occur.

Artikel ini, "Setting the Story Straight: AOP != Interception" (link dari web archive) menarik untuk dibaca. Menurut penulisnya interception pattern berbeda dengan AOP.

Sebagai kesimpulan artikel tersebut: Interception can be seen as a simplified form of AOP.

Friday, May 06, 2005

Java XML-RPC, gampang banget...

Ingin membuat aplikasi client-server? tidak mau membuat web service karena terlalu ribet? tidak mau terlalu banyak coding dengan RMI? coba XML-RPC menggunakan Apache XML-RPC

Apache XML-RPC mudah digunakan. Hanya dengan sedikit coding kita sudah bisa membuat aplikasi client-server. Bisa menggunakan Built-in HTTP Server sebagai server atau kita juga bisa membuat servlet yang di-deploy di web server (servlet container).

Langkah pertama membuat class handler yang akan menjadi class pemroses (processor) dari setiap request. Contoh :
 public class Messenger {
public String send(String address, String message) {
// process sending message here
return "Sending successful to " + address+ " message is \"" + message + "\"";
}
}
Lalu buat server:
  import org.apache.xmlrpc.WebServer;
public class XmlRpcServer {
public static void main(String[] args) {
try {
WebServer webServer = new WebServer(7777);
webServer.addHandler("MyMessanger", new Messenger());
webServer.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Setelah itu jalankan server, dan buat client:
  import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Vector;
import org.apache.xmlrpc.XmlRpcClient;
import org.apache.xmlrpc.XmlRpcException;
public class SmsEngineClient {
public static void main(String[] args) {
try {
XmlRpcClient client = new XmlRpcClient("http://localhost:7777");
Vector params = new Vector ();
params.addElement("friend");
params.addElement ("Apa kabar euy?");
String result = (String) client.execute("MyMessanger.send", params);
System.out.println(result);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (XmlRpcException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Jalankan program client, dan lihat hasilnya. Mudah sekali.

Dengan XML-RPC kita bisa dengan mudah melakukan pertukaran data dengan tipe:
int, boolean, java.lang.String, double, java.util.Date, java.util.Hashtable, java.util.Vector dan byte[] (byte array, untuk pengiriman file misalnya).

Jadi kenapa tidak pakai XML-RPC saja?

Menjalankan program Java pada Windows Service atau sebagai Unix daemon

Ingin menjalakan program java sebagai Windows Service? atau sebagai daemon di sistem operasi Linux atau Unix?

Kita bisa gunakan Java Service Wrapper dengan mudah untuk keperluan tersebut. Java Service Wrapper mempunyai tiga metode untuk dapat menjalankan aplikasi java kita sebagai Windows service atau daemon.

Metode yang paling mudah bahkan tanpa mengubah sedikitpun aplikasi yang sudah kita buat. Pada versi 3.1.2, hanya dengan mengubah file wrapper.conf sesuai kebutuhan dan menjalankan file MyApp.bat, kita sudah bisa menjalankan aplikasi java sebagai Windows service.

Tutorial menyusul...

Paging pada iBatis

iBatis memiliki inteface PaginatedList dengan PaginatedArrayList sebagai class implementasi yang bisa kita gunakan untuk keperluan paging dengan mudah. Tetapi sayangnya interface tersebut tidak memiliki method untuk mendapatkan berapa jumlah keseluruhan data. Kita hanya bisa membuat navigasi previous dan next dengan informasi halaman (page) tanpa bisa menampilkan jumlah seleuruh halaman atau record yang ada.

Dibawah ini kode demo menggunakan falitas paging pada ibatis:
 PaginatedList usersPL = UserDao.getUserPaginatedList(2);
for (int i =0; i < usersPL .size(); i++) {
System.out.println(usersPL .get(i));
}
System.out.println(
"-- Page: " + usersPL .getPageIndex() +
", Row size: " + usersPL .getPageSize() );

System.out.println("-- Goto page 3");
usersPL .gotoPage(3);
for (int i =0; i< usersPL .size(); i++) {
System.out.println(usersPL .get(i));
}
System.out.println("-- Page: " + usersPL .getPageIndex() );

System.out.println("-- Goto next page");
usersPL.nextPage(3);
for (int i =0; i< usersPL .size(); i++) {
System.out.println(usersPL .get(i));
}
System.out.println("-- Page: " + usersPL.getPageIndex() );

Friday, April 29, 2005

Hati-hati dengan lisensi software

Gerakan open source adalah hal yang bagus dan telah membuat perkembangan software di negara berkembang, seperti Indonesia ini, cukup cepat. Dunia Java banyak juga diwarnai dengan proyek-proyek free dan open source dan di Indonesia, saya percaya telah banyak juga proyek-proyek komersial yang menggunakan free/open source software yang terdapat di Internet.

Tapi sayangnya karena hukum, terutama yang menyangkut IT, kurang berlaku disini (implementasinya tidak bagus) maka banyak orang menggunakan free/open source software tanpa memperhatikan lisensinya. Ini berbahaya dan budaya yang tidak bagus. Sebagai contoh, banyak orang menggunakan software berlisensi GPL (GNU Public License) untuk keperluan komersial tapi mereka --karena menggunakan untuk software komersial-- merasa produknya benar-benar miliknya, hasil jerihpayahnya sehingga tidak mau memberikan source code-nya ke konsumen/klien. Hal seperti itu tentu saja salah karena GPL mengharuskan baru yang menggunakan software berlisensi GPL juga harus menyertakan source codenya baik itu tertulis atau dalam bentuk soft-copy.

Jadi sudah seharusnya kita membaca lisensi produk open source yang akan kita gunakan. Jika ingin memakai software free/open source, carilah yang memang sesuai dengan lisensi produk yang akan dibuat.

Macam-macam lisensi open source dapat dilihat di website OSI

Monday, April 25, 2005

IT dan birokrasi?

Ada yang salah dengan birokrasi IT?

Ini sekedar share pengalaman, saat birokrasi IT pada suatu perusahaan kadang membuat orang teknis menjadi pusing dan terjepit. Terjepit antara birokrasi dengan masalah yang perlu diselesaikan dengan cepat.

Wednesday, April 20, 2005

Ekspresi logika

Baru saja saya dapat masalah gara-gara desain user interface (UI) yang kurang fleksibel. Masalahnya bermula dari kebutuhan client akan pembuatan aturan logika untuk keperluan strategi bisnisnya. Aturan tersebut dibentuk dari variabel-varibel yang sudah ditentukan (ada) dan mudah untuk diubah-ubah. Sistem harus membaca aturan logika yang dibuat dan mengeksekusinya. Masalah timbul karena desain UI yang dibuat tidak dapat membuat prioritas pada deretan aturan logic. Contoh yang dimaksud adalah seperti ini:

(a OR b) AND c

Logika "a OR b" akan dieksekusi dahulu, kemudian hasilnya akan di-AND dengan variabel c. Jika aturan tersebut kita tuliskan

a OR b AND c

hasilnya akan berlainan, karena tingkat eksekusi AND (precedence) adalah lebih dulu dibanding OR. Aturan tersebut akan dieksekusi seperti

a OR (b AND c)

Dengan prioritas (tangan kurung) kita akan lebih mudah untuk membuat aturan logika, tapi akan sulit jika tanpa prioritas, apalagi aturannya sudah semakin kompleks atau rumit. Tidak mudah untuk mengubah UI sehingga mendukung prioritas, jadi untuk saat ini client harus membuat aturan logika tanpa prioritas. Jadi tantangannya adalah bagaimana membuat sebuah sebuah ekspresi atau aturan logika tanpa tanda kurung yang ekivalen dengan aturan logika aslinya. Atau dalam kata lain bagaimana kita menghilangkan tanda kurung dalam sebuah ekspresi logika?

Sepertinya belum ada software tool untuk keperluan seperti ini. Sebagai bahan acuan, hukum logika berikut ini (ingat kembali pelajaran SMP) kadang membantu, tapi tidak dijamin..


  1. Hukum Komutatif
    a AND b <=> b AND a,
    A OR B <=> B OR A
  2. Hukum Asosiatif
    (a AND b) AND c <=> a AND (b AND c),
    (a OR b) OR c <=> a OR (b OR c)
  3. Teorema DeMorgan's
    NOT (a OR b) <=> NOT A AND NOT B,
    NOT (a AND b) <=> NOT a OR NOT b
  4. Hukum distributif
    a OR (b AND c) <=> (a AND b) OR (a AND c),
    a AND (b OR c) <=> (a OR b) AND (a OR c)

Java Expression Parser (JEP) cukup bagus untuk melakukan parsing pada ekpresi logika boolean. JEP inilah yang saya gunakan sebagai mekanik untuk mengeksekusi ekspresi logika. JEP mendukung prioritas eksekusi dengan tanga kurung, jadi masalah tanda kurung pada masalah saya adalah bagaimana UI dapat dengan mudah membuatnya, artinya perombakan UI. Ini yang saya sesalkan...


Monday, April 18, 2005

AJAX: Web based rich client application

Yang belum tau AJAX artikel "Ajax: A New Approach to Web Applications" merupakan artikel utama yang mempopulerkan teknik ini.

AJAX = Asynchronous JavaScript + CSS + DOM + XMLHttpRequest.

AJAX merupakan sebutan untuk teknik pada aplikasi web yang menggunakan :
  • Presentasi web berbasis standar XHTML dan CSS;
  • Tampilan dan interaksi dinamis menggunakan Document Object Model (DOM);
  • Perukaran dan manipulasi data menggunakan XML dan XSLT;
  • Penggambilan data secara asynchronous menggunakan XMLHttpRequest;
  • Menggunakan JavaScript sebagai teknologi yang menggabungkan komponen2 tersebut.
Keuntungan menggunakan AJAX:
  • Lebih efektif, karena beberapa hal :
    • Transfer data hanya untuk bagian tertentu yang akan diupdate pada sebuah halaman web sehingga transfer data lebih kecil.
    • Beberapa proses cenderung dilakukan di client
  • Halaman web lebih interaktif atau responsif
Kerugiannya:
  • Sangat tergantung pada kompabilitas browser karena menggunakan client side scripting.
  • Point accessibility bisa menurun karena tergantung pada konfigurasi/kemampuan browser.
  • Lebih rumit dari aplikasi web biasa karena banyak menggunakan client side scripting, hal ini bisa diminimalisasi dengan adanya tools, library atau framework. Misalnya menggunakan DWR, JavaScript O Lait
  • Effort testing/debugging lebih besar
Saat ini pun kelihatannya Sun mulai mengadopsi AJAX sebagai blueprint solusi untuk aplikasi J2EE. Coba baca artikel: Asynchronous JavaScript and XML (AJAX) with Java 2 Enterprise Edition

Website portal tentang AJAX, www.ajaxmatters.com bagus untuk referensi, karena berisi link-link tentang artikel, tutorial, sample code dan lain-lain.

Links lainnya:
JavaScript/ECMAScript Language Specification
ECMAScript for XML (E4X) Specification
Document Object Model (DOM) Level 3 Load and Save Specification



Friday, April 15, 2005

Hati-hati menggunakan Singleton pada aplikasi Java.

Kita biasanya menggunakan singleton class (pattern) untuk keperluan caching, dimana setiap object yang mengakses instance dari singleton class akan mendapatkan nilai yang sama.
Instance dari class singleton hanya akan ada satu dalam JVM, karena pattern ini menghindari pembuatan instance baru jika sudah ada sebuah instance.
Dengan singleton pattern kita terhindar dari meng-create object berulang-ulang.

Tapi kita perlu hati-hati menggunakan Singelton di aplikasi J2EE. Karena ada scalability issue yang harus diperhatikan jika kita menggunakan singleton.

Perhatikan, ada beberapa hal yang membuat Singleton tidak singleton.

Jika aplikasi kita multithreding, ada masalah synchronization yang membuat class singleton menjadi beberapa instances. Yaitu jika pada method yang meng-create instance dari class singleton diakses oleh lebih dari satu thread pada waktu yang --hampir-- bersamaan.

Jika aplikasi kita menggunakan lebih dari satu JVM misalnya pada aplikasi terdistribusi/cluster, bagaimana kita menduplikasi singleton antar JVM?

Singleton biasanya menggunakan "static" keyword, dan ini bisa menimbulkan masalah pada aplikasi J2EE yang menggunakan banyak (lebih dari satu) class loader.

Pada JDK 1.2 virtual machine, singleton dapat di-garbage collection. Karena pada dasarnya instance akan dihapus oleh GC jika tidak ada object lain yang menyimpan reference ke class atau instance tersebut.

Saturday, April 09, 2005

Software design: Harus pakai MDA dan UML?

Ini cerita cepat...

Dulu pertama kali belajar UML (Unified Modeling Language) tidak begitu mudah apalagi saya belajar programming bersamaan dengan belajar mendesain software (tentu saja dengan menggunakan UML). Yang saya rasa pertama kali dengan UML adalah bingung, karena terlalu banyak dan saya tidak tahu kalau kita tidak perlu menggunakan semua digram untuk mendesign software atau sistem. Dan yang membuat saya bingung juga adalah kata "Languange" sehingga saya pikir UML seperti bahasa pemrograman. Saya heran kenapa mereka tidak membuat nama dengan "Diagram". Dengan banyaknya jenis diagram dalam UML membuat belajar lebih lama, berbeda ketika mendesain software hanya dengan flowchart atau DFD (data flow diagram) saja.

UML sepertinya berusaha meng-cover semua kebutuhan untuk desain software, bahkan saya pikir malah tidak hanya software, sehingga begitu banyak model yang digunakan.

Kemudian ketika mendesain dengan metode MDA (Model Driven Architecture), ternyata hambatannya adalah sinkronisasi antara kode riil dengan model awal yang kita buat. Kadang-kadang kita bekerja cepat dan efektif dengan menggubah langsung kode program dengan desain yang masih ada di kepala. Saat kita sedang coding kemudian ingin membuat sebuah class, kita kembali ke diagram, membuat kotak, bla bla bla, kemudian kembali ke kode. Proses yang tidak efektif kan? Adalagi dengan masalah code yang di-generate oleh tool MDA yang pernuh komentar atau template-nay tidak sesuai dengan yang kita inginkan. Kita harus belajar lebih banyak dari tool untuk bisa mulai memprogram. Belum lagi masalah harga tool yang mahal.

Fiuhh... apa sih MDA itu? Saya bingung pertama kali saya dengar MDA karena saya pikir MDA itu adalah sebuah high level architecture system, ternyata bukan. Ternyata dengan definisi mudahnya MDA itu adalah metode membuat software dengan menggunakan berfokus pada modeling dahulu kemudian coding. Dengan fokus pada modeling berarti banyak pekerjaan kita adalah modeling, kemudian dengan modeling tersebut kita bisa generate code (menggunakan tools) sehingga model yang kita buat lebih bersifat powerful. Agar model yang kita buat lebih powerful lagi, maka dibuatlah metadata (yang open) sehingga tidak tool spesific. Agar lebih powerful lagi, maka disyaratkan model tersebut harus language-independent atau platform-independent. Dan saya sadar, ternyata saya sudah melakukan MDA tanpa tau kalau metode yang saya pakai itu adalah MDA.

Oke, jangan bingung-bingung dengan cara bagaimana kita membuat software. Begitu banyak metodologi yang kadang-kadang tidak terlalu jauh beda. Dan jangan bingung dengan begitu banyaknya jargon-jargon yang aneh-aneh dan telalu berlebihan. Kita gak sendirian kalau kita tidak mengimplementasikan MDA atau menggunakan UML.

Monday, April 04, 2005

Change request

Ceritanya...

Setelah kita selesai dengan dokumen-dokumen (business requirement, software design & spefication dan lain-lain) yang disetujui oleh client, kita mulai dengan membangun (develop) apa yang tertulis. Tapi kadang apa yang kita desain salah atau kurang tepat sehingga kita harus mengubah software yang telah kita buat. Perubahan juga bisa terjadi karena kesalahan pengertian terhadap bisnis proses atau memang karena proses bisnis yang berubah.

Perubahan bisnis proses akan membuat kita pusing kepala karena harus merubah aplikasi (software) yang kita buat, karena itu diperlukan "change request document" yang berguna untuk mengontrol perubahan selama project yang dapat mengakibatkan perubahan biaya, waktu, resource dan kualitas. Tanpa perjanjian yang jelas pada scope of project dan manajemen dokumen yang baik, perubahan bisnis akan lebih membuat kita pusing kepala. Oleh karena itu dokumen dan pengesahan (approval) terhadap dokumen menjadi penting.

Isi dokumen change request harus menjelaskan secara lengkap tentang perubahan yang terjadi. Komponen-komponen yang penting untuk ditulis dalam dokumen tersebut adalah:
  • Requestor, orang yang menginisialisasi perubahan
  • Waktu permintaan perubahan
  • List dokumen yang terkait, dokumen lain yang berubah (document affected) akibat dokumen change request atau dokumen tambahan yang memperjelas
  • Detail / deskripsi perubahan
  • Penyebab perubahan
  • Detail analisis
    • Hasil evaluasi, keuntungan dan kerugian yang ditimbulkan dari change request
    • Pengaruh adanya perubahan (impact)
    • Pengaruh jika perubahan tidak dilakukan
    • Pengaruh terhadap system/modul lain
  • Solusi yang digunakan
  • Perubahan biaya
  • Perubahan resource (jumlah orang yang terlibat dalam proyek)
  • Perubahan waktu pengerjaan (plan)
  • List reviewer dan approver
  • Status dokument, misalnya: Open, Approved for analysis, Approved for implementation, Rejected, Deffered, Closed
  • Waktu selesai implementasi
Baik juga jika kita menambahakan atribut pengkategorian dari perubahan yang diminta, misalnya pengkategorian impact yang menunjukan seberapa besar pengaruh yang diakibatkan karena perubaha tersebut , scope of change yang menunjukan jenis perubahan, apakah perubahan bisnis, perubahan desain atau perubahan yang lain.

Pengalaman pribadi saya yang membuat "bete" adalah kejadian ketika client meminta untuk adanya perubahan kemudian kita mulai merespon perimtaan tersebut dengan membuka diskusi. Diskusi mulai panas dan memajang dengan pengaruh yang besar disana sini. Saat diskusi kita selalu memikirkan solusi detail yang akan dilakukan, karena client cukup educated maka kadang diskusi sampai pada desain interface secara umum. Kemudian kita mulai membuat dokumen change request berlembar-lembar, untuk memperjelas dibuat juga gambar-gambar dari mock-up screen yang akan dibuat.Cukup melelahkan. Kemudian setelah dokumen selesai kita mulai men-submit ke orang yang berhak melalukan approval. Karena impact-nya cukup besar, cost-nya pun besar, nah dengan mudahnya sang approver me-reject dokumen atau meminta diskusi ulang untuk solusi yang sederhana (solusi yang diambil dengan toleransi proses bisnis disana-sini). Bagaimana dengan kerjaan, waktu yang telah terbuang sebelumnya?? Inilah yang membuat saya "bete". Karenanya step "approved for analysis" sebelum kita mulai panjang lebar mediskusikan perubahan. Tapi ini terjadi pada proyek saya dimana tim bertindak sebagai kosultan tapi juga implementor.

Wednesday, March 30, 2005

Seperti XML, tetapi bukan

Ada yang bilang XML tidak benar-benar human readable, XML kurang efisien, karenanya beberapa orang membuat alternatif penggati XML yang lebih sederhana dan mudah. Tapi tetap saja XML memiliki kelebihan dari sisi iteroperability, kemudahan mendapatkan library untuk processing-nya (parser), kalaupun kurang simple sudah banyak tool (editor) untuk memanipulasi XML.

Beberapa alternatif pengganti XML diataranya:


Thursday, March 24, 2005

Java: Serialization Tutorial

- Suatu java object disimpan di memory dan dapat digunakan lagi selama JVM masih running

- Bagaimana menyimpan object agar masih bisa digunakan dilain waktu?

- Object serialization adalah proses penyimpanan suatu object pada kondisi tertentu dalam bentuk deretan byte (sequence of bytes) atau proses kebalikannya yaitu membuatnya kembali dari deretan byte menjadi object real dalam JVM

- Object serialization hanya menyimpan object's state. File class dari object serta method-method-nya tidak disimpan.

- Deretan byte tersebut dapat kemudian kita simpan menjadi suatu file atau dalam database atau ditransfer lewat jaringan.

- Suatu object yang dapat disimpan dan dibuat lagi (persit) harus dibuat menjadi persistance object.

- Object yang dapat disimpan dengan mekanisme object serialization disebut serializable object atau object tersebut bersifat serializable

- Untuk membuat object menjadi serializable, maka object tersebut ditandai dengan cara mengimplementasikan interface java.io.Serializable baik secara langsung ataupun tidak langsung (maksudnya secara hirarki object tersebut

- Contoh :
 import java.io.Serializable;
import java.util.Date;
import java.util.Calendar;
public class PersistentTime implements Serializable {
private Date time;
public PersistentTime() {
time = Calendar.getInstance().getTime();
}

public Date getTime() {
return time;
}
}

- Object diatas, karena telah meng-implement Serializable, dapat dibuat menjadi byte stream dan disimpan pada berbagai media misalnya file dalam disk.

- Interface Serializable merupakan interface kosong yang hanya sebuah interface penanda (marker)

- Untuk menyimpan atau mentransfer serializable object kita dapat menggunakan mentod ObjectOutputStream.writeObject(Object obj).

- ObjectOutputStream merupakan sebuah filter stream class yang dapat kita gunakan untuk menyimpan byte stream menjadi file atau ditransfer lewat network

- Contoh menyimpan object menjadi suatu file:
  import java.io.ObjectOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FlattenTime {
public static void main(String [] args) {
PersistentTime time = new PersistentTime();
FileOutputStream fos = null;
ObjectOutputStream out = null;
try {
fos = new FileOutputStream("time.obj");
out = new ObjectOutputStream(fos);
out.writeObject(time);
out.close();
} catch(IOException ex) {
ex.printStackTrace();
}
}
}

contoh diatas akan menyimpan object menjadi suatu file bernama time.obj

- Contoh untuk membuat object dari persistance object
 import java.io.ObjectInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Calendar;

public class InflateTime {
public static void main(String [] args) {
PersistentTime time = null;
FileInputStream fis = null;
ObjectInputStream in = null;
try {
fis = new FileInputStream("time.obj");
in = new ObjectInputStream(fis);

// Recreate object
time = (PersistentTime)in.readObject();
in.close();
} catch(IOException ex) {
ex.printStackTrace();
} catch(ClassNotFoundException ex) {
ex.printStackTrace();
}
}
contoh diatas membuat object dari file bernama time.obj

- Proses untuk mendapatkan object dari sequence of bytes disebut proses deserialization

- Untuk mendapatkan real object kita harus melakukan casting menggunakan class aslinya dari object tersebut. Dalam contoh diatas adalah PersistentTime.

Karena sebenarnya persistance object hanya menyimpan state/property dari object itu saja

- Tidak semua object serializable, contohnya Thread, Socket, OutputStream dan subclass-nya.

- Bagaimana jika object yang serializable memiliki object yang tidak serializable?

Object tersebut harus ditandai dengan deklarasi "transient"

- Ketika object di-deserialize (dilakukan casting setelah byte stream dibaca) constructor dari object tersebut tidak dipanggil. Bagaimana jika ada proses yang penting yang ada di constructor object tersebut?

- Kita dapat membuat method tersendiri dan constructor memanggil method tersebut. Jika object di-deserialize maka kita harus secara manual memanggil method tersebut.

- Proses tersebut dapat diotomatisasi dengan mengimplementasikan method spesial berikut :
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException;
- Contoh :
  public class MyObject implements Serializable {

public MyObject() {
initialization();
}

private void initialization() {
// code constructor disini
}

private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException {
in.defaultReadObject();

initialization();
}

}


- Kita dapat melakukan hal yang sama untuk proses serialization menggunakan method spesial berikut:
private void writeObject(java.io.ObjectOutputStream out)
throws IOException

- Method spesial readObject() dan writeObject() juga dapat digunakan untuk memastikan suatu proses dilakukan pada saat serialize atau deserialize.

Misalnya untuk keperluan security pada object yang disimpan maka setiap proses serialization object akan dienkrip terlebih dahulu dan didekrip saat proses deserialization

Contoh lain misalnya pada kasus suatu class serializable merupakan subclass dari class yang non-serializable. Untuk memastikan field dari parent class tersimpan dalam byte stream kita bisa menambahan code untuk menyimpan field dari parent class pasa method writeObject().
Lihat contoh code di:

http://java.sun.com/j2se/1.4.2/docs/guide/serialization/examples/nonserialsuper/sources.html

- Bagaimana jika suatu object yang merupakan subclass dari object yang Serializable tidak ingin bisa di-serialize atau di-deserialize? Gunakan method spesial tadi untuk melemparkan (throw) exception misalnya :
   throw new NotSerializableException("This object cannot be serialize");
- Saat object di-serialize, maka dibuat sebuah "fingerprint" yang disebut serialVersionUID berupa 64-bit data.

- Kita dapat membuat serialVersionUID sendiri dari awal pada serializable object dengan menambahkan field long bernilai sembarang seperti ini:
   static final long serialVersionUID = 4070409649129120458L;
- Jika suatu file dari persistance object disimpan kemudian object tersebut mengalami perubahan kecil, misalnya penambahan field (java code berubah), dan kita dapat mengatakan bahwa file dari persistance object yang disimpan masih kompatibel dengan object yang baru maka object baru tersebut harus diberikan serialVersionUID yang sama object yang lama.

Jika hal ini tidak dilakukan proses deserialization akan menghasilkan exception java.io.InvalidClassException.

- Untuk mengetahui serialVersionUID dari byte stream file, dapat digunakan tool "serialver" yang ada di JDK.

- The Externalizable Interface
....


- Links :
http://java.sun.com/developer/technicalArticles/Programming/serialization/
http://www.jguru.com/faq/subtopic.jsp?topicID=3341

Friday, March 18, 2005

WS-* spesification map

Kalau kita belajar web service maka kita akan dibingungkan dengan banyaknya spesifikasi/standar yang digunakan. Spesifikasi web service biasanya open sehingga mudah dipelajari tapi karena banyaknya perusahaan atau organisasi yang membuat spesifikasi yang kadang mirip, kita jadi dibingungkan dengan spesifikasi tersebut. Spesifikasi yang mirip biasanya mulcul karena memang merupakan solusi untuk masalah yang sama.

Jika ingin melihat bagaimana rumitnya spesifikasi web service, kita bisa lihat peta "Web Services & WS_* Specifications"

Selain itu juga kita bisa lihat Big Picture of the XML family Of Spesifications.

Wednesday, March 16, 2005

Java: Multi threading pada aplikasi JFC/Swing

  • User melakukan action pada Swing GUI komponen misalnya button
  • Action yang dieksekusi ditulis dalam method event listeners
  • Event listeners selalu dieksekusi dalam Event Dispatch Thread
  • Event Dispatch Thread bertanggung jawab untuk mengeksekusi semua event satu persatu.
  • Jika ada event yang prosesnya lama, event selanjutnya tidak akan dieksekusi sebelum proses tersebut selesai. Event yang belum dieksekusi akan menunggu di Event Queue.
  • Jika event yang belum dieksekusi adalah event yang mengubah tampilan GUI, maka GUI akan terlihat hang dan tidak responsif (frezee).
  • Komponen Swing memang tidak didesain secara default thread save, jadi implementasi yang salah bisa membuat aplikasi Swing
Solusi asynchronous (misalnya, SwingWorker 3) melakukan proses berikut:
  • Segera keluar dari listener method dengan mendelegasikan proses ke thread baru
  • Dengan bantuan class SwingWorker, thread baru yang mengerjakan task/event yang prosesnya lama
  • Menggunakan method SwingUtilities.invokeLater() untuk mengirimkan event baru ke Event Queue
  • Setelah worker thread menyelesaikan prosesnya, maka worker mengirimkan method finished() ke Event Queue
Solusi synchronous (misalnya, Spin dan Foxtrot) melakukan proses berikut:
  • Menggunakan worker thread
  • Event Dispatch Thread tidak keluar dari listener method, tapi melakukan dequeue events
  • Setelah time-consuming task selesai worker class memerintahkan Event Dispatch Thread untuk memberhentikan proses dequeue events dari Event QUeue

  • Kelebihan dengan solusi ini :Kode program lebih readable dan sederhana, exception handling yang lebih baik

Tuesday, March 15, 2005

PHP: NuSOAP dan DIME attachment

Butuh sending atau receiving DIME attachment pada web service manggunakan NuSOAP?

Saat ini saya sedang membuat sebuah class tambahan agar class soapclient dapat mendukung DIME attachment. Class ini dibuat seperti class soapclientmime pada file nusoapdime.php yang dibuat oleh Scott Nichol. Karena PEAR::SOAP sudah mendukung DIME attachment, maka dengan bantuan class Net_DIME dari PEAR maka pekerjaan ini jadi lebih mudah.

Saat ini create DIME attachment yang saya bikin untuk request (memmbuat DIME message untuk dikirim) sudah selesai. Inti perkerjaannya adalah disini :

function &_makeDIMEMessage(&$xml) {
// See class nusoap_base
$namespaces = 'http://schemas.xmlsoap.org/soap/envelope/';

// encode any attachments using DIME (see this link)
// now we have to DIME encode the message
$dime =& new Net_DIME_Message();
$msg =& $dime->encodeData($xml,$namespaces,NULL,NET_DIME_TYPE_URI);

// add the attachements
$c = count($this->requestAttachments);
for ($i=0; $i < $c; $i++) {
$attachment =& $this->requestAttachments[$i];
if ($attachment['data'] == '' && $attachment['filename'] <> '') {
if ($fd = fopen($attachment['filename'], 'rb')) {
$data = fread($fd, filesize($attachment['filename']));
fclose($fd);
} else {
$data = '';
}
$attachment['data'] = $data;
}
$msg .= $dime->encodeData($attachment['data'],
$attachment['contenttype'],
$attachment['cid'],
NET_DIME_TYPE_MEDIA);
}
$msg .= $dime->endMessage();
return $msg;
}
Selanjutnya agar NuSOAP support DIME attachment kita perlu penambahan kapabilitas untuk menerima response DIME message dan kapabilitas pada WSDL.

Friday, March 11, 2005

PHP: NuSOAP with certificate authentication

Dirjen Pajak Indonesia membuat Web Service untuk pelaporan pajak dari individu ataupun lembaga/perusahaan. Ini ide bagus, tapi sayang implementasinya kurang bagus. Saya tidak terlibat dengan project tersebut tapi setidaknya tau.

Web service yang dibuat tersebut disebut dengan eFiling (Electronic Filing System) yang maksudnya adalah layanan untuk mengirimkan Surat Pemberitahuan Pajak Tahunan (SPT) secara online. Web service tersebut dijual ke beberapa ASP (Application Service Provider), kemudian ASP tersebut membuat aplikasi sendiri yang mudah digunakan oleh masyarakat luas.

Implementasi web service tersebut menggunakan .NET, sayangnya pengembang proyek tidak memperhatikan interoperability dan kurang peduli dengan dokumentasi. Sehingga menyulitkan ASP untuk membuat aplikasinya. Walaupun saya bukan salah seorang dari ASP yang ada tapi saya tau sekali hal ini. Dengar-dengar proyek ini sudah berlangsung lama, lebih dari setahun dan hingga saat ini belum satu pun ASP yang benar-benar siap untuk menjual produk/layanannya ke masyarakat, padahal eFiling ini sudah diluncurkan oleh Presiden.

Tapi saya bukan ingin mengomentari proyek tersebut. Saya hanya memberikan highlight bahwa dalam pembangunan web service yang melibatkan banyak pihak yang menggunakannya masalah interoperability, dokumentasi dan keamanan sangatlah penting.

Implementasi web service ini cukup baik dilihat dari segi keamanan (security). eFiling menerapkan user authentication, XML-Encryption, XML Digital Signature (XML-Dsig), dan menggunakan SSL (HTTPS) dengan koneksi dedicated (antara ASP dan Dirjen Pajak). Keempat hal tersebut sudah cukup untuk membuat web service cukup aman.

User authentication yang digunakan adalah dengan mekanisme login menggunakan username dan password. XML-Encryption dan XML-DSig, karena standar yang umum/bebas dan gratis sudah banyak diimplementasikan. SSL dengan authentikasi sertifikat juga hal yang sudah biasa didunia web. Tapi sayangnya eFiling menggunakan DIME (Direct Internet Message Encapsultion) untuk mekanisme attachment pada SOAP. DIME adalah standar Microsoft, pernah disubmit ke IETF tapi tidak pernah menjadi RTF. Mekanisme attachment untuk web service, kita bisa menggunakan standar SOAP with attachments (Sw/A).

Implementasi web service client untuk eFiling ini akan sangat sulit jika kita ingin menggunakan PHP. Ini karena PHP tidak memiliki library yang memadai untuk standar-standar web service (WS-*). Setelah bersusah payah mencari-cari dengan google, akhirnya didapatkan NuSOAP sebagai kandidat utama untuk mencoba implementasi web service client untuk eFiling. Kenapa NuSOAP, karena library ini support koneksi dengan SLL dan authentication dengan digital certificate. Tapi ternyata NuSOAP tidak mendukung XML-Encryption dan XML-DSig dan DIME. Library PHP PEAR::SOAP mendukung DIME attachment dengan package DIME_Attachment tapi sayangnya tidak support authentication dengan digital certificate.

Tidak adanya library untuk XML-Encryption dan XML-DSig membuat aplikasi PHP harus dibuat saling beroperasi dengan aplikasi yang dibuat dengan bahasa lain yang memiliki library untuk kedua fungsi tersebut.

NuSOAP yang digunakan juga perlu mengalami perubahan untuk bisa sukses digunakan ketika authentication menggunakan digital certificate. Dibawah ini contoh code PHP menggunakan library nusoap.er.php (NuSOAP yang sudah dimodifikasi, saya akan upload code ini lain waktu) :
<html>
<head>
<title>DJP SOAP test</title>
</head>
<body>
<?
require_once('nusoap.er.php');

$soapclient = new soapclient('https://eFiling:1208/certReqWs/RegistrationService.asmx?WSDL','wsdl');

$username="";
$password="";
$certparams = array('cainfofile' => '/home/ejlp/htdocs/.cert/CADJP.cert',
'sslcertfile' => '/home/ejlp/htdocs/.cert/korupsipajak.cert.pem',
'sslkeyfile' => '/home/ejlp/htdocs/.cert/korupsipajak.key.pem',
'passphrase' => 'password');
$soapclient->setCredentials($username,$password,'certificate', $certparams);
ini_set("soap.wsdl_cache_enabled", "1");
$soapclient->create();

$err = $soapclient->getError();
if ($err) {
echo '<p><b>Create soapclient error: ' . $err . '</b></p>';
}

$proxy = $soapclient->getproxy();
$params = array( 'UserName' => 'test' , 'Password' => 'testpassword');
$results = $proxy->GetNPWP($params);

echo '<h3>Request:</h3> <xmp>'.$proxy->request.'</xmp>';
echo '<h3>Response:</h3> <xmp>'.$proxy->response.'</xmp>';
echo '<h3>Debug:</h3> <xmp>'.$proxy->debug_str.'</xmp>';
?>
</body>
</html>

Thursday, March 03, 2005

XML Signature

XML digital signature (XMLDsig) merupakan standar untuk memberikan digital signature pada data/dokumen xml.

XMLDsig merupakan rekomendasi dari W3C dan sudah mulai banyak digunakan pada web service sebagai salah satu standar untuk keamanan.

Dengan memberikan digital signature, data/dokumen xml dapat diverifikasi kebenarannya serta integritas datanya terpercaya.

XML digital signature adalah data signature dalam format xml yang distadarisasi. Karena formatnya xml dan jika digunakan untuk dokumen xml maka XML digital signature dapat ditempatkan dengan 3 macam cara yaitu:

1. Enveloped - Signature berada --sebagai element-- pada dokumen yang di tandai (signing)
2. Enveloping - dokumen XML yang di-signed berada didalam signature element
3. Detached - Signature berada terpisah dari signed data

Struktur XMLDsig adalah sebagai berikut:
  • SignedInfo: Isi yang di-sign
  • SignatureValue: Signed value
  • SignatureMethod: Algoritma yang digunakan mengkonvesi data yang dikanonikalisasi (canonicalized contents) kedalam bentuk SignatureValue
  • KeyInfo: Information key yang digunakan untuk validasi (opsional)
Catatan: Canocalization (C14N) adalah standar algoritma untuk memverifikasi kesamaan dokumen XML walaupun mungkin dua dokumen XML berbeda jika dibandingkan secara teks. Algoritma ini diperlukan untuk digital signature sedemikian sehingga dari dokumen XML yang kanonikal (sama) jika dilakukan hashing akan didapatkan hash value yang sama. Hash value tersebut akan menjadi informasi integritas data yang di-sign.

bersambung...

http://www.w3.org/Signature/

Saturday, February 26, 2005

Inductive User Interface

Inductive User Interface (IUI) diperkenalkan Microsoft, lihat disini artikel lengkapnya, katanya IUI adalah model user interface baru yang menyarankan bagaimana membuat aplikasi-aplikasi software menjadi lebih sederhana dengan memecah menjadi beberapa screen atau halaman sehingga mudah dijelaskan dan dimengerti.

IUI bisa dibilang lebih seperti web-sytle application karena merupakan desain interface yang fokus pada single task (satu pekerjaan) sehingga memudahkan user untuk mengetahui apa yang harus dilakukan dan apa yang dilakukan selanjutnya. Hmm.. pasti kita berfikir ini seperti wizard ya?

IUI design guidelines meliputi :
  1. Setiap screen fokus pada satu pekerjaan.
  2. Jelaskan atau deskripsikan pekerjaan tersebut. Gunakan judul yang baik/mudah jika perlu berikan deskripsi tentang pekerjaan pada screen tersebut.
  3. Buat bagian-bagian yang mengisi screen nyaman untuk pekerjaan tersebut. Pilih control/komponen yang tepat.
  4. Berikan link ke pekerjaan berikutnya
Menurut saya, dilihat dari contoh-contohnya desain IUI memang sangat mirip dengan web application, terutama dari segi artistik, penempetan menu dan deskripsi dari suatu task dalam satu halaman. Karena lebih artistik dibanding desain widget/window desktop yang biasa, IUI lebih menarik untuk dilihat.

Tapi apakah kemudahan menjadi salah satu tujuan utama desain UI? Salah satu aspek yang tidak kalah penting adalah aspek produktifitas. Komentar Inductive vs Productive UIs membuka mata kita juga bahwa produktifitas penggunaan aplikasi adalah penting juga selain kemudahan.

Lihat komentar selajutnya dari penulis artikel IUI tersebut.

Code Coverage: Seberapa menyeluruh tes yang dilakukan?

Setelah kita melakukan unit test pada kode program kita, akan timbul perasaan percaya diri jika test yang kita lakukan berhasil (sukses) semua. Tapi muncul pertanyaan, apa unit test yang kita buat sudah menyeluruh sehingga kemungkinan untuk error (adanya bug) kecil sekali?

Pengenalan tentang code coverage bisa dibaca disini atau baca artikel yang agak detail "Introduction to Code Coverage" . Berapa artikel tentang code coverage dan detail teknik pengecekan coverage tool bisa didapatkan di halaman ini.

Code coverage, secara sederhana dapat dikatakan sebagai pengukuran terhadap hasil tes yang telah dilakukan. Seberapa menyeluruh? Apakah ada kode yang belum ditest? Nah, code coverage menjawab pertanyaan2 itu. Dengan code coverage tool yaitu software untuk membantu secara otomatis melakukan code coverage, kita akan mendapatkan summary dari analisis seberapa baik atau mnyeluruhnya test yang kita lakukan. Code coverage tool melakukan tes pada kode program kemudian membandingkannya dengan tes yang telah kita lakukan. Beberapa metode dilakukan oleh tool untuk mengecek apakah suatu statement, blok, fungsi atau methode sudah dites atau belum. Beberapa metode yang umum dilakukan oleh code coverage diantaranya:
  • Statement coverage/line coverage,
  • Basic block coverage,
  • Decision coverage/branch coverage
  • Condition coverage
  • Multiple condition coverage
  • Path coverage
  • Function coverage
  • Relational operator coverage
Artikel lain yang bagus, banyak menjelaskan metode-metode yang pengukuran dapat dibaca di artikel Code Coverage Analysis.

Kesimpulannya, coverage tool hanya sebatas tool, 100% coverage dari hasil analisis tool merupakan persentase menyeluruhnya sangatlah relatif. Tentu saja masih diperlukan critical thinking dalam mengalisis kode program kita, mensimulasikan kemungkinan2 error dan masih perlu test lain seperti performance testing.


Di artikel "Java Code Coverage Tools Evaluation" kita bisa baca evaluasi beberapa java coverage tool, dan kesimpulan pada artikel tersebut Emma and Clover adalah yang terbaik diantara yang lain.

Lihat juga list coverage tool open source untuk Java

Friday, February 25, 2005

CVS statistik report

StatCVS berguna untuk membuat report HTML dari CVS repository. Kita dapat melihat grafik-grafik statistik aktifitas pada repository, seperti:
  • Grafik lines of code (LOC) per-waktu
  • Persentase LOC per-author
  • Repository-directory/package tree
  • LOC dari masing-masing repository-directory/package
  • LOC per-author per-waktu
  • Rangkuman aktivitas (commits) per-jam dalam sehari
  • Rangkuman aktivitas (commits) per-hari dalam seminggu
  • Aktifitas (commits) masing-masing author per-tanggal
  • perbandingan modifying vs Adding dari masing-masing author
  • Juga dapat diintegrasikan dengan program CVS viewer/browser seperti : viewCVS, cvsweb, atau Chora

Download cvsnt dari http://cvsnt.org lalu install
Download statcvs dari http://statcvs.sourceforge.net

Misalkan user cvs adalah ejlp dan CVS server kita adalah 3.219.189.99 dengan repository path-nya adalah C:/project

Login ke CVS server

D:\myproject1>cvs -d:pserver:ejlp@3.219.189.99:C:/project login

Check out project dari CVS server

D:\myproject1>cvs -d:pserver:ejlp@3.219.189.99:C:/project co myproject1

Buat log file dari CVS

D:\myproject1>cvs -d:pserver:ejlp@3.219.189.99:C:/project log > logfile.txt

Buat direktori tempat output dari statcvs

D:\myproject1>mkdir cvssummary

jalankan statcvs

D:\myproject1>java -jar D:\statcvs-0.2.2\statcvs.jar -output-dir cvssummary -title "My Project 1" logfile.txt D:\myproject1StatCVS - CVS statistics generation

Jika tidak ada error kita akan kembali ke command prompt. Selasai, tinggal kita lihat hasilnya di direktori cvssummary. Click file index.html

Lihat dokumentasinya untuk command line arguments yang lebih lengkap.

Tuesday, February 22, 2005

Web service: standar baru untuk optimasi SOAP

- W3C XML Schema specification mensyaratkan binary data pada XML untuk diencode menggunakan base64 atau hexadecimal. Base64 encoding membuat data membesar 50%, sedangkan hexadecimal encoding memperbesar dua kalinya.

- SOAP menggunakan format XML sehingga binary data dapat diikutkan dengan menggunakan encoding. Tapi encoding binary data akan membuat file menjadi lebih besar sehingga tidak efektif karena memakan space, bandwith serta menambah proses encoding/decoding.

- Binary data dalam SOAP message bisa direpresentasikan dalam format byte array, dengan menggunakan tipe xsd:hexBinary atau xsd:base64Binary. Tapi Implemantasi SOAP biasanya tidak mendukung format byte array yang besar.

- Transfer binary data juga bisa dilakukan dengan SOAP with attachments (Sw/A), yang merupakan extension dari standar SOAP 1.1. Sw/A menggunakan MIME multipart/related message seperti pada attachement email, biasanya menggunakan base64 encoding.

- W3C membuat standar untuk mengoptimalisasi transmisi paket SOAP dengan standar XML-binary Optimized Packaging (XOP), SOAP Message Transmission Optimization Mechanism (MTOM), dan Resource Representation SOAP Header Block (RRSHB).

- XOP membuat encoding binary data pada dokumen XML menjadi lebih efisien. XOP bekerja pada level XML Information Set (Infoset) sehingga representasi abstrak dari XML dokumen dapat dapat diserialisasi (deserialize) dengan cara yang berbeda-beda.

- MTOM mendefinisikan bagaimana XOP dapat ditransmisikan dengan optimal menggunakan SOAP message. MTOM bisa menjadi solusi pengganti SOAP with Attachments (Sw/A) yang tidak di support oleh Microsoft sampai saat ini.

- RRSHB mendefiniskan bagaimana SOAP client dapat menggambil data dari original resource atau dari cache (local data) sehingga tidak perlu adanya transmisi lewat network.

- Karena ke-3 recomendation W3C tersebut baru dirilis 25 January 2005, jadi belum ada implementasi library untuk itu. Mungkin dari BEA, IBM atau Microsoft akan segera merilis library untuk memudahkan kita melakukan implementasi karena ketiga perusahaan tersebut yang banyak meberpartisipasi pada ke-3 recomendation tersebut.

- Ke-3 recomendation ini akan jadi next standar web service baru selain standar SOAP baru, SOAP 1.2

Monday, February 21, 2005

Java: Tutorial menggunakan testing framework dengan JUnit

JUnit: Pengalaman pertama

Hari ini saya mencoba menggunakan JUnit test, unit testing framework untuk Java. Awalnya dari extreme programming, saya tau mengapa unit test begitu penting. Jadi sudah tau JUnit sudah lama tapi tidak pernah sampai mencoba menggunakannya karena merasa tidak ada waktu dan tidak dibutuhkan, selain itu proyek-proyek yang salakuakan biasanya memiliki time frame yang ketat artinya bukan sekedar waktu yang sangat sempit bahakan bisa dibilang sebenarnya proyek tidak bisa selesai dengan jangka waktu yang ditetapkan. Jadi prosedur testing sering kali dilakukan berbarengan dengan waktu development atau tidak ada fase testing yang cukup sehingga kualitas produknya rendah dan sering terjadi kesalahan pada saat sistem/program telah masuk masa production. Saya kira ini sering terjadi di proyek IT di Indonesia, yang tingkat korupsinya masih tinggi dan pengharaan waktunya kurang.

Pengalaman pertama yang memaksa saya melakukan unit testing adalah, database development saya ngaco (tidak bisa digunakan) ketika saya sedang melakukan bug fixing. Setelah bug di-fix, tentu saja saya tidak bisa melakukan testing di mesin production maka saya melakukan simulasi (tes) dengan menggunakan JUnit dan beberapa mock object sehingga testing bisa dilakukan tanpa perlu koneksi ke database. Sekarang saya akan menjelaskan sedikit tentang bagaimana menggunakan Junit untuk unit tes, tentu saja ini hanya sebuah artikel contoh penggunaan yang tidak menyeluruh.

Pertama download Junit framework di JUnit.org, kemudian simpan jar file di CLASSPATH

Kemudian mualailah coding class untuk testing. Class untuk testing tersebut akan memiliki format seperti ini:

import junit.framework.TestCase;

public class NamaClass_Test extends TestCase {
public NamaClass_Test(String name) {
super(name);
}

public void testSesuatu() {
// assert disini
}

public void testSesuatuLagi() {
// assert disana
}

public void testSesuatuLainnya() {
// assert dimana-mana
}
}

Unit class test yang kita buat harus merupakan child dari class junit.framework.TestCase, didalam unit class test tersebut kita dapat meng-override method setUp() untuk meletakan inisialisai varibel atau proses tertentu, dan meng-override method tearDown() untuk menyimpan bagian-bagian yang harus dieksekusi setelah test dalam class tersebut selesai, misalnya menutup koneksi ke database.

Jangan gunakan constructor untuk menginisialisasikan sesuatu yang akan ditest, gunakanlah setUp(), karena jika terjadi error akan menghasilkan error message yang tidak informatif yaitu unit.framework.AssertionFailedError: Cannot instantiate test case ...

Selain itu kita dapat membuat method-method public tanpa return value (void) dengan awalan test untuk meletakan kode testing kita.
Didalam method test yang kita buat, kita melakukan assertions (kamus: to state or express positively) yaitu membandingkan hasil aktual dengan hasil yang diharapkan (expected).

assertEquals(...)
assertTrue
(...)
assertFalse(...)
assertNull(...)
assertNotNull(...)
assertSame(...)
assertNotSame(...)
fail(...)

Lihat dokumentasi untuk lebih jelasnya mengenai method-method diatas. Method assert diatas pada umumnya memiliki argumen (expected_result, actual_result) atau (Pesan_Kesalahan, expected_result, actual_result). Jika hasil expected_result sama actual_result maka JUnit akan mengganggap test sukses.
perhatikan method dengan assertion berikut ini:

public void testSesuatu() {
SomethingVO someVO = (new BusinessClass()).transferToManager(99);
assertEquals(
"SomethingVO tidak bisa ditransfer",
new SomethingVO("Something No 99"),
someVO);
}

Pada contoh diatas JUnit akan mengecek apakah result object someVO sama dengan expected object SomethingVO("Something No 99"), jika sama maka kita dapat mengatakan method transferToManager lulus tes.

Dengan menggunakan banyak method berawalan test dalam satu class, kita megumpulakan satu fungsional test dalam satu class dan kita akan dapat dengan mudah meng-execute semua method-method tersebut dengan cara membuat method main seperti ini:

public static void main(String[] args) {
TestRunner.run(NamaClass_Test.class);
}

Contoh output jika class tersebut di-execute adalah :

There were 2 failures:
1) testSesuatu(com.test.NamaClass_Test)junit.framework.AssertionFailedError: Sesuatu is NOT accepted
at com.test.CaseWorklistTest.testTransferToCollector(NamaClass_Test.java:76)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at com.test.NamaClass_Test.main(NamaClass_Test.java:174)
2) testSesuatuLagi(com.test.NamaClass_Testjunit.framework.AssertionFailedError: Sesuatu is already assign
at com.test.NamaClass_Test.testAssign(NamaClass_Test.java:106)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at com.test.NamaClass_Test.main(NamaClass_Test.java:174)

FAILURES!!!
Tests run: 3, Failures: 2, Errors: 0

Nah, kita bisa lihat ada 3 tes yang telah run, ada 2 assertion failure dan 0 error.

JUnit memberikan beberapa cara yang dapat dilakukan untuk mengeksekusi class TestCase, kita bisa membuat main method seperti diatas atau bisa menggunakan GUI tool

java -classpath D:\junit3.8.1\junit.jar junit.swingui.TestRunner NamaClass_Test

Kita dapat mengelompokan beberapa TestCase menjadi satu group/suite dengan menggunakan class TestSuite. Dengan TestSuite, kita dapat menjalankan banyak TestCase sekaligus dan bahkan menggabungkan atau menjalankan beberapa TestSuit sekaligus.

public class SuitSuiw_Test() {
public static Test suite ( ) {
TestSuite suite = new TestSuite();

// Tambahakan dua buah TestCase bernama NamaClass0_Test dan NamaClass1_Test
// dan sebuah TestSuit bernama NamaClass2_Test
suite.addTest(new NamaClass0_Test("testMoneyEquals"));
suite.addTest(new NamaClass1_Test("testSimpleAdd"));
suite.addTest(new NamaClass2_Test().suite());
}
}

Kemudian buatlah main method untuk eksekusi

public static void main (String[] args) {
junit.textui.TestRunner.run( suite() );

// Gunakan statement dibawah ini untuk hasil dengan GUI
//junit.swingui.TestRunner.run( suite() );
}

Selesai..

Sunday, February 20, 2005

Smart Value Object (SVO)

Kita biasanya menggunakan pattern Value Object atau Transfer Object, yaitu membuat object yang hanya properties untuk menyimpan nilai-nilai.
Object tersebut berguna untuk menghubungkan antar layer dalam arsitektur J2EE, misalnya antar presentation layer dengan business, atau business layer dengan data layer, interaksi client dengan server.

SVO dibuat dengan tujuan mempermudah tracking pengubahan pada bussines object (VO) dengan menggunakan byte code processing untuk pengecekan adanya perubahan pada VO tersebut.

Jika VO mengalami perubahan maka kita tinggal mengirimkan VO tersebut ke object Mediator yang berperan sebagai pemroses modifikasi data (misalnya input/update/delete ke database). Mediator juga akan berperan sebagai pendeteksi jika ada concurrent access, sehingga terhindar dari synchronization problem. Mediator adalah sebuah Interface yang implementasinya berbeda-beda sesuai dengan data layer.

Konsep SVO bisa dilihat di gambar berikut:



SDO menggunakan pengecekan secara byte code terhadap VO, sehingga VO yang kita buat seperti layaknya VO biasa, tidak ada penambahan code apapun untuk mejadi bagian dalam SVO.

Contoh code SVO :

TestVO test = new TestVO();
test.setId(new Long(0));
TestVO result = myMediator.getGraph(test);
result.setName("new");
myMediator.updateGraph(result);
result.setName("new2");
// try to do a second update without obtaining the last version first
myMediator.updateGraph(result); // will throw ConcurrencyException


Deskripsi lengkap tentang SVO bisa di lihat di websitenya. SVO menggunakan BSD license.

Thursday, February 17, 2005

Java: Penggati standar class untuk waktu/tanggal dan kalender

Beberapa base class standar Java tidak disukai oleh developer karena beberapa masalah. Seperti Java Collections Framework, kita bisa menggunakan alternatif Commons Collection sebagai replacementnya.

Katanya penggunaan java.util.Date dan java.util.Calendar dari Sun JRE juga tidak bagus karena beberapa masalah seperti lambat, masalah synchronization, sulit digunakan untuk perhitungan waktu dan lain-lain. Karena itu kadang orang membuat function sendiri dengan perhitungan yang simple untuk kalkulasi waktu/tanggal bahkan beberapa project open source membuat library sendiri sebagai replacement dari standar Date/Calendar API Java.

Informasi yang cukup bagus tentang ini, bisa dilihat di halaman CalendarDate project.

Link dibawah ini beberapa project free java library untuk keperluan tanggal/waktu dan kalender :

Saturday, February 12, 2005

JCE provider

Dua Java Cryptography Extension (JCE) provider ini free of charge dan lisensinya simpel:

Java: Oracle Collection Object

Ini pengalaman partner saya. Dia bikin oracle object seperti ini:

CREATE OR REPLACE
TYPE T_SOMETHING AS OBJECT
(
PK_SOMETHING NUMBER,
SOMETHING VARCHAR2(10)
);
/

Kemudian dia bikin collection dari object tersebut:

CREATE OR REPLACE
TYPE "T_COLL_SOMTHING" AS TABLE OF T_SOMETHING;
/

Collection object tersebut digunakan sebagai return dari sebuah oracle function

CREATE OR REPLACE FUNCTION GET_SOMETHING(a_date DATE)
RETURN T_COLL_SOMTHING
IS
...
...
...dihapus...

Yang membuat pusing adalah, di develompent server (embedded WAS di WSAD 5.1.0/JRE1.3) code java dibawah ini menghasilkan nilai hexadesimal.

CallableStatement cs = conn.prepareCall("BEGIN ? := get_something( ? ); END;");
cs.registerOutParameter(1, Types.ARRAY, "T_COLL_SOMTHING");
cs.setDate(2, currDate);
cs.execute();

Array res = cs.getArray(1);
rs = res.getResultSet();

while (rs.next()){
java.sql.Struct struct = (java.sql.Struct)rs.getObject(2);
Object[] objectArray = struct.getAttributes();
String s = (String)objectArray[1];
System.out.print(s);
}

Jika varibel string "s" dikonversi dari hexa ke kode ascii, didapatkan hasil yang diinginkan.

URL dari google ini http://forums.oracle.com/forums/thread.jsp?forum=99&thread=228159&message=640498
menyarankan untuk menambahkan nls_ charset12.zip di classpath.

Tapi tampaknya nls_ charset12.zip tidak memecahkan masalah. Di production server (WAS 5.1/JRE 1.4.2 dengan menggunakan embedded data source) menghasilkan karakater "???"

Saya coba seperti ini :
     oracle.sql.STRUCT struct = (oracle.sql.STRUCT)rs.getObject(2);
Datum[] objectArray = struct.getOracleAttributes();
String s = ((oracle.sql.CHAR)objectArray[1]).getString();
System.out.print(s);
hasilnya adalah
java.sql.SQLException : Non supported character set: oracle-character-set-178
Bagaimana ini?

Saturday, February 05, 2005

Web service: standar dan organisasi

W3C develops interoperable technologies (specifications, guidelines, software, and tools) to lead the Web to its full potential. W3C creates a final specification or set of guidelines called Recommendation.

SOAP (Simple Object Access Protocol), WSDL (Web Services Description Language), UDDI (Universal Description, Discovery and Integration), XML (EXtensible Markup Language), XML Schema

OASIS is a not-for-profit, international consortium that drives the development, convergence, and adoption of e-business standards. Final realease of their standard called OASIS Standard.

OASIS Standards are approved within an OASIS Committee, submitted for public review, implemented by at least three organizations, and finally ratified by the Consortium's membership at-large.

WSRP (OASIS Web Services for Remote Portlets), WSS (Web Services Security),UDDI Specification, WSRM (Web Services Reliable Messaging)

WS-I is an open industry organization chartered to promote Web services interoperability across platforms, operating systems and programming languages.

WS-I makes :
  • Profiles provide implementation guidelines for how related Web services specifications should be used together for best interoperability.
  • Sample Applications demonstrate Web services applications that are compliant with WS-I guidelines.
  • Testing Tools are used to determine whether the messages exchanged with a Web service conform to WS-I guidelines.
Basic Profile 1.1, Simple SOAP Binding Profile 1.0, Attachments Profile 1.0

Oracle: Hati-hati dengan data NULL

Jika kita jalankan procedure dibawah, apa yang akan kita dapatkan?

CREATE OR REPLACE PROCEDURE example AS
init NUMBER;
result NUMBER;
BEGIN
init := 25;
result := init + NULL;
dbms_output.put_line('Result = '|| result);
END;

Suatu operasi aritmetika pada varibel not null dengan varibel null, hasilnya null.

Apa yang kita dapatkan jika kita menjalankan query dibawah ini dan field column1 pada tabel my_table memiliki data NULL?

SELECT * FROM my_table WHERE column1 <> 0;

Kita tidak mendapatkan record yang column1 berisi NULL.

Karena saya bukan DBA atau database programmer, sempat juga membuat kesalahan . Jadi hati-hati dengan NULL. Baca Oracle "PL/SQL User's Guide and Reference" bagian Expressions and Comparisons, Handling Nulls:
  • comparisons involving nulls always yield NULL
  • applying the logical operator NOT to a null yields NULL
  • in conditional control statements, if the condition yields NULL, its associated sequence of statements is not executed

Oracle: Membuat synonym

Kadang kita perlu mempunyai user lain yang memiliki otoritas/role yang lain untuk mengakses suatu schema. Misalnya saja kita butuh user yang memiliki hak akses read only pada suatu schema.

Misalkan kita buat user FOO adalah user yang memiliki akses read only ke schema BAR. User A akan kerepotan dalam mengakses object di schema BAR, karena setiap dia akan mengakses object di schema BAR maka harus menuliskan BAR.NAMA_OBJECT.

Untuk memudahkannya kita bisa buat sysnonym dari table, view, procedure, function dan package object yang ada di schema BAR untuk si FOO.


set heading off;
set linesize 200;
set feedback off;

spool c:\create_synonym.sql

SELECT 'CREATE SYNONYM ' || object_name || ' FOR ' || owner ||'.'|| object_name || ';' script
FROM all_objects
WHERE owner = 'BAR'
AND object_type IN ('PROCEDURE','FUNCTION','TABLE','VIEW','PACKAGE');

spool off;

Thursday, January 27, 2005

PHP: PEAR and PEAR::SOAP instalation. Quick start

Install PEAR

Download file go-pear.php from http://go-pear.org/ and placed in php installation directory, example c:\wamp\php

Open command line editor and type

C:\wamp\php>php go-pear.php

After PEAR installed then type

C:\wamp\php>pear install Mail_Mime HTTP_Request Net_URL Net_DIME SOAP

If you are behind the firewall then you will get

Warning: fsockopen(): unable to connect to pear.php.net:80 (Unknown error) in RP
C.php on line 464
XML_RPC_Client: Connection to RPC server pear.php.net failed

It happened because you haven't set your proxy. You can see your PEAR configuration by typing

C:\wamp\php>pear config-show
CONFIGURATION:
==============
PEAR executables directory bin_dir C:\wamp\php
PEAR documentation directory doc_dir C:\wamp\php\pear\docs
PHP extension directory ext_dir C:\php5
PEAR directory php_dir C:\wamp\php\pear
PEAR Installer cache directory cache_dir C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\pear\cache
PEAR data directory data_dir C:\wamp\php\pear\data
PHP CLI/CGI binary php_bin c:\wamp\php\php.exe
PEAR test directory test_dir C:\wamp\php\pear\tests
Cache TimeToLive cache_ttl 3600
Preferred Package State preferred_state stable
Unix file mask umask 0
Debug Log Level verbose 1
HTTP Proxy Server Address http_proxy
PEAR server master_server pear.php.net
PEAR password (for password
maintainers)
Signature Handling Program sig_bin c:\gnupg\gpg.exe
Signature Key Directory sig_keydir C:\WINNT\pearkeys
Signature Key Id sig_keyid
Package Signature Type sig_type gpg
PEAR username (for username
maintainers)

Set http_proxy varible configuration :

C:\wamp\php>pear config-set http_proxy http://3.193.197.2:8080

After that try to install required and SOAP package again

C:\wamp\php>pear install Mail_Mime HTTP_Request Net_URL Net_DIME SOAP
downloading Net_URL-1.0.14.tgz ...
Starting to download Net_URL-1.0.14.tgz (5,173 bytes)
.....done: 5,173 bytes
No release with state equal to: 'stable' found for 'SOAP'

The SOAP package is not stable yet. You need to set your prefered
package state to beta if you want to use this package.

C:\wamp\php>pear config-set preferred_state beta

C:\wamp\php>pear install Mail_Mime HTTP_Request Net_URL Net_DIME SOAP
downloading Mail_Mime-1.2.1.tgz ...
Starting to download Mail_Mime-1.2.1.tgz (15,268 bytes)
.....done: 15,268 bytes
downloading HTTP_Request-1.2.4.tgz ...
Starting to download HTTP_Request-1.2.4.tgz (13,212 bytes)
...done: 13,212 bytes
downloading Net_URL-1.0.14.tgz ...
Starting to download Net_URL-1.0.14.tgz (5,173 bytes)
...done: 5,173 bytes
downloading Net_DIME-0.3.tgz ...
Starting to download Net_DIME-0.3.tgz (6,740 bytes)
...done: 6,740 bytes
downloading SOAP-0.8.1.tgz ...
Starting to download SOAP-0.8.1.tgz (69,177 bytes)
...done: 69,177 bytes
install ok: Net_DIME 0.3
install ok: Mail_Mime 1.2.1
install ok: Net_URL 1.0.14
install ok: HTTP_Request 1.2.4
install ok: SOAP 0.8.1


After PEAR::SOAP installed sucessfuly, try to use PEAR::SOAP library for web service client

<?
require_once 'SOAP/Client.php';
$wsdl_url = 'http://soap.amazon.com/schemas3/AmazonWebServices.wsdl';
$proxyParams = array('proxy_host' => '3.193.12.2','proxy_port' => 8080);
$WSDL = new SOAP_WSDL($wsdl_url);
$client = $WSDL->getProxy();
$params = array(
'manufacturer' => "O'Reilly",
'mode' => 'books',
'sort' => '+title',
'page' => 1,
'type' => 'lite',
'tag' => 'trachtenberg-20',
'devtag' => 'XXXXXXXXXXXXXX',
);
$books = $client->ManufacturerSearchRequest($params);
?>


Some Links/Tutorial on PEAR::SOAP implemantation :
A PHP Web Services Client
PEAR::SOAP Server Quick Start
PEAR::SOAP Client Fast Start

Wednesday, January 26, 2005

Software instalasi Apache + MySQL + PHP + lain-lain pada Windows

Sebenarnya instalasi Apache + MySQL + PHP pada sistem operasi Windows cukup mudah, tapi agak ribet karena kita biasanya ingin cepat dan tidak mau report untuk edit-edit file konfigurasi. Beberapa tools untuk instalasi Apache + MySQL + PHP + lain-lain pada sistem operasi Windows yang mempermudah/mempercepat dilist dibawah ini dan dikomentari sedikit

WAMP
Bagus (+++), instalasinya mudah, memiliki service manager dan memiliki cukup add-on yang biasa diperlukan. Versi terbarunya mempaketkan Apache1.3, PHP5, MySQL4, PHPmyadmin, SQLitemanager. Jika kita perlu Apache2, PHP4, Perl, Zend optimizer ataupun webalizer, kita dengan mudah bisa menginstal add-on-nya.

phpdev
Bagus dan inovatif (+++), sayangnya untuk uninstalnya tidak bisa sekali klik, kita harus delete manual file-filenya. Software ini membundel Apache 1.3, Apache 2, PHP4, MySQL4, phpmyadmin, AnalogX php.ini configurator, PHP-GTK 0.51, PhpWebsite. Yang menjadi nilai lebih adalah software ini dibuat dengan PHP (kecuali installernya menggunakan NullSoft) dan memberikan aplikasi PHP untuk desktop dengan menggunakan PHP-GTK baik itu aplikasi yang sekedar contoh-contoh dan juga aplikasi network tools seperti ping, tracet, dll.

XAMPP
Cukup bagus (++) dan up todate tapi instalasi dilakukan pada command prompt (text-based), memiliki beberapa add-on yang bisa kita tambahkan seperti Perl(mod_perl), Python(mod_phyton) bahkan Tomcat dan Cocoon.

easyphp
Bagus (++), tapi karena buatan orang Perancis jadi untuk default instalasi dan tools configurasinya pun dalam bahasa Perancis. Software ini mempaket PHP 4 Apache 1.3 danMySQL 4. Versi terbarunya mungkin akan menggunakan Apache 2 dan PHP 5.

PHPTriad
Kurang bagus (+). Dulu phptriad cukup populer tapi sekarang projectnya berhenti (tidak di-maintain lagi) sehingga tidak up to date. Software ini berubah nama menjadi Sokkit yang tidak gratis walaupun versi lamanya masih bisa kita download.

FoxServ
Lumayan (-). FoxServ rilis terakhir adalah versi 3.1 Beta 1 (January 16, 2003). Dari versi dan tanggal rilisnya kita bisa terlihat bagaimana foxserv tidak up to date sehingga lebih baik menggunakan lain ;)

List lengkap Apache, PHP, MySQL/database lainnya bisa dilihat di sini

Spyware tools

Spyware adalah software yang bersifat iklan (adware), menambil informasi personal, mengubah konfigurasi tanpa 'sepengetahuan' pengguna komputer. Spyware sudah seperti virus, bisa sangat mengganggu dan bahkan merusak. Gara-gara spyware biasanya Internet Explorer kita sering hang, default home address jadi tidak bisa diubah, menjadi lambat saat browsing, muncul toolbarsering tiba2 muncul pop-up windows, dan lain-lain. Biasanya orang yang awam dengan internet komputernya mudah terjangkit spyware karena berkunjung ke situs-situs porno kemudian tanpa sadar mendownload/menginstal software-software shareware tanpa membaca agreement.

Karenanya software spyware remover pun banyak dibuat. Kebanyakan tidak gratis, tapi ada juga yang freeware. Software spyware yang baik tentu saja menyediakan update spyware definition, karena spyware seperti juga virus terus bertambah. Spyware biasanya mengecek file-file cache browser atau temporary internet files, file-file cookies, windows registry.

Salah satu software spyware yang bisa jadi pilihan adalah AntiSpyware dari Microsoft. Selain bisa scan spyware yang ada di komputer, AntiSpyware juga menjaga komputer kita dari spyware. Jadi tidak sekedar scanner dan remover tapi juga prevent protection. Walaupun masih beta (25 Jan 2005) tapi software ini cukup baik dan lengkap.

AntiSpyware bisa di download http://www.microsoft.com/athome/security/spyware/software

Followers