Thursday, December 3, 2009

FOSS.IN 2009

Its my third day attending the Free and Open Source Software India Conference (FOSS.IN) in Bangalore.
This is my third international event I'm attending, but it also my first international event I'm attending in about.. 10 years :) The first and the second were SEARCC Computer Competition (1996) in Bangkok and IOI 1996 in Hungary.
For us Indonesians, the climate is very much like at home. The food, is on other hand, very foreign tasting. Our hope on tasting familiar food lies on KFC and McDonald's at the Mall named 'The Forum' nearby. Today I tried the food, but I don't think I would dare to eat such food anymore. I raise my hat to the Europeans who faithfully eats the lunch given in the place :)
One problem occured to me is that I couldn't find a place to charge my laptop in an easy way. Further observation revealed, there are few plugs in front of the first row in each Auditorium, which are almost always full. But today I found that there is an extension chord in the floor near the first row, which now I blissfully plugged in my charger.
The conference opened my eyes that Indian people were significantly more involved in FOSS projects than Indonesians. Their Indians, although some with limited English, seems very interested and some has significant involvement in several FOSS projects, if not pioneering one or two such projects.
'm still attending some of the talks now.. so thats all for now.

Saturday, November 21, 2009

IWSS - Java developer's nightmare

InterScan Web Security Suite, abbreviated IWSS, it is said to be a comprehensive solution tailored for large corporate deployment. Product of Trend Micro, IWSS scans every HTTP access from a corporate's intranet onto the great internet. Unfortunately, it assumes that every .jar file accessed by a corporate's intranet is a java applet, therefore it naively apply bytecode manipulation on it, making a dialog box pops up every time the class in the jar file access something in the host OS. Like accessing a file in Eclipse's plug-ins folder. Like accessing a file in the Local Settings folder.

Why does it have to be like this? When does an antivirus company, allowed to do manipulations that in the past only done by virus? Let me explain. A jar file is an JVM executable. I downloaded tens if not over a hundred jar files from the internet, because Eclipse's update mechanism is just like that- by downloading jar files from the Internet. IWSS tampered with them, modified them.. it modified the executables so I could no longer expect the original behaviour of them. It ruins tens if not hundreds of jar files in my two laptops, which I must cleanup now. Virus in the past also did something similar to this. Exe files were modified by viruses, its header altered to call the virus body attached in the end of the exe file before calling the original entry point of the executable.
Please. I don't think that there is any reason for an antivirus company to behave like a virus. For the damages that already done, I think Trend Micro must provide its users a cleanup tool, a tool that could scan a harddisk for altered jar files, with com.iwss package in it, and modified them to normal, un-applying the bytecode manipulation said before. It is similar to virus cleanup tool, no?
I don't think Trend Micro has done everything they could to detect whether the JAR file is an applet or not. Oh, I see, they seem just UNABLE to do that. I wonder if they were UNABLE to create such bytecode transformation I said in the previous paragraph.

Saturday, November 14, 2009

Installing MULE ESB on Centos

I have one configuration that downloads SAP data using a Mule-1.4.4. Why not mule 2? The SAP Transport for Mule 2 didn't exist yet during the time I built the system. It was implemented on a Windows Sandbox system, that unfortunately has few shortcomings such as not being backed by tech support staffs, virus-prone, must be started up after power outages, and shared system load with SAP ERP Sandbox & one Ubuntu OS loaded in VMWare (whew, that's a lot..).
So I think it would be better to migrate the Mule-system into a Centos-powered virtual machine located in the Data Center (where power outages are rare and of course we have no worm/virus problem).
Extracted mule-1.4.4.tar.gz into /opt/mule-1.4.4. Put the IBM JDK 1.5's bin directory onto user's PATH by editing user's .bashrc file. Extracted sapjco 2.1.8 into /opt/sapjco2.
Tried run Mule for the first time, but it wants to download mail-1.4.jar. I copied the missing file from the previous system to lib\user. I also copied activation-1.1.jar to lib\user. Mule runs but complains about it being unable to write pid files and log folders. Chown-ed the entire mule tree to the mule user I created for the purpose of running the system.
Now, for the SAP integration part.. extracted in the home folder of mule user. Copied mule-transport-sap.jar and mule-transport-sap-examples.jar from the target folders resulting from the previous built (on a WinXP system, I think) onto lib\user.
I tried to run the config file from the mule-sap-transport system. Unfortunately it choked because of missing commons-dbcp and ojdbc.jar (I used oracle jdbc endpoint). I copied the missing jars from the previous system onto lib\opt (don't know whether will make any difference if I used lib\user). Symlinked sapjco.jar into lib\user.
At long last, Mule runs now. But when I triggerred the sap download (RFC call), exceptions spewn in the console (or mule.log, depends on I used mule start -config ... or just mule -config ...). It couldn't find the native library, but somehow it was able to load in the same folder. Must be the wrapper mechanism (mule used wrapper from tanukisoftware) that causes this strangeness. Poking my .bashrc again, and finds out that the LD_LIBRARY_PATH is not being exported.. silly me. Adds LD_LIBRARY_PATH to the export clause, exit the console, re-login, and now it works..

RAID5 Failure, Again

This time I get (another) annoying RAID5 failure. The CentOS 4.7 server won't boot because it was unable to start the RAID5 array. Yes, this is the second time I stumbled upon this problem (see this Indonesian-written post). I burned a new CentOS 4.7 DVD (using a new REAL server's DVD writer, no less), then I boot up the DVD, typed linux rescue in the boot command line, and tried to follow the exactly the same step I've done and written in this blog, but to no success: the system complains that the superblock doesnt match.
Seems I forgot the new RAID5 configuration in this server. I forgot that I have reinstalled this server with SAP ERP Netweaver, creating two software RAID5 arrays in the process, and of course with different partitions.
The partitions were: sda3, sdb3, sdc1, sdd2. The four partitions created a 215 megablock (thats about 100 GB, I think) md1 partition. Here's the chemistry:
- The kernel won't add non-fresh member (sdd2) into the array, it kicks it out of the RAID assembly.
- The remaining RAID assembly of three partitions couldn't be started. The cause is, which I found out after forcing the array to run, is that event counter in sda3 is not the same with the others. But kernel said nothing of this in the dmesg log. It just said 'unable to start degraded array ..'
- I forced the assembly to run. Must do this when the md device stopped. So, mdadm -S /dev/md1, then mdadm -A --force --run /dev/md1 /dev/sda3 /dev/sdb3 /dev/sdc1 /dev/sdd2. It runs indeed, writing error messages about sda3
- But sdd2 still kicked out from the array. I must manually add it to the array, mdadm -a /dev/md1 /dev/sdd2
Now, I am just waiting for the recovery (recovery status can be read in /proc/mdstat) to finish, so I could boot up this system in confidence. I hope nothing else went wrong.

Saturday, October 10, 2009

Java-based Domain Driven Frameworks

Yesterday I'm browsing and exploring about Full-stack Domain Driven Application Frameworks written in the Java platform. The Java platform still has a lot of potential, but somehow the Rails framework tells me that we're still far from it, my exploration yesterday.
Here is a brief of the frameworks I read about:
  1. JMatter - This one I already use a few months back. The UI is pretty decent, but the lack of production quality web-based view technology.. makes it very far behind others. It currently only has production-grade Swing viewer, making it a two tier application platform. Security-wise, two-tier platforms are not good -> each client must have a database connection to the db server, which potentially could be abused. Has no authorization code built in. Actions on the entity written in the domain model, encapsulating business logics.
  2. OpenXava - Web-based GUI with some AJAX parts. Has no authorization code built in. Separates actions from domain model, the concept is that actions must be contained in controllers.
  3. Jspresso - Has multiple view (GUI) technology implemented - ULC, Flex, and WingS. Flex is Adobe's RIA technology, WingS is AJAX Web-based view technology. ULC I have no experience. The Reference manual somewhat not completed. Domain model not written in Java, it was written in spring beans XML. I havent figure out how to write business logic, but entity relationship stuffs seems to be complete. Class-based authorization and dynamic authorization (The docs were very hazy about this one - seems that this is authorization based on object's state but I havent' found out how to implement authorization based on object's owner).
  4. Nakedobjects - Currently only has Swing/AWT viewer (sorry, haven't got time to find out which is which) and HTML (web-based) viewer. Domain model written in Java, contains business logic (similar to JMatter). Class-based authorization.
  5. Trails - only has Tapestry viewer, which generates Web-based GUI. Domain Model in Java. Seems to be the only one that implement class based authorization and association-based authorization.
The feature I was looking for is association based authorization. But the thing is, OpenXava's view descriptor features seems to be most complete compared to others - makes me hard time thinking whether it is best to start with OpenXava or to start with Trails...

Saturday, September 12, 2009

HTB traffic control burst calculation inaccuracy

My previous Kubuntu 7.04's Linux 2.6.20 kernel uses a 1000 Hz timer kernel (refer to HZ constant defininition and fourth value of kernel ABI /proc/net/psched routine psched_show in sch_api.c). HTB's burst is calculated by tc binary using the formula : bitrate/timer frequency + maximum transfer unit.
Ubuntu 8.04's Linux 2.6.24 kernel have an improved packet scheduler timer resolution. It now uses high resolution timer, with nanosecond accuracy. Refer to psched_show in sch_api.c, and Fourth value of /proc/net/psched now returns 1 G (10^9). HTB burst calculation is now bitrate/10^9 + mtu.. Somehow this is will always a small value, and as a side-effect HTB qos scheduler no longer capable of delivering high bitrates accurately to stations.
My analysis based on my limited knowledge of the packet scheduler : the linux's packet scheduler is driven by calls to dequeue function. This might be driven by tx complete interrupt or something else. So it is not timer-driven. But the packet scheduler routines (such as sch_htb) keeps track of passing time using the value of packet scheduler timer (previously, 1KHz timer, and now, the 1 GHz timer). Htb adds tokens into the token bucket based on time passed between previously recorded time of change in the class (cl->t_c) and the current time (q->now) (see sch_htb.c:660). Herein lies the problem, the current time q->now is no longer the current time, because the timer frequency is in nanoseconds and there are tens if not hundreds of instructions being executed between the assignment of q->now (see htb_dequeue at sch_htb.c:894) and the usage of q->now. And, maybe, some interrupt has occurred (I dont really know, dequeue is not being called in the context of NMI, is it ?), and maybe one milliseconds has passed.. The inaccuracy of the size of the added token, causes the htb to prevent packets being sent in timely manner -> it thinks that the class not eligible to send package because token remaining is less than packet size, the token count is actually less than what it supposed to be.
This is what I thought, for now. The cure seem to be changing tc source code to assume 1KHz timer (which amounts to 1ms accuracy) when tc finds out that a nanosecond timer is in use, so the token buffer is large enough to cater for problems caused by time inaccuracies said above.

Sunday, September 6, 2009

Names in our code

This is just a summary of some rule-of-thumbs when developing source codes.

When coding, do these :
  • use descriptive names
  • please classify/categorize so we have shorter source files. Or, we have fewer source files in each folder (distribute files into category folders). In OOP, we should refactor into new classes if things gotten too crowded in one class, or even refactor the class into different packages. In PHP, we should refactor into new files and/or new folders.

Rules that were Anti-patterns :
  • don't use generic names like $query. When reading it, I don't have a clue what does it stands for, a query to the users table, or a query to delete a user, or what? OK, maybe it can be used if the scope is local, that is, I could easily look for the meaning in the same function or small file.
  • avoid long parameter list. It is difficult to find out which parameter means what. We could use: a value class in OOP languages, or associative array in PHP, or even object in PHP, to give meaningful parameter. When function insert(name,address,groupid,status,isAdmin) being called, it becames insert($name,$address,null,0,$isAdmin), and we must look elsewhere what does the 0 stand for. If we have $entity = array('name' => $name, 'address' => $address, 'groupid' => 0, 'isAdmin' => isAdmin); and call insert($entity); things are much easier to understand and easier to modify.

Monday, August 17, 2009

Multiple PHP in a machine blues

I am compiling PHP's source code and a PHP extension (apc). The reason for not using packaged version of PHP is that there is another critical application running in the server, with its own PHP version, and we don't want to risk incompatibility issues forcing the application run with a different PHP version. Meanwhile I need PHP compiled with debug flags, and also with gd enabled and apc extension for another application. I prefer Debug flags to be enabled because we're testing this whole stuff and don't want to be in the dark when error (s) cropped up (previous set of PHP-apache-oci8 triad sometimes issued segmentation faults but we don't now the source of the errors).

The problem is, that the apc Makefile won't use the debug flag set during previous PHP compilation. It turns out that we must be very careful that:
  • the phpize being used is from the correct PHP compilation (I deleted the scripts/phpize and scripts/php-config after changing PHP's configure parameters, then invoke make install on PHP)
  • no other phpize or php-config is being run, especially by setting the PATH environment variable so the path to the correct phpize/php-config is the first directory listed in the PATH.
The second item is blocked me for some time, I didn't realize that the phpize - configure - make phase invoked php-config plainly (using the PATH). Because there is several PHP installation in the system, the php-config being run is from the other installation (the root administrator installed the other PHP binaries in the normal location such as /usr/local/bin).

Munin, again

More problems come when I'm just starting to use Munin-Node to monitor several Windows 2003 servers :
  1. the memory value reported by Munin-Node are all wrong. The sum of app and unused is not related to total physical memory installed in the servers. It turns out that the Windows API used returns 64-bit values, and simple change to the format specified fixes the problem.
  2. external plugin doesn't work. Turns out that the external plugin must not print the trailing newline when invoked by 'name' argument, and it also must prints a line of '.' after each 'config' and 'value' (or default) invocation.
  3. after several days of running, external plugins stopped working. I used sysinternals' process explorer in the server, and found out that there is some chance that external plugin invocation doesn't close the listener thread. After a few days the unclosed threads became too much and prevent the Munin-Node service from spawning new external plugins.

Thursday, August 6, 2009

Munin-Node 1.5 with correct memory plugin

Munin is a solution to monitor servers. It shows graphs of some important server's system parameters, such as disk free space, cpu utilization, memory usage, network traffic, and even the HD temperature. Munin requires an agent, called Munin Node, installed at the server (you must be root or administrators to do this). Of course, there is a specific Munin Node to be installed for each operating system. On Ubuntu systems, there is munin packages in ubuntu's repository. Meanwhile Jory Stone created Munin Node for Windows, and I'd be needing that because some of the servers used at my workplace is powered by Windows Server 2003.
I read the postings at jory's Munin Node site, and seems that memory plugin must be patched in order to have visible memory graphs. I've downloaded the source code from jory's site, then I followed the instructions to fix the memory plugin (uncommented few lines in MemoryMuninNodePlugin.cpp), and the next task is to compile the whole thing.
A simple thing, compiling, is not as simple as it seems.
First, the vcproj file is for VS 2008. I'm using VS 2005. After editing the version part of the file, the project file could be opened. Next, netfw.h couldnt be found. A few googling back and forth found some netfw.h, and I downloaded it with icftypes.h (look here). Then, msi.lib seems to be missing (I'm using VS 2005 which lacks that file). I am forced to download Platform SDK, and I choose only windows installer SDK to install (minimize download volume). Well, now I have a fresh munin-node.exe. But wheres that upload button in blogger... Oh, blogger doesn't allow us to upload files.
So i upload the executable in my own site at google.
It seems that, no easy deployments for executables compiled in VS 2005 - we either must link to C Runtime (CRT) static library, or link to CRT DLL and use some mechanisms to ensure the DLL will be installed using Windows SxS (side by side) mechanism. The mechanisms include making the user installed the VC Runtime redistribution or include the CRT Merge shared module into a MSI-packaged installation format.
I compiled it once more and this time packaged the executable in .MSI format (seems that the vdproj format for VS 2008 were compatible with 2005). Jory sets up the release version to be statically-linked, so the only motivation for .MSI packaging is the ease of service installation.

Wednesday, July 15, 2009

OpenOffice 3.1

OpenOffice 3.1 melakukan startup dengan cepat - itu impresi pertama saya. 11 detik membuka OpenOffice Calc. Close, kemudian buka lagi - 3 detik untuk membuka Calc untuk kedua kalinya.

Skills Statistics

There is always a concern of skill shortage when we try to decide which platform of choice we're going to use to develop internal applications.
Well, maybe we could see what kind of skills is up for sale at :
Some thing we could try to relate from this list :
Popularity of programming languages : 1. PHP with 11 thousand freelancers, 2. .NET with 8 thousand, 3.Java with 8 thousand freelancers. ASP.NET ranks further below (5 thousand freelancers), as a web development platform its ranking is not as favorable as PHP (another popular web development platform). I assume that .NET skill means client-server WinForms skill. Further down is J2EE which somehow as popular as Visual Basic (we know how popular VB are in the real world.. )
Strange enough, there is no Oracle skilled freelancers open for hire, despite MySql as 1st place popular database and SQL Server as 2nd popular database skill.
Operating System skills : Windows as 1st place with 4 thousand freelancers, but it is not that far with Linux with 3 thousand freelancers.

Friday, July 10, 2009


Ada perkataan: makin banyak yang kita tahu, makin sadar kita bahwa kita baru mengetahui sebagian kecil dari pengetahuan yang ada.
Di industri yang saya geluti, industri teknologi informasi, pembelajaran berlangsung tanpa henti. Selalu ada hal yang baru. Sampai suatu saat, berpikir apakah perlu untuk menghentikan penyerapan hal baru dan saatnya menerapkan hal-hal yang telah diketahui.
Mari kita lihat model proses belajar (Learning) yang umum ada di perusahaan jaman dahulu. Pada model ini, moda belajar utama yang diakui perusahaan ialah pembelajaran formal - keryawan dikirim untuk pelatihan, sehingga mendapatkan skill dan knowledge yang dibutuhkan untuk bekerja. Karyawan cuma perlu menerapkan apa yang diberikan dan mengikuti peraturan - it is a simple world. Jika ia belajar dari jalur lain, itu merupakan nilai tambah yang dimilikinya, namun pada model learning lama jalur lain tidak diatur dan tidak diperhitungkan. Perusahaan menyiapkan career path dan learning path - karyawan tinggal mengikuti dengan baik.
Masuklah ke abad 21.
“80% of learning and knowledge transfer occurs through informal, tacit learning activities but only 20% of the budget spent on corporate learning is focused on informal learning activities.”
– The Business Impact of Social Computing on Corporate Learning, Carol Rozwell, Gartner Research
Ada apa dengan formal learning? Masalah dengan formal learning dengan konten semi-statis ialah :
  1. Courseware that is outdated due to lack of bandwidth from the content team
  2. Course content that is not easily accessible or searchable, or that only a handful of subject matter experts even know exists
  3. Overabundant content that can make finding the best fit a daunting task
  4. Content that lacks the real-world examples and insight delivered through interaction with subject matter experts
  5. Content that fails to address “never seen before” situations, and that cannot give learners the confidence needed to perform in a highly uncertain environment

Perubahan kondisi lapangan terjadi sangat cepat, demand akan knowledge dan skill baru cukup tinggi, sementara tenaga kerja dibatasi mengakibatkan workload tinggi pula - karyawan tidak sempat mengikuti Training, ia akan mengandalkan intuisinya dan bantuan dari expert lewat jalur informal. Ia akan belajar secara informal mendapatkan skill dan knowledge yang dibutuhkannya.. itulah yang akan terjadi. Itulah yang sedang terjadi.

Thursday, July 9, 2009

IE memanggil Firefox ?

Siang hari ini ada pasien sebuah komputer yang IE nya ngadat. IE mau muncul, tapi kalau diketik URL di address barnya, muncul popup Application not found. Ada lambang Firefox di start menu tapi executablenya tidak ada. Clue dari pengguna komputer ialah ia tadinya mencoba memasang IE7 dan kemudian diuninstall (sehingga IE yg aktif IE6). Tampaknya Firefoxnya juga diuninstall (entah karena alasan apa).
Googling sana-sini, sampai akhirnya menginstall Windows XP Service Pack 3 karena berasumsi ada DLL yang mismatch atau tidak lengkap. Tetap kondisi tidak membaik.
Ternyata masalahnya ada di sebuah registry key. Entah bagaimana registry key ini merefer ke DLL milik IE7 di temporary folder dan mempengaruhi perilaku IE6 sehingga mencari Firefox (uaneeeh) ketika sebuah URL diketikkan di address bar. Kalo ga percaya, liat bahasan di sini dan sini.
Solusi masalah ini ialah menghapus registry key HKEY_CLASSES_ROOT\CLSID\{C90250F3-4D7D-4991-9B69-A5C5BC1C2AE6}, tutup semua jendela IE (kalau perlu hentikan Explorer), tunggu 5 detik, kemudian buka kembali IE. Ada yg menyarankan menghapus file DLL IE7 tapi tadi saya tidak lakukan (mungkin kalo error lagi baru aku jalanin :) )

Roles, Profiles dan PFCG di SAP

Ini adalah sebuah overview mengenai sistem authorization di SAP. Ketika seorang user (mencoba) melakukan suatu hal di sistem SAP, misalnya membuka transaksi screen ber-kode tertentu, sistem akan memeriksa apakah user tersebut memiliki authorization object tertentu. Jika authorization object tersebut dimiliki, maka diperiksa juga apakah nilai field-fieldnya match atau tidak dengan properti dari operasi yang akan dilakukan. Sebuah authorization object berisi beberapa field, field ini dapat diisi * (wildcard), multiple value ataupun single value, dan logika matching ini disesuaikan dengan jenis value yang diisi. Field diisi * berarti match dengan semua operasi. Field berisi multiple value berarti match jika properti operasi sama dengan salah satu value yang ada.
Role merupakan kumpulan dari Menu dan Authorization Object. Ada pemisahan yang agak kurang natural antara Role dan Profile, di mana Profile yang dimiliki user-lah yang dicek oleh sistem authorization di SAP. Ketika Role disave, ia harus digenerate menjadi Profile. Baik Role dan Profile diasosiasikan dengan user.
Di mana peran PFCG? PFCG menggenerate Profile dari Role. Tetapi lebih penting lagi, ia menggenerate Authorization Object yang diperlukan dari Menu yang telah dipilih ke dalam Role. Dari authorization object yg disuggest oleh PFCG, admin dapat mengubah isi field, menonaktifkan authorization object, atau bahkan menambahkan authorization object baru.

Oracle 10.2 on Linux x86_64

Bagaimana caranya kita install Oracle Database Server di Linux ? Jika anda berkata, masukkan DVD/CD, run installer, klik next-next-next, anda salah besar..
Isu major: installer Oracle 10g untuk Linux tidak sadar akan semua paket sistem yang diperlukan sebelum instalasi Oracle Database. Hasilnya: ketika cek persyaratan, semua OK, tetapi installer bisa saja mandek di tengah jalan dengan error tertentu.
Guideline : Oracle Metalink Note 169706.1 (aku tahu kode ini malah dari SAP Notes :) ). Pada Red Hat Enterprise Linux 4, atau CentOs 4, Install paket-paket berikut ini sebelum instalasi (perhatikan ada paket x86_64 maupun i386):
# binutils-
# compat-db-4.1.25-9.x86_64.rpm
# compat-gcc-32-c++
# compat-libstdc++-33-3.2.3-47.3.x86_64.rpm
# compat-libstdc++-33-3.2.3-47.3.i386.rpm
# control-center-2.8.0-12.x86_64.rpm
# gcc-3.4.3-47.x86_64.rpm
# gcc-c++-3.4.3-47.x86_64.rpm
# glibc-2.3.4-2.9.x86_64.rpm
# glibc-2.3.4-2.9.i386.rpm
# glibc-common-2.3.4-2.9.x86_64.rpm
# glibc-devel-2.3.4-2.9.x86_64.rpm
# glibc-devel-2.3.4-2.9.i386.rpm
# glibc-headers-2.3.4-2.9.x86_64.rpm
# glibc-kernheaders-2.4-9.1.87.x86_64.rpm
# gnome-libs-
# libaio-0.3.103-3.i386.rpm
# libaio-0.3.103-3.x86_64.rpm
# libgcc-3.4.3-9.EL4
# libstdc++-3.4.3-22.1.x86_64
# libstdc++-devel-3.4.3-22.1.x86_64
# make-3.80-5.x86_64.rpm
# pdksh-5.2.14-30.x86_64.rpm
# sysstat-5.0.5-1.x86_64.rpm
# util-linux-2.12a-16.EL4.23.x86_64 (for raw devices)
# xorg-x11-deprecated-libs-6.8.1-23
# xscreensaver-4.18-5.rhel4.2.x86_64.rpm
Gunakan yum untuk menginstall paket2 ini dari repository paket Linux yang anda gunakan. Saya sarankan Linux yg diinstall pakai distribusi Centos karena repositorynya dapat diakses dengan bebas, jika pakai Red Hat maka repositorynya tidak bebas diakses (anda harus punya support account).

Sebuah saran: kalau ada paket yg terlewat, dan terjadi error, anda akan tergoda untuk menginstall paket yg terlewat tadi dan menekan tombol Retry di oracle installer. Jangan lakukan itu, pilih abort dan ulangi instalasi dari awal.

Selain paket-paket, mungkin kernel parameter perlu anda ubah. Edit di /etc/sysctl.conf. Pada setting saya, ada nilai2 berikut :
#oracle-requested params
kernel.sem = 250 32000 100 128
kernel.shmmax = 1073741824
net.ipv4.ip_local_port_range = 1024 65000
net.core.rmem_default = 262144
net.core.rmem_max = 262144
net.core.wmem_default = 262144
net.core.wmem_max = 262144

Thursday, April 9, 2009

Bagi orang yg telah disebut sebagai pelupa sejak sekolah dasar, tampaknya pertanyaan mendasar ini seharusnya sudah muncul sejak lama. Or is it I who doesn't remember it?
Demo, lets think about analogies - they make things simpler. Ingatan manusia seperti layaknya storage di komputer, memiliki kapasitas penyimpanan yang besar. Tetapi, informasi tidaklah
hanya disimpan, ia harus bisa dicari dan dikeluarkan kembali. Indexing di komputer, adalah asosiasi di manusia. Manusia mengingat informasi berdasarkan banyak hal, apakah topik, pelaku, waktu, lokasi, bentuk, ataupun kriteria lainnya. Di sini manusia memiliki tempat yg berbeda untuk asosiasi, dengan kapasitas yg lebih kecil daripada penyimpanan utama tadi. Ada kalanya kita bisa tiba2 teringat suatu hal, disebabkan karena kita memikirkan hal lain yg berhubungan dgn hal pertama tadi.
Kita lupa, adalah akibat dari hilangnya asosiasi ke informasi yg tersimpan di otak. Short term memory, adalah ingatan yg terasosiasi penuh, siap dicari dgn kriteria apapun.
Nah, supaya ingatan tetap bisa diretrieve, apa yg bisa dilakukan? Memaksimalkan memori yg bisa diakses dgn mengoptimalkan penggunaan ruang asosiasi? Mungkin, dgn informasi yg terstruktur, asosiasi yg dibutuhkan menjadi lebih sedikit, sehingga
lebih banyak volume ingatan yg dapat diakses langsung oleh kita.

Thursday, March 26, 2009

Software engineering

Jika pelukis membuat lukisan, penulis membuat buku, maka kami, para software engineer, writes code. Kami menulis code dalam bahasa pemrograman, sehingga muncullah software di dalam komputer yang dapat membantu manusia dalam menghadapi aktivitasnya sehari2.

Suatu fakta yg signifikan, bahwa bidang ini termasuk muda dibandingkan yg lain seperti chemical engineering atau electrical engineering. Saya dulu mengira bahwa perkembangan ilmu di bidang IT atau software, dapat dengan cepat menyebar di seluruh dunia, karena pada umumnya para pelajar IT atau pekerja IT lebih sering menggunakan Internet daripada orang lain. Sehingga, begitu ada breakthrough di teknik object oriented, saya mengira bahwa dalam waktu satu dekade (10 tahun) hampir semua pekerja IT sudah mengerti teknik object oriented tersebut. Teknik yang saya maksud ialah Design Patterns, yang dipublikasikan sekitar 1995 oleh Erich Gamma (sekarang ia bekerja sebagai engineer di IBM). Ternyata, sampai sekarang pun, mayoritas pekerja IT Indonesia belum paham. Mungkin teknik ini terlalu rumit untuk diterapkan secara praktikal, atau mungkin bahwa dunia IT Indonesia tidak terlalu memerlukan object-orientation..

Dan ini membawa kita ke topik yang menarik, apakah yg diperlukan bagi seorang software engineer di Indonesia? Akan saya coba brainstorming dari aktivitas sehari-hari seorang software engineer (thats me :). Sebuah hal yang cukup sering dilakukan, adalah membangun sebuah aplikasi web-based, untuk memenuhi kebutuhan pencatatan manusia, dan memberikan logika (business logic) sehingga aktivitas (transaksi) sehari-hari lebih teratur dan menaati prinsip-prinsip tertentu. Dan umumnya, setelah dicatat, ada pihak yang tertarik untuk dibuatkan laporan secara otomatis oleh komputer, sesuai dengan keperluannya saat itu.

Secara teknis, pilihan kami ialah mengcoding aplikasi menggunakan bahasa pemrograman seperti PHP, Java, atau .NET. Akan tetapi, karena targetnya web-based application, kami dituntut juga untuk mengetahui HTML, bahasa yang digunakan untuk 'menggambar' layar-layar user interface yang akan dihadapi user. Untuk mempercantik tampilan, pasangan HTML adalah CSS. Kita lihat bahwa aplikasi web-based memberikan tantangan yang 'lebih' misalnya karena memberikan kita kesempatan untuk mempelajari dan menguasai 3 buah bahasa sekaligus (satu bahasa Core Logic, satu bahasa markup, satu bahasa styling)
Kemudian, karena keperluan manusia yang dibantu komputer umumnya adalah pencatatan, maka tentunya para engineer mempraktekkan best-practice beberapa dekade terakhir yaitu penyimpanan data di relational database management system. Kita lihat, bahwa kecenderungan terakhir ini memberikan kesempatan para engineer untuk memahami dan menguasai bahasa keempat, yaitu SQL (structured query language).
SQL sederhana merupakan masalah sepele, tapi sebuah SQL kompleks yang terdiri dari 4 inner query, belasan kolom, dan belasan kondisi WHERE merupakan ujian kemampuan visualisasi abstrak bagi developer, dan merupakan mimpi buruk para software engineer. Beberapa pihak mendiskreditkan RDBMS dan mendorong manusia ke arah lebih civilised seperti object oriented database (atau object oriented persistence system), tetapi saya melihat bahwa kompleksitas SQL muncul karena source code yang sulit diubah dan bukan karena kelemahan konsep RDBMS.

Sebuah software yang dihasilkan proses engineering, di Indonesia, pada umumnya sulit diubah karena banyak faktor:
1. terlalu banyak duplikasi, akibatnya ketika ingin mengubah satu hal, misalnya nama kolom di suatu tabel, kita harus mengubah di banyak tempat di source code (belasan atau puluhan tempat, jika softwarenya cukup besar)
2. terlalu rumit, sehingga untuk mengubah satu hal, membutuhkan seminggu bagi developer untuk memahami kodenya (sebelum merubah apapun)
3. source code tidak terstruktur, menyulitkan manajemen source code, misalnya untuk mencari source code yang menangani suatu hal tertentu. Asumsi untuk faktor ini ialah kita melakukan maintenance software, tanpa developer yang membuat aplikasi pertama kali.

Sebuah breakthrough lain, yang cukup signifikan dalam dekade terakhir, ialah Ruby On Rails. Sebenarnya ini merupakan sebuah 'library' dalam bahasa pemrograman Ruby. Yang membuat signifikan, ialah pembuatnya mengklaim 10x perubahan produktivitas ketika melakukan pembuatan aplikasi menggunakan Rails. Rails bukan hanya library, tetapi merupakan framework, yang 'memaksakan' struktur tertentu pada source yang dibuat. FORTRAN juga memaksakan struktur tertentu, tapi hanya bersifat sintaksis, berbeda dengan Rails yang memaksa kita bekerja dengan konsep Model-View-Controller. MVC merupakan sebuah Architectural Design Pattern yang membuat engineer memisahkan source code menjadi tiga kelompok besar, Model, yang memuat business logic, View, yang memuat logika penampilan, dan Controller, yang memuat logika penerimaan input dari user (button ditekan, form disubmit). Bagi saya, pemisahan MVC cuma masalah strukturisasi. Ada pula orang yang berpendapat, seharusnya kita tidak perlu mengcode V atau C, karena kedua layer ini dapat dibuat generik (lihat: Naked Objects Framework). Menurut saya, yang terpenting adalah di M-yaitu sang Domain Model. Business logic disimpan di sini, dan Rails mengadopsi konsep Active Record - yaitu mencampur business logic dengan logika persistensi (yang melakukan query ke database untuk menyimpan dan mengambil data). Bagi pembuat Hibernate, sebuah persistence framework berbasis Java, sangat penting untuk memisahkan business logic dan layanan persistensi - jadi kita lihat ada dua konsep berbeda yang berkembang belakangan ini. Saya berprinsip, tidak penting disatukan atau dipisah (seperti halnya MVC) tapi yang terpenting, seberapa mudah saya dapat melakukan perubahan pada Domain Model? Seberapa mudah saya menambahkan satu field? Seberapa sulit saya memindahkan satu property (field) dari satu model (atau entitas, atau tabel di RDBMS) ke model lainnya?
Menurut saya, ini adalah hal yang cukup penting. Saat ini, karena sulit untuk mengubah 'model' (atau desain, atau ERD), maka developer stuck pada model yang tidak sesuai dengan kebutuhan sebenarnya. Karena SQL, merupakan bahasa yang sangat powerful, maka aplikasi tetap dapat berfungsi dengan model data yang rancu, namun di sana-sini akan muncul banyak SQL rumit yang menyulitkan perubahan aplikasi. Padahal, perkembangan (development) itu intinya proses perubahan dari aplikasi yang belum jadi menjadi aplikasi yang siap pakai..

Solusi terhadap masalah kita, sayangnya, menuntut kita berpikir mengabaikan prinsip maupun cara lama. Masalah saat ini tidak akan dapat diselesaikan dengan cara berpikir yang menyebabkan terjadinya masalah tersebut. Beberapa ide pemikir IT dekade terakhir antara lain :
1. memindahkan business logic sepenuhnya ke aplikasi, mengurangi beban kompleksitas pada SQL, stored function, stored procedures, ataupun database triggers. Padahal, ada pekerja IT yg saat ini berprinsip untuk memaksimalkan penempatan business logic di dalam database..
2. desain, menjadi hal yang tidak tabu untuk dirubah.. kesederhanaan yang terjadi ketika desain berubah menjadi lebih match dengan kondisi riil lapangan, bernilai sangat tinggi - performansi aplikasi meningkat, aplikasi lebih mudah dituning, source code mudah dibaca, penambahan fungsi mudah dilakukan, dan lain-lain, semua ini worthwhile untuk ditukar dengan usaha untuk merombak source code sebagai akibat perubahan desain
3. atau even better, buatlah sehingga merubah desain, semudah mungkin.. menggunakan framework manapun, sehingga hal ini dapat tercapai. Hibernate Persistence Framework menjanjikan para engineer mengkode SQL dengan volume jauh lebih sedikit daripada cara manual, begitu pula Ruby On Rails, CakePHP, CodeIgniter.. Prevayler Persistence Framework, di sisi lain, menjanjikan bahwa para engineer tidak perlu menulis satu barispun SQL (death to the database, they said)

Kita lihat, ternyata breakthrough 'design patterns' tidaklah useless at all, karena semua framework yang dibuat sekarang, dibangun atas design pattern-design pattern.

Saya belum menyinggung istilah refactoring di paragraf-paragraf di atas. Idenya ialah, kita harus bisa mengubah desain pada sebuah running application, sehingga kualitasnya meningkat, tanpa mengorbankan fungsionalitas aplikasi. Jadi mirip dengan tone yang saya gunakan pada paragraf-paragraf di atas. Sebenarnya, mengukur kualitas software dari banyaknya duplikasi, kompleksitas source code, adalah dua dari banyak metoda yg digunakan untuk mengukur kapan kita harus melakukan refactoring. Bau di code, atau Code smells, begitu istilah Kent Beck & Martin Fowler, yang mereka jadikan patokan perlunya melakukan refactoring atau tidak. Sebenarnya saya belum menerapkan satu safety net di sini - yaitu automated test. Menurut penulis buku Refactoring, automated test membuat refactoring tidak berakibat buruk bagi fungsionalitas aplikasi. Which is, unfortunately, is the very issue I am facing - tiap refactoring yang saya lakukan di aplikasi saya, membuat munculnya bug-bug yang menghantui user sampai saya perbaiki..

Ok, now, menutup satu topik yang sudah saya buka, bahwa dalam menulis web based application kita harus memahami minimal 4 bahasa komputer.. Alternatifnya, kita belajar menggunakan GWT (which is, mulai populer setelah beberapa tahun hidup..) GWT membuat kita cuma coding dalam satu bahasa: Java. Ia melakukan konversi dari Java ke Javascript pada saat deployment aplikasi. Sayangnya, kita tetap harus memahami HTML dan CSS, meskipun ada abstraksi HTML yang disertakan oleh GWT sebagai kelas-kelas Java. Setidaknya satu bahasa untuk dipelajari menjadi berkurang :). I wonder, jika Prevayler tetap dikembangkan, dan dapat digunakan bersama GWT.. berarti kita bebas dari SQL& Javascript - its a totally killer concept :). Cuma tampaknya, web-based application memang akan lebih tidak menyenangkan dari pada client-server application, yang mana kita sama sekali tidak perlu tahu HTML & CSS, dan tidak perlu tahu perbedaan browser IE dan Firefox :).

Manusia punya batas, dan mengurangi unnecessary complexity membuat kita dapat memikirkan konsep aplikasi yang lebih useful (dan tentunya.. sedikit lebih rumit)

Monday, March 2, 2009

Inconsistent Access Control in Liferay Social Office

Beberapa hari ini cukup dipusingkan dengan Access Control di Liferay Social Office. Untuk sebuah folder di bawah Document Library, apapun Permissions yang kita set, selalu saja semua user dapat melakukan 'Add Document' atau 'Add Folder'. Kecuali kalau 'view' permission tidak kita berikan ke user, maka user tersebut tidak dapat membuka folder tersebut, apalagi Add Document atau Add Folder. Saya belum cek kalau user mengetikkan URL add document langsung (tanpa view isi foldernya lebih dahulu) tetap bisa dilakukan Add Document atau tidak. Anyway, ternyata masalahnya ada di propagasi permission dari parent folder ke subfoldernya. Semua permission yang dimiliki current user pada sebuah folder akan dipropagasikan ke subfolder di bawahnya. Perilaku Aplikasi menjadi cacat karena Community Member memiliki permission Add Document dan Add Folder pada root folder di komunitas tersebut, sementara tidak ada UI untuk merubah permission pada root folder. Hanya Permission pada folder-folder lain yang dapat diubah, lewat menu 'Action:Permissions' yang tersedia saat kita menampilkan folder tersebut sebagai isi dari folder lain.
Solusi saat ini ialah menambahkan UI untuk mengubah permissions pada current folder yang sedang ditampilkan, sehingga pada saat menampilkan root folder, administrator dapat mengubah permissions pada root folder.
Perubahan pada webapps\ROOT\html\portlet\document_library\view.jsp atau view.portal.jsp :

(baris: 274)
boolean showCurDocumentSearch = showFileEntriesSearch && (results.size() > 0);
boolean showChangePermissions = DLFolderPermission.contains(permissionChecker, folder, ActionKeys.PERMISSIONS);
Tambahkan di baris 301:
<c:if test="<%= showChangePermissions %>">
modelResource="<%= DLFolder.class.getName() %>"
modelResourceDescription="<%= folder.getName() %>"
resourcePrimKey="<%= String.valueOf(folder.getFolderId()) %>"
<liferay-ui:icon image="permissions" url="<%= changePermissionsURL %>" />

Nah, selanjutnya, kami mengalami anomali di portlet permissions. Di Forum Liferay ada beberapa posting yang membahas kasus ketika seseorang pernah diberi akses untuk menambahkan sebuah portlet ke sebuah halaman, kemudian akses tersebut dihilangkan ketika user tersebut telah menambahkan portlet tersebut. Pada banyak kasus, user tetap dapat melihat isi dari portlet yang sudah ditambahkan meskipun hak aksesnya sudah tidak dimiliki. Ia hanya dicegah dari menambahkan portlet, dan tidak dicegah dari melihat isi portlet yang mana ia tidak lagi memiliki akses. Pada kasus kami, manifestasinya ialah kadang-kadang halaman depan user menunjukkan status denied, dan setelah beberapa kali dicoba (dengan navigasi berputar-putar ke tempat lain dahulu) portlet-portlet di halaman depan user tetap ditampilkan di halaman default.

Wednesday, February 18, 2009

Zend Framework - what a configuration

Hari ini mencoba sesuatu yang baru. Menggunakan 3 orang berpengalaman (including.. me:) )untuk menyelesaikan satu hal sepele.. yaitu mengkonfigurasi sebuah aplikasi PHP berbasis Zend Framework sehingga bisa ditaruh di folder selain webroot. Sebenarnya, tidak ada satupun yang pernah menggunakan Zend Framework (kami terbiasa dengan CakePHP dan CodeIgniter), jadi tentunya tetap ada tantangan.
CodeIgniter menggunakan file konfigurasi system/application/config/config.php untuk menset base_url, dan pada CodeIgniter yg kami pakai sudah ada algoritma deteksi otomatis yang berfungsi baik.
$config['base_url'] = "http://".$_SERVER['HTTP_HOST'];
$config['base_url'] .= preg_replace('@/+$@','',dirname($_SERVER['SCRIPT_NAME'])).'/';
Neverthless, untuk Zend tampaknya konfigurasi disimpan di file app.ini. Ternyata, agak sulit juga mencari dokumentasi tentang isi file ini. Setelah membrowsing-browsing cukup lama, kami menemukan dokumentasi fungsi setBaseUrl di FrontPageController. Pertanyaannya.. darimana ini harus disetup? Hipotesa bahwa baseUrl ini seharusnya diubah via app.ini ternyata salah, kami selanjutnya menemukan bahwa ada orang yang mengubah baseUrl di bootstrap.php.
Dan.. setelah mengikuti itu pun.. tetap saja aplikasi merefer ke CSS dan JS yang ditulis tanpa prefix baseUrl yang baru diset..
Penelusuran lebih lanjut, dengan lead dari seseorang dari kami yang menunjukkan bahwa kita baru menset baseUrl di controller, di mana ada kode pada view mengasumsikan keberadaan $this->baseUrl, yang mana.. ternyata bukan standar Zend Framework..
Mengutip seorang teman yang lebih senior, ternyata embe itu bukan kuda, memang Controller dengan View itu berbeda.. (lain dengan CodeIgniter ya, di mana $this di Controller ekivalen dengan $this di View)
Setelah browsing lebih lanjut, ketemu di blog entry ini dan juga ini, yang menjelaskan bahwa ini memang bukan standar Zend Framework, tapi kita dapat mensetnya di bootstrap.php (juga).
Intinya, cara yang standard dari Zend ialah membuat view dengan kode seperti :
<a href="<?php echo $this->url(array(
'controller' => 'user',
'action' => 'edit',
'id' => '123'
));?>">click me!</a>
untuk menggantikan
<a href="/my_app/user/edit/id/123/">click me!</a>

Tetapi ada cara yang lain (non-standard), yaitu
<a href="<?=$this->baseUrl ?>/user/edit/id/123/">click me!</a>
Sambil menambahkan di bootstrap.php sehingga (garis besarnya) ada fragmen seperti berikut:
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
//view renderer (from the helper broker)
if (is_null($viewRenderer->view)) {
//force instantiation of the view

$frontController = Zend_Controller_Front::getInstance();

//... additional front controller setup goes here ...

//set your base URL here

$viewRenderer->view->baseUrl = $frontController->getBaseUrl();
//set baseUrl for views, retrieved from the front controller

$response = $frontController->dispatch();
//do... something!
What a configuration. Sebetulnya kalo programmer aslinya (hiudah pakai url helper semua bakal beres. Dan ternyata, masih banyak URL yang ditulis bahkan tanpa referensi ke $this->baseUrl ataupun $this->url(...), yang harus ditulis ulang supaya aplikasi dapat hidup di dalam sebuah folder di bawah webroot.
The moral is.. know your framework well.. or else you'll be shot in

What? No delete event in Liferay Social Office?

A strange thing indeed, for some company to release a beta software which is not functionally complete. I always thought that a beta software is fully functional but without a production-grade stability. Of course, the software industry has its historical anti-example such as QuarkXpress (3.3 or 4, I forgot) which had an alpha release, beta release, and gamma release, before the true 'Release'.
Liferay Social Office is a simplification of Liferay Portal, configured for optimum social interaction, and in my opinion, knowledge sharing and management. What they really do is rewrite some GUI codes so the resulting UI is not too complicated to master. But here lies the catch. You could create a new Calendar Event, but there is no user interface from where you could delete the event.
Someone posted the question to Liferay's forums, and the question was answered with something like
.. er.. we would include the delete functionality in the next release ..
That is not an acceptable answer for me, because we were trying to use this Social Office for one of our client departments. So, for the meantime, I must be content with adding these lines :
<c:if test="<%= CalEventPermission.contains(permissionChecker, event, ActionKeys.DELETE) %>">
<portlet:actionURL windowState="<%= WindowState.MAXIMIZED.toString() %>" var="deleteURL">
<portlet:param name="struts_action" value="/calendar/edit_event" />
<portlet:param name="<%= Constants.CMD %>" value="<%= Constants.DELETE %>" />
<portlet:param name="redirect" value="<%= redirect %>" />
<portlet:param name="eventId" value="<%= String.valueOf(event.getEventId()) %>" />
<liferay-ui:icon-delete url="<%= deleteURL %>" />

into the webapps/ROOT/html/portlet/calendar/view_event.jsp.

Wednesday, February 4, 2009

Javascript Confusion

Ketika saya dulu mencoba library/framework jQuery, muncul sebuah pertanyaan, kapan kita mulai menggunakan framework/javascript library ? Kapan benefitnya melebihi costnya, misalnya pada waktu eksekusi halaman, kurva pembelajaran.. Pada saat itu performansi jQuery kurang memuaskan untuk kebutuhan kami. Namun karena ga begitu ngerti javascript juga, akhirnya dibiarkan pake jQuery :).
Pada kesempatan berikutnya, saya dan teman saya membuat sebuah aplikasi sederhana dengan deadline yang lumayan ketat. Javascript dihindari karena belum begitu paham dan masalah cross-browser compatibility yang lumayan pelik. Tapi, pada suatu halaman, kita terpaksa menggunakan javascript untuk membuat dua buah radio group saling terkait satu sama lain, yaitu radio group kedua hanya boleh digunakan pada saat sebuah radio button tertentu di group pertama dipilih. Cuma sebuah script onclick, dan script yang dijalankan ketika halaman diload untuk mendisable radio group kedua pada awal halaman. Kenapa nggak di PHP? Takutnya kalau user mendisable javascript, dan kondisi awal halaman sudah di-disable, dia sama sekali tidak bisa memilih radio group kedua.. Biarlah aplikasi tetap berfungsi bagi user tanpa javascript, dengan degraded functionality.
Dengan kebutuhan se-simple itu, ternyata membutuhkan berjam-jam.. dan belum bisa juga menemukan versi yang berfungsi di Internet Explorer maupun Firefox. Akhirnya, aku taruh jquery.js di folder js, dan mulai menggunakannya. Sepuluh menit pertama, sudah bisa menemukan versi yang berjalan baik di IE maupun Firefox.. Meskipun belum sepenuhnya sesuai dengan yang diharapkan. Setelah tweaking lebih lanjut, dan mencoba-coba beberapa pilihan desain (mau didisable ato dihidden ya.. :) ), akhirnya selesai.. dengan empat baris perintah jQuery :) Ya, memang satu baris jQuery itu udah bisa macam-macam.. seperti :
perintah satu baris ini mendisable semua children dari element dengan id 'tanya_faskes'.. Dan berfungsi untuk semua browser.
Now, kenapa kalau di IE tulisan di daerah radio groupnya ikut di disabled .. dan kalo di Firefox tidak...

Thursday, January 29, 2009

Guessing root causes

Ketika muncul suatu masalah, sering kita hanya dapat mengenali gejala. Dan kemudian melakukan perbaikan berdasarkan gejala tadi. Dan hanya kadang-kadang kita dapat mengenalil root cause, sehingga dapat melakukan perbaikan yang lebih menyeluruh. Seperti hari ini, seorang pengembang mengalami masalah tidak dapat melakukan pembuatan web service di sistem SAP Development. Sebelumnya, di sistem lain yang mirip sandbox, pembuatan web service ini sudah pernah dilakukan. Karena dulu sempet nulis di Wiki, saya jadi bisa ingat lagi kejadian-kejadian ketika dahulu mengaktifkan Web Service di mesin yang lama. Dan jadi ketahuan ada satu langkah yang belum dilakukan. Tetapi.. knowledge milik kita sendiri hanya bisa membantu sejauh itu, tetap belum dapat diaktifkan, si web service itu. Dari transaksi SE80, membuka function group yang tepat, kemudian klik kanan, create web service.. gagal di langkah terakhir wizard.
Transaksi SU53, melihat event kegagalan authorization terakhir .. didapatlah authorization object yang diperlukan untuk melanjutkan step pembuatan web service. Namun setelah authorization object ini didapat, muncul kegagalan berikutnya.. dan lewat SU53 lagi, didapat satu authorization object yang lain, yang belum dimiliki user kita.
This is getting tiresome, mengingat proses memberikan authorization object ke user harus melewati pihak lain, dan kadang-kadang harus menunggu surat-menyurat (you know, some things must be official). Akhirnya kembali ke Google, memanfaatkan pengetahuan kolektif umat manusia (ceile..). Aku mengharapkan menemukan list authorization object yang lengkap di situ. Sayangnya mr Google hanya menemukan halaman yang publik di Internet, dan tidak ada informasi definitif mengenai daftar authorization object di situ.. tapi sebuah keyword yang ultra-important di dunia SAP menarik perhatianku di antara hasil search Google : 'according to SAP Notes 913944 ...'. SAP Notes adalah elemen dari knowledge base SAP, yang hanya bisa dibuka oleh customer terdaftar SAP. Menggunakan login Bos, ke website SAP, pilih SAP notes, masukkan 913944.. voila: muncul list of authorization objects yang diperlukan untuk membuat 'Web Services Datasource'. By interpolation, object2 di situ juga akan bermanfaat kalau kita hanya ingin membuat 'Web Services'..
Could you guess what the root cause are?
Btw, cara-cara serupa di atas juga aku lakukan ketika mencoba memanggil SAP RFC via JCo library, dan kebetulan user yg digunakan untuk RFC tidak memiliki semua authentication objects yang diperlukan..

RAID5 Failure

Yak.. itu adalah problem mengerikan yang terjadi kemarin. Sebuah server yang kuinstall Centos 4.7 dan berharddisk empat buah, dipasangi RAID5, dan sudah beberapa bulan melayani kami sebagai Server Linux SAP satu-satunya yang diinstall from scratch. Di situ cuma diinstall aplikasi SAP GRC (Governance, Risk & Compliance) dan SAP Netweaver (+Oracle) sebagai pondasinya.
Kemarin aku mulai menghandle masalah ini, karena penasaran (RAID5 kok bisa fail).
Konsep RAID5 yang kupasang adalah begini: dari 4 buah hard disk, data disebar ke 4 hard disk dengan informasi pelengkap (sejenis CRC mungkin), sehingga sistem tetap berfungsi meskipun salah satu hard disk fail. Ternyata, Software RAID5 di Linux memiliki beberapa karakter:
- ketika sedang beroperasi, dan satu dari 4 hard disk mati, sistem berubah mode operasional, dari normal mode ke degraded mode. Transisi ini terjadi otomatis, dan mungkin kita bisa lihat di log file.
- tetapi, ketika proses booting, salah satu dari 4 hard disk tidak bisa digunakan, sistem menolak melanjutkan booting. Mungkin idenya adalah supaya system admin mengganti dulu hard disk yang rusak sebelum melanjutkan operasional server.
Nah sebenarnya tidak ada satupun hard disk yang mati, tetapi sistem menolak melanjutkan booting. Aku masukkan CD Centos, masuk ke rescue mode.. Lihat log kernel pakai dmesg, ternyata ada sesuatu yang tidak konsisten dengan salah satu hard disknya. Browsing di internet, orang lain menyarankan untuk memaksa RAID hidup hanya dengan 3 hard disk yang ada dan kemudian meng-add lagi hard disk ke-4 (sda2) ke dalam sistem RAID yg ada. (OK, sebetulnya komponen Software RADI bukanlah hard disk tetapi partisi, software raid yg ini dibangun dari 4 partisi di 4 hard disk berbeda).
Langkah-langkah mdadm --assemble --run /dev/md2 /dev/sda2 /dev/sdb1 /dev/sdc1 /dev/sdd1 telah kujalankan, tetapi tetap saja si RAID tidak mau hidup. Gejalanya ialah isi /proc/mdstat yang menyatakan si-md2 ini inactive.
Akhirnya sistem mau berfungsi setelah ditambah parameter --force. Dan ternyata, bukan hanya si sda2 yang tidak konsisten, sdb1 juga, dan --force tadi memaksa sistem mengganggap dia baik-baik saja. Setelah itu, restart, dan biarkan dia rekonstruksi..
Sebetulnya, ini semua gara-gara kernel panic yang muncul sesekali. Dan setelah kernel panic, mungkin ada data yang belum terkirim ke harddisk-harddisk itu. Sebenernya sih ga terlalu parah kan, cuma beberapa sektor tidak sync, apalagi aku pakai ext3 yang secara default pakai journalling, tetapi metoda failsafe si RAID ini yang mencegah sistem berfungsi sampai semuanya beres (atau dianggap beres :) )

Monday, January 26, 2009

Tidak bisa buka popup window di IE6

Hari ini revisit ke suatu masalah yang mungkin umum terjadi.. Yaitu instalasi Internet Explorer yang ngadat. Dulu waktu kami mroyek di Merpati, pernah kejadian seperti ini, dan kalau tidak salah kami solve dengan mengupdate service pack Windows di semua komputer OP (Planning). Tapi hari ini seorang temanku yang lain mengalami masalah yang agak berbeda, service pack nya sudah maximum, dan setelah mengalami trouble dengan IE 7 ia melakukan uninstall. Ternyata setelah uninstall, Internet Explorer (yang kini versi 6) masih ngadat. Ia tidak mau membuka pop up window, bahkan yang dicoding tanpa JavaScript sekalipun (just a simple A HREF="_BLANK" dst..).
Kemudian aku googling dan menemukan orang dengan masalah serupa. Meskipun masalah sebenarnya berbeda, tetapi orang ini sudah menulis semua langkah-langkah yang ia lakukan untuk meresolve masalah ini (dan gagal). Langkah terakhirnya (menginstall ulang Autodesk Trueview 2009), sama sekali tidak generik, dan tidak relevan untuk kasus ini. Untungnya, salah satu dari langkah-langkah sebelumnya berguna untuk Fino (menurutnya, langkah yang benar-benar membuat perbedaan adalah bagian regsvr32):
- membersihkan history dan temp files (

- melakukan Restore/Reset Default Settings dari IE6

- Menginstall ulang IE6 berdasarkan metoda no. 4 di artikel

- merestart print spooler

- menginstall ulang Java

- meregister ulang file-file berikut ini (lakukan di command prompt):

> cd \windows\system32

> regsvr32 Shdocvw.dll
> regsvr32 Shell32.dll
> regsvr32 Oleaut32.dll
> regsvr32 Actxprxy.dll
> regsvr32 Mshtml.dll
> regsvr32 Urlmon.dll

- menscan seluruh sistem dengan dua antivirus berbeda

Daftar langkah ini mungkin berguna jika ada orang yang perlu memperbaiki IE-nya yang ngadat.
By the way, kalau masih ngadat, saya menyarankan melihat list Add-Ons di Internet Options:Manage Add-Ons, dan mulai mendisable add-ons yang tidak penting (atau bahkan menguninstall program pembawa add-ons tsb)

Thursday, January 22, 2009

SCP Tunneling via SSH

Beberapa minggu yang lalu aku diajari trik ini oleh neni, kayaknya sih bakal berguna untuk orang lain..
Kondisi awal: sebuah server (katakan server A) hanya bisa dihubungi lewat server B. Jika kita ingin mengakses file di server A, biasanya kita terpaksa masuk via SSH ke server B, kemudian SCP file dari server A ke server B ato sebaliknya, dan mengeditnya di server B (pakai vi.. ato pico..). Cara ini terlalu ribet untuk pengeditan sederhana.
Solusi neni: Bukalah WinSCP (eh ternyata free ya..), kemudian setting koneksi langsung ke server A, tapi kali ini pilihlah Advanced options dan Connection:Tunnel. Di Tunneling via SSH, isi dengan informasi koneksi ke server B.

Kemudian, untuk lebih nyaman lagi, gunakan Notepad++ sebagai text editor, coba pilih menu 'Preferences' dan isikan seperti pada gambar dibawah ini .

Wednesday, January 21, 2009


Hari ini aku melanjutkan apa yang dikerjakan Neni dengan PEAR::Mail di server e-recruitment (yang sebetulnya.. pekerjaan saya ya harusnya :) ). Status sebelumnya, PEAR::Mail mampu mengirim ke smtp ingoing milik telkom. Tetapi tidak dapat mengirimkan email outgoing ( ke luar telkom) karena smtp yang itu kan.. memang khusus untuk email masuk. Untuk dapat mengirimkan email keluar, kita butuh outgoing SMTP. Kalo dari dalam Telkom, tinggal pakai SMTP-nya domino, berikan authentication sesuai username & password dari account email internal yg dipakai. Nah, kalo dari luar..(servernya kan Internet-facing, technically dia ada di luar intranet Telkom) kita butuh outgoing SMTP yang bisa dipakai anonymously (atau kalau gak, username&password yg bisa dipakai untuk ngirim email). Siang ini dapat bocoran nama salah satu anonynous SMTP punya telkom yang bisa digunakan.
Tetapi percobaan2 awal gagal terus. Ga tau kenapa. Kemudian kuaktifkan error logging PHP (lihat set_error_handler di PHP manual) dengan kode seperti ini (I hate coding without frameworks) :
function myErrorHandler($errno, $errstr, $errfile, $errline)
error_log("at $errfile line $errline : $errstr ($errno)\n",3,"/usr/local/apache/htdocs/erecrut/logs/log1.log");
return true;
$old_error_handler = set_error_handler("myErrorHandler");

ok.. keluar errornya cuma sedikit, dan tidak meaningful (cuma notice nggak penting yang ketangkep).
Setelah diingat2, dulu Neni bermasalah dalam mencek error yang muncul (kalo ga salah, kadang tipenya boolean, kadang tipenya object). Dulu aku suruh ga usah dicek aja (karena ga tau cara yg benernya). Dan sekarang saatnya untuk mencari cara yang bener.. :)
Ternyata cara error handling PEAR::Mail yg bener itu mirip seperti ini :
$mail = $smtp->send($to, $headers, $body);
if (PEAR::isError($mail))
error_log("PEAR error: ".var_export($mail,true)."\n",3,"/usr/local/apache/htdocs/erecrut/logs/pearerror.log");
biarkan PEAR yang meriksa itu error ato bukan. Di sini aku pakai variasi error_log yang naruh pesan ke file, dan karena ngga ngerti pathnya relatif ke mana aku pake path absolut. Soalnya directory lognya harus di- chmod o+rw dulu.
Ternyata.. Ada error yang ditangkap file log ini.. Masalahnya ialah email kita ditolak oleh SMTP server gara2 mengirimkan SPAM. Pesannya kira2 seperti ini: 'localhost rejected because you sent SPAM emails'. Terpikir, mungkin ga ini ditolak gara-gara string nama servernya masih localhost ? Jangan2 dia mengenali komputer yang mengirim email cuma dari string nama servernya? String nama server ini dikirimkan di SMTP ketika memulai percakapan (HELO namaserver). Aku ganti nama servernya dan presto.. all is well.. :
$smtp = Mail::factory('smtp',
array ('host' => $host,
'port' => $port, 'localhost' => ''));

Tuesday, January 20, 2009

How to Recreate MySQL System Tables

You might wonder, why would I need to recreate MySQL system tables. Well, the case is that my WoS folder has gotten pretty big, and I lost my original file. And the website doesn't carry WoS anymore. (now its called MoWes, and for some reason I still trust the old' WoS than the MoWes). I need to copy this to another computer, without the 270 MB-or-so MySQL datafiles. So the solution is-> just copy them, excluding the data folder inside mysql folder. But the newly copied MySQL won't start. It created new datafiles all right, but it still won't start. Examining the log files, it said something about missing grant tables.
So I added this option when starting mysql:
bin\mysqld-nt --skip-grant-tables
This forced it to start even without grant tables. Now, the grant tables still must be created, and after browsing for a while I found out that we could initialize the grant tables using these scripts:
  • mysql_system_tables.sql
  • mysql_system_tables_data.sql
  • fill_help_tables.sql
These files cannot be found in WoS's mysql folder. Fortunately I found them in /usr/share/mysql folder in my Ubuntu box, assuming that these files are compatible with WoS's mysql I begin running the scripts using MySQL Query Browser.
The first run spits errors. Seems that I must manually do these before those scripts:
create database mysql;
use mysql;
Then I retried running mysql_system_tables, then all the other scripts. After restarting the mysql server, all seems to be working correctly.

PHP modules' DLL hell

In Windows platform, the webserver package of my choice is MoWes (mobile webserver). In the past it is called WoS (Webserver on a stick). We just copy the folder from one computer to another, and run its exe-file, instantly we have a Apache - MySQL - PHP triad running without any installation hassles.
But recently, I copied the MoWes onto two servers, and I cant seem to load both PHP_OCI8 and PHP_LDAP modules. After a few wrong turns, finally I used Microsoft Visual Studio's Dependency Walker tool. And voila - both of the DLL's problems were shown before my eyes.

PHP_LDAP's problem was SSLEAY not installed. PHP_OCI8's problem was that the OCI.DLL is in the AMD 64-bit architecture (equivalent to Intel EM64T architecture) while the php/apache system is in 32-bit architecture. Now, where did I keep the downloaded the oracle instant client for win32..

Tuesday, January 6, 2009

Strange Oracle Problems: Oracle database won't start

One of the desktops in my office is being used as a Server. It has Quad-core AMD Phenom X4, and 4 hard drives in Linux Software RAID 5 Configuration (Ok, it is a strange beast, because I was the one who chose the components and bought the system). We installed Centos 4.7 (64-bit), Oracle 10g, and SAP Netweaver. It is very much a hassle to set up, the 64-bit Oracle. But recently a strange error pops up when starting the Oracle database. It says, the shared_pool_reserved_size is out-of-bound (too large). The current setting is about 100 MB. At first, I wonders is this related to problems occured before, because the mixups between 64-bit and 32-bit parts of the Oracle RDBMS. I thought, the valid range of shared_pool_reserved_size is determined by the architecture (that is-64 or 32 bit).
Then, after some readings and pondering, I found out that not the shared_pool_reserved_size that was incorrect, it was the shared_pool. And it has nothing to do with the 64-bit architecture. Current setting of shared_pool is at 157MB, and shared_pool_reserved_size is only allowed from min_reserved_size to 0.5*shared_pool. The correct shared_pool setting is 1570MB (1.5 GB), and some mishaps make one of the numbers truncated..
Learnt some new Oracle commands while fixing this issue.. these could be run even when the database is idle (not mounted, not started).
/home/oraac1>sqlplus /nolog
This command creates a text-based parameter file from the existing binary parameter file. Which file? The default one. This would differ between systems, but I bet the default one is the one thats being used to start the Oracle RDBMS in normal conditions. In my windows Oracle XE, this is C:\oraclexe\app\oracle\product\10.2.0\server\dbs\SPFILEXE.ORA. In the Linux Oracle, this is /oracle/AC1/102_64/dbs/spfileAC1.ora, and the created text-based parameter file would be /oracle/AC1/102_64/dbs/initAC1.ora.
After the text-based PFILE was created, I just correct the shared_pool line (add another 0 in the end). Then..
This command creates a binary startup parameter file from the existing text parameter file. Similar to the previous one, this also refers to default parameter files.
ok.. that done, I just need to start the whole SAP-Oracle system using startsap, and all is well.

MySQL & Oracle back-and-forth

Do you know that Oracle database could be migrated into MySQL database, and vice-versa? Use Oracle's Schema Migration functionality in the free Oracle SQLDeveloper to migrate from MySQL to Oracle, use MySQL Migration Toolkit to migrate from Oracle to MySQL.

Hint: it is easier to migrate from Oracle to MySQL, than from MySQL to Oracle.. but it is also easier than migrating from Oracle 10g to Oracle 9.2..

If anyone interest, I could post the details..