27 January 2009

Autentifikasi Web Aplikasi pada Tomcat dengan JDBC Realms

Setelah beberapa saat yang lalu kita menggunakan session untuk melakukan validasi pada halaman jsp, kali ini kita akan mencoba membuat autentifikasi web aplikasi dengan Realm.

Pada Apache atau web server lain yang sejenis, biasanya kita menggunakan autentifikasi Realms dengan mengikutsertakan File .htaccess pada direktori dimana kita menginginkan adanya keamanan dalam direktori tersebut.

Sama halnya dengan Apache, Realm adalah suatu fitur dalam Tomcat yang berfungsi sebagai pintu autentifikasi bagi user yang ingin mengakses semua resources dalam web aplikasi yang kita buat. Realm mengatur role-role dari setiap user yang terdaftar, role-role ini menjadi sebuah acuan bagi Tomcat untuk mengatur web aplikasi mana saja yang boleh di akses oleh user-user yang telah terdaftar. Tomcat secara default telah mendukung Realm dengan sangat fleksibel. Fleksibel yang dimaksud disini adalah, Tomcat mensupport autentikasi dengan beberapa metode yang bisa kita pilih sesuai dengan keinginan kita. Metode autentikasi Realm yang didukung oleh Tomcat antara lain:

  1. Autentifikasi berdasarkan File (The Memory Realms).

Pada metode ini, autentikasi dijalankan dengan cara membaca File tomcat-users.xml yang terletak pada /conf/tomcat-users.xml, dalam file ini berisi list dari user-user dengan role-role tertentu.

  1. Autentifikasi menggunakan JDBC (The JDBC Realms).

Metode ini menggunakan database sebagai storage list user-user dan role-role yang dimilikinya. Pada Tomcat 5.5, secara default ada beberapa database yang sudah didukung untuk metode JDBC Realms ini. Untuk memakai metode ini library database seperti mysql-connector harus di install dengan cara memasukkan File jar mysql-connector ke dalam <Tomcat-Folder>/common/lib/.

  1. Autentifikasi dengan JNDI (JNDI Realms).

Pada autentifikasi ini, Tomcat akan memvalidasi user dan role-rolenya dengan cara membaca web directory service, seperti LDAP. Untuk menggunakan metode ini, library-library yang berisi provider-provider JNDI harus diinstall ke dalam <Tomcat-Folder>/common/lib/.

Dari beberapa tipe autentifikasi dengan Realm di atas, kita akan mencoba menggunakan metode yang ke dua yaitu Autentifikasi menggunakan JDBC (The JDBC Realms) sebagai percobaan kita kali ini. Kita akan menggunakan database mysql sebagai storage list dari user-user dan role-role yang dimilikinya. Sementara untuk skenario-skenario percobaan kita kali ini, kira-kira seperti dibawah ini:

  • Buat database sebagai storage yang menampung user-user dengan role-role yang dimilikinya.

  • Buat sebuah username pada mysql yang hanya bisa membaca saja pada database skenario pertama.

  • Aktifkan konfigurasi Realm dengan metode JDBC pada Tomcat.

  • Buat konfigurasi web aplikasi pada Tomcat agar bisa mendukung Realms.

Pada skenario-skenario diatas, sebenarnya dari langkah 1 sampai dengan langkah 3 hanya kita lakukan sekali saja, artinya konfigurasi dari langkah 1 sampai langkah 3 akan menjadi permanen dalam environment Tomcat yang ter-install tsb. Sementara untuk langkah ke-4 sifatnya optional, artinya setiap web aplikasi yang nantinya akan kita deploy, bisa memakai autentikasi Realm ini, dan boleh juga tidak, jadi tergantung keputusan kita dalam menentukan apakah suatu web aplikasi yang kita buat akan memakai autentifikasi Realm atau tidak. Kemudian pada jika kita ingin menambahkan list user dengan role-rolenya, atau merubah role suatu user, maka perubahannya kita lakukan dari dalam database mysql.

Sekarang mari kita jalankan satu demi satu skenario diatas. Untuk skenario pertama silahkan buat database dan tabel-tabelnya pada database mysql, seperti contoh query mysql berikut ini:


create database tomcat_server;
use tomcat_server;
-- --------------------------------------------------------
--
-- Table structure for table `user_auth`
--

CREATE TABLE IF NOT EXISTS `user_auth` (
`USERNAME` varchar(30) NOT NULL default '',
`PASSWORD` varchar(30) NOT NULL default '',
PRIMARY KEY (`USERNAME`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

--
-- Dumping data for table `user_auth`
--

INSERT INTO `user_auth` (`USERNAME`, `PASSWORD`) VALUES
('admin', 'admin99'),
('mojo', '7mono7');

-- --------------------------------------------------------

--
-- Table structure for table `user_role`
--

CREATE TABLE IF NOT EXISTS `user_role` (
`ROLE_NAME` varchar(30) NOT NULL,
`USERNAME` varchar(30) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

--
-- Dumping data for table `user_role`
--

INSERT INTO `user_role` (`ROLE_NAME`, `USERNAME`) VALUES
('tomcat', 'mojo'),
('manager', 'admin'),
('admin', 'admin');

Query tsb, juga langsung bisa dijalankan dengan cara meng-copy paste langsung ke dalam mysql-console, hanya saja perhatikan nanti untuk konfigurasi selanjutnya karena kita akan memakai database dan tabel yang telah kita buat pada tahap ini.

Kita lanjutkan dengan skenario ke-dua yaitu membuat user yang hanya mampu membaca saja database ini. Kenapa harus bisa membaca saja? Kita harus berhati-hati dalam memberikan access-privileges pada user database, apalagi konteks pada Realms ini adalah berkaitan dengan access seluruh web aplikasi kita. Untuk skenario ke-dua ini sebenarnya sebagai saran saja dari saya, jika anda memang menginginkan membuat user database dengan access-privileges yang lebih luas dari pada skenario ini untuk pengembangan lebih lanjut, silahkan saja (All by your own risk). Dibawah ini adalah contoh query yang bisa mengakomodir skenario ke-dua

mysql> grant select on tomcat_server.* to 'tomcat-user'@'localhost' identified by 'tomcat55';

Pada query tsb, kita membuat sebuah user dengan nama tomcat-user dan dengan passwordnya tomcat55, grant select adalah perintah kepada database mysql supaya user tomcat-user ini hanya bisa membaca saja.

Kemudian kita masuk ke skenario ke-3, dimana dalam skenario ini kita akan mengaktifkan konfigurasi Realm dengan metode JDBC pada tomcat. Konfigurasi Realm ada pada file servlet.xml yang terletak pada folder <Tomcat-Folder>/conf/. maka kita harus mengedit File ini untuk bisa mengaktifkan Realm dengan metode JDBC. Ada dua langkah yang harus dilakukan untuk skenario ke dua ini. Dimana langkah-langkah tersebut adalah:

  • Aktifkan konfigurasi Realm.

Cari dan lakukan pengeditan servlet.xml pada bagian seperti di bawah ini:

<Realm className="org.apache.catalina.Realm.UserDatabaseRealm"
resourceName="UserDatabase"/>

Jika baris tersebut belum ada, maka silahkan tambahkan, atau bila baris tersebut ada dalam blok comment, silahkan hapus comment yang mem-blok baris ini.

  • Aktifkan dan isi konfigurasi JDBC Realm sesuai dengan skenario pertama yang tadi kita buat. Seperti contoh servlet.xml pada bagian dibawah ini:
<Realm  className="org.apache.catalina.Realm.JDBCRealm"
driverName="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost/tomcat_server"
connectionName="tomcat"
connectionPassword="tomcat55"
userTable="user_auth"
userNameCol="USERNAME"
userCredCol="PASSWORD"
userRoleTable="user_role"
roleNameCol="ROLE_NAME" />

Kita bahas sedikit sebagai review dari konfigurasi di atas, di sini kita memakai driver com.mysql.jdbc.Driver untuk mysql-drivernya, kemudian memakai user tomcat dengan password tomcat55 untuk koneksi ke database mysql sesuai dengan skenario ke dua yang kita buat tadi. Perhatikan bahwa semua value pada tahap ini kita buat sama persis dengan sql query yang kita buat pada skenario pertama.

Kemudian kita bisa jalankan skenario ke-4 yaitu menerapkan autentifikasi JDBC Realms pada web aplikasi kita. Buatlah sebuah web aplikasi, atau pakai web aplikasi kita yang memang sudah ada untuk bisa kita terapkan autentifikasi ini. Cara mengaktifkan authentifikasi ini pada web aplikasi adalah dengan cara mengedit File web.xml yang ada pada folder /webapps/<your-application>/WEB-INF/

Pengeditan dilakukan dengan cara menambah baris-baris seperti di bawah ini pada File web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">

<!--Access Configuration based on Realms-->
<security-constraint>
<web-resource-collection>
<web-resource-name>All Page</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>tomcat</role-name>
</auth-constraint>
</security-constraint>

<login-config>
<auth-method>BASIC</auth-method>
<Realm-name>Tomcat-Advance-Authentication-Realm</Realm-name>
</login-config>
……………
……………

<web-apps>

Pada baris tsb, semua autentifikasi dilakukan pada semua resources yang ada pada web-aplikasi ditandai dengan baris <url-pattern>/*</url-pattern>, kemudian untuk metode autorisasinya disini kita menggunakan autorisasi BASIC.

Demikianlah, percobaan kita kali ini, menggunakan autentifikasi JDBC Realm pada Tomcat sebagai validasi user terhadap resources web aplikasi kita. Silahkan dikembangkan sesuai dengan keinginan dan kebutuhan.


Terima kasih.

Menteng, 26 Januari 2008.

Josescalia.

26 January 2009

Beberapa Tips dan Trik pada Servlet dan Jsp

Dalam perkembangan teknologi web dengan menggunakan bahasa pemrograman Java, kita mengenal servlet dan jsp. Servlet dan Jsp hadir sebagai sebuah layer presentasi dari struktur web aplikasi yang kita buat dengan menggunakan Java. Layer presentasi adalah layer yang bertugas untuk menghadirkan tampilan-tampilan yang biasanya menjadi sebuah hasil akhir sebuah proses aliran data. Ketika memilih menggunakan servlet atau jsp sebagai sebuah layer presentasi, pastinya didasari oleh pertimbangan-pertimbangan yang matang sesuai dengan tujuan yang memang ingin dicapai.

Meski hanya sebagai sebuah layer presentasi dalam suatu aplikasi web, servlet dan jsp juga memiliki daya tarik tersendiri untuk bisa di eksplorasi dan dipergunakan dalam aplikasi web kita. Dibawah ini beberapa trik dan tips yang bisa dilakukan pada servlet dan jsp yang bisa dipakai sesuai dengan kebutuhan-kebutuhan yang ada.

1. Mengambil nilai parameter dari deployment descriptor (web.xml) pada init Servlet.

Perhatikan kode kode berikut ini:

public class SendMailServlet extends HttpServlet {
private String smtpHost;

public void init(ServletConfig config) throws ServletException {
super.init(config);
smtpHost = config.getInitParameter("smtpHost");
}
…………………………
}
Kode di atas adalah sebuah potongan kode dari sebuah servlet pengirim email. Untuk pengiriman email, proses ini jelas membutuhkan sebuah SmtpHost sebagai sebuah server untuk menghantarkan email sehingga email tsb bisa sampai ke tujuan. Untuk menghindari hard-code, nama SmtpServer di letakkan di dalam deployment descriptor(web.xml), sehingga ketika ada perubahan pada nama SMTP Server, developer tidak perlu membongkar ulang, kompilasi ulang dan mendeploy ulang aplikasinya, cukup dengan mengganti nilai dari parameter "smtpHost” pada web.xml saja dan aplikasi pun dapat berjalan kembali tanpa gangguan yang berarti.Dan tentunya dibawah ini adalah potongan kode dari web.xml dimana nilai dari parameter smtpHost tersebut diletakkan

<servlet>
<servlet-name>sendMessage</servlet-name>
<servlet-class>org.mojo.mail.web.servlet.SendMailServlet</servlet-class>
<init-param>
<param-name>smtpHost</param-name>
<param-value>smtp.speed.net.id</param-value>
</init-param>
</servlet>

Sedangkan untuk process flownya adalah, ketika pertama kali servlet ini dipanggil maka application server segera menjalankan metode init pada servlet itu, kemudian metode ini mengisi nilai variabel smtpHost dengan cara mengambil nilainya dari deployment descriptor tempat dimana servlet tsb di deklarasikan.

2. Menggunakan Interface RequestDispatcher untuk melempar suatu proses ke servlet lain.

Menjadi suatu pilihan yang menarik jika kita membuat skenario bahwa setiap servlet mempunyai masing-masing tugas yang berbeda. Misal ada servlet yang tugasnya mengirimkan email, atau servlet yang tugasnya menampilkan pesan error, dan lain-lain. Dengan skenario seperti ini, kita akan lebih mudah menelusuri error yang mungkin saja terjadi pada suatu proses, sebab masing-masing proses mempunyai modul yang berbeda.

Dengan skenario seperti ini, kita pasti membutuhkan pelemparan proses dari suatu servlet ke servlet lain.

Untuk melempar suatu proses dari satu servlet ke servlet lain kita bisa menggunakan Interface RequestDispatcher. Perhatikan kode-kode berikut ini.

public class Test1Servlet extends HttpServlet{

public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
System.out.println("doGetInvoked");
throwToServlet(req, res);
}
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
System.out.println("doPost Invoked");
throwToServlet(req,res);
}
private void throwToServlet(HttpServletRequest req, HttpServletResponse res)
throws IOException, ServletException {
System.out.println("This Process wil throw to another servlet");
RequestDispatcher rd = getServletContext().getNamedDispatcher("Test2");
rd.forward(req,res);
}
}

Pada kode class servlet diatas kita melihat ada baris

RequestDispatcher rd = getServletContext().getNamedDispatcher("Test2");

Baris ini adalah baris dimana servlet mengambil ServletContext yang terletak pada web.xml, kemudian di ikuti dengan baris

rd.forward(req,res);

dan baris ini adalah suatu baris yang memerintahkan proses data di lempar ke servlet lain yang bernama Test2.

Pada prakteknya jangan lupa untuk menambahkan servlet Test2 pada isi dari web.xml

Sementara jika pelemparannnya kita lakukan dari jsp maka barisnya akan sedikit berubah menjadi seperti dibawah ini:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
RequestDispatcher rd = getServletConfig().getServletContext().getNamedDispatcher("Test2");
rd.forward(request,response);
%>

Ada penambahan getServletConfig pada baris inisialisasi RequestDispatcher disana, dan untuk forwardnya parameter diisi dengan request dan response yang sudah secara default ditanamkan dalam jsp.

3. Menggunakan metode sendRedirect untuk melempar suatu proses ke URL lain.

Jika pada trik yang kedua kita menggunakan interface RequestDispatcher untuk melempar suatu proses ke servlet lain, pada trik yang ketiga ini kita menggunakan metode sendRedirect untuk melampar suatu proses ke URL lain. Perbedaan trik ini dengan trik kedua adalah, jika trik yang ke dua hanya melempar proses ke servlet dalam context web-app yang sama, sementara tips yang ini bisa melempar proses bukan hanya ke context-app yang berbeda tapi juga cross url atau melempar ke URL yang berbeda.

Untuk melempar suatu proses ke URL lain perhatikan kode-kode berikut ini :

public class Test1Servlet extends HttpServlet{

public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
System.out.println("doGetInvoked");
throwToURL(req,res);
}
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
System.out.println("doPost Invoked");
throwToURL(req,res);
}
private void throwToURL (HttpServletRequest req, HttpServletResponse res)
throws IOException, ServletException {
System.out.println("This Process wil throw to another URL");
res.sendRedirect("Test2");
}
}

Pada kode diatas perintah untuk melempar ke URL lain ada pada baris res.sendRedirect(“Test2”);

Dan jika kita ingin melakukannya dalam jsp, cukup dengan merubah baris res.sendRedirect menjadi response.sendRedirect saja. Sebab sekali lagi, variabel response sudah ditanamkan menjadi default ServletResponse pada type file jsp, sehingga kita tidak perlu membuat variabel untuk ServletReponse ini. Yang terakhir tentu saja url-mapping untuk Test2 ini juga harus di definisikan pada web.xml, kecuali url yang di tuju bukanlah URL yang berada pada WebAplikasi kita.

Catatan : Perbedaan antara tips ke dua dengan tips ke tiga jika dilihat dari sisi browser adalah: URL address pada tips ke-dua tidak berubah ketika proses pelemparan proses dilakukan, sementara untuk tips ke-tiga URL address pada browser akan berubah.

4. Menangani Null Value ketika memparsing parameter antar HTTP method.

Pada proses HTTP Post atau HTTP Get, jsp mem-parsing semua parameter yang dilempar dari form untuk kemudian dilakukan proses-proses selanjutnya. Terkadang ketika kita memparsing parameter pada jsp, kita sering kali menemui Null Value yang akhirnya proses data tidak bisa dilakukan karena jsp menangkap NullPointerException. Pada prakteknya Null Value terjadi karena parameter yang di parsing memang tidak membawa suatu nilai dari form feedernya. Oleh karena itu ketika jsp mem-parsing parameter tsb, maka terjadi Error NullPointerException. Untuk mencegahnya kita bisa membuat sebuah nilai default pada variabel yang nantinya akan menjadi wadah dari hasil parsing parameter.

Perhatikan kode-kode jsp berikut ini:

<%
String sId = request.getParameter("ID") == null ? "1" : request.getParameter("ID").trim();
String sName= request.getParameter("Name") == null ? "" : request.getParameter("Name");
%>

Pada kode diatas kita bisa melihat bahwa String sId akan menangkap sebuah parameter yang dilempar, parameter itu bernama ID, jika parameter ID yang dilempar mempunyai nilai Null maka secara default nilai variabel sId akan diisi dengan nilai 1, demikian juga dengan proses penangkapan parameter Name, namun variable String sName ini akan akan diisi oleh nilai “” jika parameter Name yang dilempar tidak membawa nilai.

Demikianlah beberapa Tips dan Trik pada servlet dan jsp yang menjadi pembahasan artikel ini. Semoga bermanfaat, dan silahkan dikembangkan sesuai dengan kebutuhan.

Menteng, 18 Januari 2008
Semoga Bermanfaat.

Josescalia.


20 January 2009

Windows Delayed Write Failed pada Maxtor One Touch 4 Mini

Pada tanggal 26 Desember 2008, saya membeli sebuah hard disk eksternal ber-merk Maxtor One Touch 4 Mini dengan kapasitas 160 GB dengan harga sekitar 750 ribu rupiah. Awal pertama saya gunakan hard disk eksternal ini saya sangat kecewa, ternyata barang yang saya beli tidak dapat digunakan sama sekali. Ketika kabel USB saya colokkan ke laptop, sistem operasi Windows XP yang saya gunakan pada laptop saya tidak mampu mendeteksi adanya hardware baru. Saya curiga jangan-jangan Windows XP tidak bisa membaca hardware ini. Awalnya saya pikir windowsnya yang salah.Kemudian saya mencoba menggunakan sistem operasi Linux Open Suse yang juga memang menjadi salah satu sistem operasi yang saya gunakan. Tapi ternyata saya kecewa sekali ternyata open suse pun tidak mampu membaca hard disk eksternal ini.

Dari sana saya simpulkan, jelas bukan laptop atau sistem operasi saya yang salah, ini pasti salahnya hard disk eksternal ini. Ada yang rusak atau apalah, yang jelas bukan dari laptop saya atau sistem operasi yang saya miliki. Kemudian saya memutuskan untuk mengembalikannya keesokan harinya ke toko tempat dimana saya membelinya. Sesampainya di toko, hard disk tersebut langsung diperiksa oleh teknisi-teknisi yang memang ada di toko tersebut. Dan hasilnya, saya lega, memang hard disknya yang bermasalah. Kemudian pihak toko menggantinya dengan hard disk eksternal baru yang memang sama persis dengan yang rusak tadi.

Sebelum saya membawa pulang hard disk pengganti tadi, teknisi memastikan bahwa hard disk penggantinya dalam kondisi bagus dengan cara mencobanya ke dalam komputer teknisi tsb. Dan memang hard disk pengganti ini, bagus dan dapat dipergunakan secara normal, sehingga saya setuju untuk membawanya pulang sebagai pengganti hard disk yang rusak tadi.

Sesampainya dirumah, saya kemudian mulai menggunakan hard disk tersebut untuk menyimpan data-data yang merupakan data-data penting. Karena memang itu tujuan saya membeli hard disk eksternal. Mem-back-up data-data penting jadi suatu bagian dalam kegiatan saya berkomputer.

Tadinya saya berfikir untuk membelah partisi hard disk ini menjadi dua sama rata, tapi rencana tersebut baru bisa saya lakukan dua hari setelahnya karena ada memang saya tidak memilki software yang mampu merubah partisi hard-disk. Sebelum saya membelah dua partisi hard disk tersebut, terlebih dahulu saya ingin menguji kekuatan hard disk ini. Sederhana saja, saya akan mencoba mengujinya dengan mengkopi file-file yang ada di laptop saya dengan ukuran yang sangat besar ke dalam hard disk ini. Pengujian pertama saya lakukan dengan mengkopi data sebesar 500 MB, dengan cara satu kali copy dan satu kali paste. Hasilnya lumayan, hard disk saya mampu menerima file dalam jumlah yang benar dan tidak corrupt, sebenarnya pengujian ini lebih mengacu kepada pengujian connector hard disk dalam hal ini pengujian kabel USB yang menjadi connector antara hard disk dengan komputer.

Kemudian saya mencoba mengkopi sekaligus data dengan ukuran 1 GB dari laptop ke hard disk tsb. Dan hasilnya pun masih OK, masih juga bagus, nah pada pengkopian data secara langsung sebesar 2 GB. Hard disk ini mulai mengalami masalah. Ketika data yang besarnya 2 GB dalam proses pengkopian ke dalam hardisk, dan progressnya baru mencapai 45% muncul balloon alert di sebelah kiri bawah desktop saya, “Windows Delayed Write Faileddan bla..bla..bla.. lainnya. Ternyata hard disk ini tidak mampu melakukan pengkopian data sebesar 2 GB ke-dalamnya. Kemudian saya mencoba membuang hasil kopian yang gagal tadi, alangkah kecewanya saya ternyata hasil kopian yang gagal tadi tidak bisa di delete, ketika di delete ada dialog window yang intinya memberi tahu bahwa folder atau file tersebut tidak bisa di delete. Saya mencoba mendeletenya lewat konsol windows, dan tetap tidak bisa juga di hapus. Kemudian saya coba delete dengan menggunakan sistem operasi Linux. Hasilnya pun juga sama, tetap tidak bisa di delete. Akhirnya saya biarkan saja folder dan file tsb. Mengingat besok di kantor, saya memang berencana untuk membelah dua partisi hard disk ini, jadi saya pikir biarkan saja, nanti saya format saja sehingga menjadi bersih kembali hard disk ini.

Dua hari kemudian saya membelah partisi hard disk tsb menjadi dua sama rata. Dan kemudian saya melakukan pengujian ulang lagi. Dan hasilnya saya benar-benar kecewa. Pengujian tsb gagal, hard disk ini masih mengalami kondisi windows delayed write failed tadi.

Kemudian saya format lagi, dan saya belah dua lagi hard disk tsb, dan kembali melakukan pengujian tadi sekali lagi. Tapi kali ini saya akan melakukan pengujiannya di atas sistem operasi Linux. Dan hasilnya pengujian tsb ternyata, sistem operasi Linux tidak mengeluarkan pesan error apapun, dan hasil dari pengkopian data pun menjadi normal, tidak ada satu file atau folder pun yang corrupt. Artinya di Linux pengkopian data sebesar 2 GB ke dalam hard disk ini lancar-lancar saja tidak ada error sama sekali.

Hmm saya mulai berfikir, jangan-jangan ada masalah dengan sistem operasi Windows XP untuk pengkopian data ke dalam hard disk eksternal dengan ukuran data di atas 1 GB. Saya pun mencari tahu dengan cara membrowsing websitenya Microsoft pada bagian FAQ dan bugs. Dan saya juga menelusuri website-website lain atau artikel-artikel di internet tentang masalah ini. Dari penulusuran itu saya ambil kesimpulan, ternyata memang ada beberapa masalah pada sistem cache ketika ada kegiatan pengkopian data dengan jumlah besar menggunakan sistem operasi windows. Meski jawaban-jawaban dari websitenya Microsoft sangat diplomatis, seperti menyalahkan kabel usb, menyalahkan connector dan lain-lain, saya masih tetap berpendapat memang ada masalah pada sistem cache windows pada kasus tertentu seperti kasus saya ini.

Kemudian saya mencari tahu lagi lewat penulusuran internet, kemungkinan ada orang lain mengalaim masalah yang sama dengan saya dan bagaimana cara mengatasinya. Setelah dua hari melakukan penulusuran, akhirnya saya menemukan sebuah artikel dengan masalah yang sama dan cara mengatasinya. Sayangnnya saya lupa mencatat link tsb, sehingga tidak bisa saya masukkan dalam artikel ini. Yang jelas link tersebut bukanlah dari website resmi, Microsoft atau vendor dari hard ware Maxtor ini, melainkan artikel dari orang yang juga mengalami permasalahan yang sama.

Ok langsung saja, intinya cara menanggulangi permasalan saya adalah dengan memperbesar sistem cache pada sistem operasi windows. Saya menggunakan sebuah software untuk melakukan perubahan sistem cache ini, saya mengetahui software itupun dari artikel tadi. Nama software tsb adalah Cacheman buatan Outer Technologies. Karena software ini tidak gratis, maka saya hanya menggunakan versi 5.0 karena versi ini tetap bisa digunakan meski kita tidak melakukan registrasi sekalipun.

Setelah saya install software ini, sesuai dengan petunjuk artikel di atas saya kemudian melakukan perubahan pada sistem cache sistem operasi Windows XP yang saya miliki. Setelah melakukan perubahan tsb, saya me-restart Windows XP saya dan mulai kembali melakukan pengujian terhadap hard disk ini.

Pengujian pada pengkopian data sebesar 2 GB, ternyata bagus, tidak ada error Windows Delayed Write Failed yang muncul, saya senang, kemudian saya lakukan pengkopian lagi berturut-turut dengan data yang lebih besar lagi, dan hasilnya pada pengujian pengkopian data sebesar 5 GB. Tidak mengalami masalah lagi. Saya menghentikan pengujian ini dan menganggap masalah hard disk eksternal saya sementara ini selesai.

Saya berencana untuk mengujinya selama seminggu, sebelum saya memutuskan bahwa masalah saya benar-benar selesai, dan saat artikel ini saya tulis, saya masih belum menemukan masalah lagi. Maka saya simpulkan bahwa masalah Windows Delayed Write Failed yang terjadi pada hard disk saya telah selesai, dan saya bisa menggunakan hard disk ini sebagai mana mestinya.

Berikut ini adalah tahapan-tahapan saya merubah sistem cache menggunakan Cacheman5.0 untuk mengatasi masalah ini.

Pada menu show wizard saya pilih All kemudian untuk setiap window settingnya berikut detailnya :

1.Disk Cache: pilih Balance
2.Icon Cache: pilih Set large maximum Icon Cache size
3.Unload DLLs from Memory: pilih Enable
4.Disable Paging Executive: pilih Enable
5.IO Page Lock Limit: pilih Large IO page lock limit value
6.Disable NTFS last access update: pilih Enable
7.Disable creation of short filenames: pilih Enable
8.Reserve more space for the Master File Table: tidak di enable
9.Defragment hard disk when idle: pilih Enable
10. Hung App Timeout: pilih Optimize
11. Wait to Kill App / Service Timeout: pilih Optimize
12. Menu Show Delay: pilih Optimize
13. Filename Completion: tidak di enable

Demikian setting sistem cache menggunakan Cacheman pada sistem operasi Windows XP saya untuk menanggulangi masalah Windows Delayed Write Failed yang terjadi pada Maxtor One Touch 4 Mini saya.


Menteng, 4 Januari 2009

Semoga bermanfaat

Josescalia.



01 January 2009

Mencari Bilangan Prima dengan Aplikasi Java

Suatu kali ada seseorang yang datang kepada saya dengan maksud ingin memulai belajar Java, ia banyak bertanya kepada saya masalah Java dan perkembangannya. Salah satu pertanyaan yang muncul dari salah satu cerita adalah bagaimana membuat sebuah program Java yang mampu menghasilkan deretan bilangan prima?, yang jadi masalah adalah, saya sendiri saat itu sudah lupa apa perngertian bilangan prima, sehingga kita kesulitan untuk membuat programnya. he..he..he..(alasan...!!!).

Kemarin saya teringat kejadian itu, dan segera saya googling mencari tahu pengertian bilangan prima. Dari wikipedia versi indonesia saya mendapatkan pengertian bilangan prima secara baku, kemudian saya coba memahami arti sebenarnya pengertian bilangan prima. Bilangan prima adalah Suatu bilangan asli yang dimulai dari 2, dimana bilangan ini adalah bilangan yang tidak habis dibagi dengan bilangan apapun dibawahnya kecuali dibagi dengan satu dan bilangan itu sendiri. Begitu pemahaman yang saya ambil dari pengertian bilangan prima. Mari kita coba ambil sebuah angka dan coba memeriksanya dengan pemahaman yang saya dapat, misal kita ambil angka 15, apakah angka 15 adalah bilangan prima ? Pemeriksaan kita, akan kita urutkan seperti ini :

  1. Apakah 15 lebih besar sama dengan 2 (15 >= 2 ) ?, sebab salah syarat pertama bilangan prima adalah bilangan asli yang dimulai dari 2.
  2. Apakah 15 akan habis dibagi dengan bilangan-bilangan yang dimulai dari 2 sampai dengan 14 ?, sebab syarat bilangan prima yang lain adalah bilangan yang tidak habis dibagi dengan bilangan apapun dibawahnya kecuali satu dan dirinya sendiri.

Ok kita mulai pemeriksaan kita satu demi satu, untuk pemeriksaan pada tahap yang pertama 15 lolos, artinya 15 memang lebih besar dari pada 2, kemudian kita lanjutkan dengan pemeriksaan tahao ke dua. Apakah 15 habis jika di bagi dengan 2, hasilnya 15 tidak habis di bagi dengan 2, karena 15/2= 7 dan sisa 1. Pemeriksaan kita lanjutkan dengan membagi lagi 15 dengan 3, pada pembagian yang ini 15 jelas bukanlah bilangan prima, sebab 15 dibagi dengan 3, habis, 15/3 = 5, habis tidak ada sisa. Jelas 15 bukanlah bilangan prima sebab 15 habis di bagi dengan 3.

Sekarang kita akan ambil satu bilangan lagi yaitu 17, dan kita akan coba periksa lagi dengan metode yang sama dengan ketika kita mencari bilangan prima untuk angka 15. Untuk pemeriksaan pertama bilangan 17 pasti lolos sebab 17 lebih besar dari pada 2, dan untuk pemeriksaan ke dua, kita lihat seperti gambar di bawah ini :

17 / 2 = 8 sisa 1
17 / 3 = 5 sisa 2
17 / 4 = 4 sisa 1
17 / 5 = 3 sisa 1
17 / 6 = 2 sisa 5
17 / 7 = 2 sisa 3
17 / 8 = 2 sisa 1
17 / 9 = 1 sisa 8
17 / 10 = 1 sisa 7
17 / 11 = 1 sisa 6
17 / 12 = 1 sisa 5
17 / 13 = 1 sisa 4
17 / 14 = 1 sisa 3
17 / 15 = 1 sisa 2
17 / 16 = 1 sisa 1

Pada gambar diatas, kita bisa melihat bahwa 17 itu selalu sisa jika dibagi dengan bilangan apapun dibawah bilangan 17 kecuali 1 dan 17 itu sendiri. Dari situ kita bisa simpulkan bahwa 17 adalah bilangan prima.

Bagaimana jika dengan tahap – tahap tersebut kita mencoba membuat aplikasi java yang mampu memeriksa sebuah bilangan apakah bilangan tersebut merupakan bilangan prima atau bukan. Ok, jika kita akan membuat sebuah program yang mampu memeriksa sebuah bilangan adalah bilangan prima atau bukan, seperti inilah kode-kode progamnya:

package org.mojo.blog.app.integer; //ignore this, if this program is not on package

public class isPrimeApplication {

public static void main(String[] args) {
int valueToCheck = 17; // value to check
boolean isPrime = false;
if (valueToCheck >= 2) {
isPrime = true; // first check and assume it's prime number
// try divide valueToCheck
// with all number less than it self
// and begining from 2
for (int i = 2; i < valueToCheck; i++) {
if (valueToCheck % i == 0) {
//if divides exactly so stop the loop and it must be not prime
isPrime = false;
break; // no need to check again
}
}
}
System.out.println("is " + valueToCheck + " Prime ? ");
System.out.println("the answer is " + isPrime);
}
}

Dalam kode di atas kita bisa melihat bahwa kita punya dua variabel, valueToCheck dan isPrime, sementara flow process kita buat mirip skenario tahap-tahap pengecekan, dimana :

  1. if(valueToCheck > = 2) adalah pengecekan tahap pertama, dimana semua angka yang masuk dalam blok ini akan sementara kita asumsikan adalah bilangan prima (isPrime = true).
  2. for (int i = 2; i <>Kemudian kita melakukan looping mulai dari 2 sampai dengan bilangan yang ingin di cek diambil 1 (valueToCheck – 1 ). Kemudian kita melakukan pemeriksaan apabila dari rangkaian looping cek tsb ada yang menghasilkan pembagian dengan tidak ada sisa, maka kita sudahi pemeriksaan, dan bilangan tsb pasti bukan bilangan prima.

Hmm, bagaimana jika program tsb kita kembangkan lagi menjadi sebuah program yang mampu mencari bilangan-bilangan prima dari suatu range bilangan, misal mencari bilangan-bilangan prima yang lebih kecil dari 50. Sepertinya secara logika kita bisa membuatnya dengan hanya menambahkan suatu looping saja sebelum looping yang ada di atas. Ok mari kita coba, perhatikan kode-kode berikut ini.

package org.mojo.blog.app.integer; //ignore this, if this program is not on package

public class PrimeAdvance {

public static void main(String[] args) {
// int valueToCheck = 17; // value to check
int nRange = 50;
boolean isPrime = false;

for (int i = 2; i <= nRange; i++) {
if (i >= 2) {
isPrime = true; // first check and assume it's prime number
// try divide valueToCheck
// with all number less than it self
// and begining from 2
for (int j = 2; j < i; j++) {
if (i % j == 0) {
//if divides exactly so stop the loop and it must be not prime
isPrime = false;
break; // no need to check again
}
}
}
if(isPrime){
System.out.println(i);}
}
//System.out.println("is " + valueToCheck + " Prime ? ");
//System.out.println("the answer is " + isPrime);
}
}

Pada kode diatas kita bisa melihat bahwa kita cukup menambahkan logika satu buah looping diatas looping yang ada sebelumnya, kemudian kita menambahkan baris, jika i adalah bilangan prima maka cetaklah ke atas konsol. Namun baris yang memerintahkan program untuk mencetak ke atas konsol kita letakkan di dalam looping range data yang ingin kita periksa.

Demikianlah, sedikit cerita tentang eksplorasi keingintahuan saya terhadap bilangan prima, yang berdasarkan senggolan cerita dari seorang teman. Silahkan di gunakan jika memang bermanfaat dan silahkan juga dikembangkan jika memang anda mempunyai ide-ide baru yang lain.

Untuk lebih memahami bilangan prima itu sendiri, berikut ini adalah link program java dimana dalam setiap proses looping-nya saya menambahkan cetakan ke konsol.

Semoga bermanfaat

Menteng 01 Januari 2009

josescalia