Mei 23, 2014

Maven repository priority in Gradle

If you get an error like this when you execute gradle build, it means that there is something wrong with your maven repository priority (just an example):

Checksum missing at http://www.systap.com/maven/releases/org/semanticweb/yars/nxparser/1.2.3/nxparser-1.2.3.pom.sha1 due to: For input string: "<!"
Download http://www.systap.com/maven/releases/org/semanticweb/yars/nxparser/1.2.3/nxparser-1.2.3.pom
[Fatal Error] nxparser-1.2.3.pom:2:10: Already seen doctype.


Below is a snapshot of my build.gradle:


    // maven repo for BigData - as embedded RDF database
    // we are looking for BigData with Blueprints also
    // needed by BigData: nxparser
    maven { url "http://www.systap.com/maven/releases" }
    maven { url "http://nxparser.googlecode.com/svn/repository" }



My BigData repository need nxparser, but the problem is, maven repo for nxparser reside after BigData repo, so gradle doesn't know that it has to fetch nxparser from repository below. Change the order into this to fix the problem:


    // maven repo for BigData - as embedded RDF database
    // we are looking for BigData with Blueprints also
    // needed by BigData: nxparser
    maven { url "http://nxparser.googlecode.com/svn/repository" }
    maven { url "http://www.systap.com/maven/releases" }



April 13, 2014

Gradle Untuk Mengelola Repo Lokal Maven

Saat pertama kali menggunakan Gradle, saya cukup kerepotan mempelajari tool ini karena dokumentasinya lebih mirip dengan manual. Tantangan yang pertama saya peroleh adalah menggunakan repository maven di komputer saya karena kadang kala software yang saya kembangkan berupa API (Application Programming Interface). Keinginan saya sederhana:

  1. Develop pustaka (API)
  2. Kompilasi dan build API dalam format .jar
  3. Push .jar ke repositori lokal maven (API, Javadoc, dan source code)
  4. API (.jar) di repositori lokal tersebut siap digunakan untuk pengembangan software berikutnya

Membaca manual Gradle cukup merepotkan untuk hal sederhana tersebut, jadi saya akan uraikan cara sederhana untuk keperluan tersebut. Pada dasarnya ada 3 file yang akan banyak digunakan:

  1. build.gradle di proyek pustaka API
  2. gradle.properties untuk berbagai properties yang diperlukan di proyek pustaka API
  3. build.gradle di proyek yang akan menggunakan file .jar tersebut

build.gradle di proyek pustaka API

Perhatikan, plugin yang digunakan adalah 'maven'. Perhatikan juga di bagian bawah mulai dari bagian untuk mengkonfigurasi POM.


apply plugin: 'java'
apply plugin: 'maven'

sourceCompatibility = '1.8'
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'


repositories {

 mavenLocal()
 mavenCentral()

 maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }

 // definisi URL utk repo lainnya ...
  
}

dependencies {

 // contoh dependency untuk compile
 compile group: 'com.bigdata', name: 'bigdata', version: '1.3.0'
 
 // dependency untuk test                     
 testCompile group: 'junit', name: 'junit', version: '4.10'

}

test {

 /* Configure which tests are included
 include 'org/foo/**'
 exclude 'org/boo/**'
 */

 maxParallelForks = 5
 maxHeapSize = '1024m'

}

// bagian ini ke bawah yang penting untuk mengkonfigurasi POM

configure(install.repositories.mavenInstaller) {
 pom.project {
  groupId 'name.bpdp'
  artifactId 'turgo'
  inceptionYear '2014'
  packaging 'jar'
  licenses {
   license {
    name 'Eclipse Public License (Version 1.0)'
    url 'http://www.eclipse.org/legal/epl-v10.html'
    distribution 'repo'
   }
  }
 }
}

// untuk sources.jar
task sourcesJar(type: Jar, dependsOn:classes) {
 classifier = 'sources'
 from sourceSets.main.allSource
}

// untuk javadoc.jar
task javadocJar(type: Jar, dependsOn:javadoc) {
 classifier = 'javadoc'
 from javadoc.destinationDir
}

// artifacts yang di-push selain .jar API
artifacts {
 archives sourcesJar
 archives javadocJar
}

gradle.properties

Berisi properties dari proyek. Isinya adalah sebagai berikut:

version=0.0.1
group=name.bpdp.turgo

Perhatikan, tidak boleh menggunakan tanda petik string untuk value karena akan menyebabkan error di task javadoc:

Illegal package name: "0.0.1"
Illegal package name: " API"

Error ini seringkali membingungkan karena tidak jelas, jadi jika menemui error seperti itu, periksa gradle.properties.

Setelah itu, task "install" ($ gradle install) akan mem-build API, menghasilkan .jar, menghasilkan .jar untuk javadoc dan sources, kemudian mem-push semua .jar ke repo lokal seperti berikut ini:

build.gradle di proyek yang akan menggunakan .jar

Sederhana saja, jika sudah di-push, tinggal cantumkan mavenLocal() di repositories dan deklarasikan dependency compile untuk .jar tersebut. Berikut ini adalah contohnya:

pply plugin: 'java'
apply plugin: 'application'

sourceCompatibility = 1.8
version = '1.0'

mainClassName = 'turgo.examples.hello.HelloTurgo'

repositories {

 mavenLocal()
 mavenCentral()

 maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }

}

dependencies {
 compile group: 'name.bpdp', name: 'turgo', version: '0.0.1'
 testCompile group: 'junit', name: 'junit', version: '4.11'
}

That's all there is to say. :)

Oktober 21, 2013

Awesome Window Manager (3.5.2) and Java 7 GUI Problem

Some complaints have been reported about Java GUI (AWT/Swing) that does not behave correctly under Java GUI. This problem come in the form of empty contents in Java GUI window and also some weird behaviour in Java GUI menu (wrong cursor pointer position, menu doesn't want to display its contents without click and hold mouse button).

This problem usually only happens in some exotic non-reparenting window manager such as awesome, dwm, subtle, and probably others. I use only awesome so this is my experience in awesome window manager. Even when since release 3.5.x, awesome has become a reparenting window manager, the weird behaviour above still exists (the menu problem). Uncommit source code is not an option for me.

If you experience this, there are two things that can be done:
  1. Change JDK from Oracle JDK to OpenJDK. I tested with OpenJDK 2.4.2 (IcedTea) and Awesome 3.5.2. This works very well without any extra steps.
  2. Use wmname and execute "wmname LG3D" from shell before running Java GUI application. This option is needed if we use Oracle JDK. I tested this with Oracle JDK 1.7.0_u45.
If you want to use OpenJDK and are so awfully lazy to compile it by yourself (just like myself), you may grab the latest binary for Linux in OpenJDK unofficial build. This works very well.

Oktober 01, 2013

Introspeksi Untuk Rekayasa Web: Aplikasi Web atau Sistem Web?

Selama ini kita cenderung menyebut istilah software yang ada di Internet dan menggunakan infrastruktur dari W3C untuk antarmuka dengan manusia melalui browser sebagai aplikasi Web. Istilah ini mempunyai konotasi sendirian dan hanya dimaksudkan untuk berinteraksi dengan manusia saja. Secara normal, kondisi ini seperti kondisi manusia yang egois: "ini yang saya punyai, silahkan kalau kamu mau berkomunikasi dengan saya, sesuaikan dengan kondisi saya". Tentu tidak se-ekstrim itu, tetapi secara konsep memang demikian. Perhatikan, selama ini saat kita melakukan rekayasa, yang kita pikirkan adalah software itu sendiri serta bagaimana software tersebut bisa dibaca dan mempermudah navigasi manusia saat menggunakan software tersebut. Hasil dari ini bisa ditebak:
  1. Standarisasi komponen antarmuka Web di browser: HTML, CSS, PNG, dll
  2. Masalah kesesuaian browser dengan standar tersebut (para desainer antarmuka Web pasti ingat dengan sulitnya membuat antarmuka Web mereka bisa bekerja lintas browser, dan muncullah berbagai macam kutukan terutama terhadap salah satu browser dari perusahaan besar).
  3. JavaScript overkill: merancang dan mengimplementasikan halaman Web yang dinamis tentu tidak bisa menggunakan HTML (saja), tetapi memerlukan JavaScript. Jaman dahulu (sekitar tahun 2000-an), jauh lebih parah lagi karena ada masalah standarisasi JavaScript sehingga akhirnya diserahkan ke ECMA dan dibuat spesifikasi menjadi ECMAScript. Saat itu ada JavaScript (Netscape) dan JScript (Microsoft), belum lagi setelah itu Microsoft juga membuat VBScript. Ini masa-masa gelap untuk para perancang halaman Web. Meski sekarang tidak seperti itu lagi, hanya ada JavaScript, masalah standarisasi ini juga masih menjadi masalah turunan (belum termasuk Google yang mengeluarkan Dart, meski bisa dikompilasi ke JavaScript). Buka kode sumber dari halaman Web, biasanya akan muncul banyak sekali snippet JavaScript.
Sebenarnya kita perlu berpikir lebih sederhana, bahwa software di Web adalah software yang digunakan untuk mendukung interaksi sosial manusia (silahkan baca kembali note saya sebelum ini). Dengan menggunakan pola pikir seperti itu, maka kita seharusnya mulai mencurahkan pemikiran ke bagaimana membuat software tersebut bisa membantu interaksi sosial manusia. Domain ini yang sekarang dikenal dengan istilah Pragmatic Web.

Pada domain Pragmatic Web, tidak ada lagi (hanya) aplikasi Web. Mengapa? Sederhana saja, software yang akan dikembangkan merupakan software untuk mendukung interaksi sosial manusia sehingga harus bersifat kontekstual, atau context-aware Web. Dalam konteks ini, kita harus membedakan antara web services dengan services. Web services berada pada ruang lingkup lapisan informasi sedangkan services berada pada ruang lingkup kehidupan nyata. Dalam kondisi seperti ini, rekayasa software di Web tidak mungkin hanya berada pada sisi penyedia (server), tetapi juga harus memikirkan bagaimana software agent di sisi klien bisa berkomunikasi dengan software agent di sisi penyedia.

Menggeser paradigma software di Web dari software yang egois menjadi suatu sistem adalah salah satu kunci untuk mengurai benang kusut di ranah rekayasa Web yang sudah terlalu banyak menghabiskan waktu di sisi (hanya) aplikasi Web.  Semoga.

Aplikasi Web di Masa Depan: Semakin Konvergen dengan Teknologi Agen

Agen bukan merupakan hal baru di dunia informatika. Sejak perkembangan AI (Artificial Intelligence - Kecerdasan Buatan), agen sebenarnya merupakan inti dari pembahasan. Jika dirunut sejak awal, kita bisa melihat teori agensi pada pemodelan ekonomi (principal-agents). Teori agensi pada pemodelan tersebut mendasarkan pada pemikiran bahwa principal selaku pemilik merekrut, menggaji, mempekerjakan agents untuk melakukan pekerjaan-pekerjaan tertentu. Tentu saja para agents tersebut harus mempunyai kecerdasan (keahlian) tertentu dan bisa bersikap serta mengambil keputusan (dalam ruang lingkupnya) terkait dengan tujuan kerjasama tersebut. Dalam kerjasama tersebut, dipastikan tidak akan muncul agency problems, yaitu konflik yang muncul karena perbedaan goals di antara mereka. Konsep inilah yang sebenarnya ingin dikerjakan pada AI. Sederhana dalam penggambaran, tetapi sangat sulit dalam implementasi. Agen itu sendiri bisa berupa agen tunggal serta MAS (Multi-Agent Systems). Agen tunggal tentu lebih mudah diimplementasikan. MAS merupakan topik yang sangat sulit (jaman dulu disebut sebagai DAI - Distributed Artificial Intelligence). Kompleksitas MAS disebabkan karena adanya interaksi antar agen.

Sementara itu, perkembangan teknologi jaringan yang sudah sampai tingkat konektivitas di seluruh dunia ternyata membuat perkembangan tuntutan pengguna aplikasi menjadi lebih kompleks. Ingat, semakin ringan dan semakin ingin dimanjakan, semakin sulit pekerjaan para pengembang aplikasi. Pada era ini, aplikasi pada dasarnya bisa kita bagi menjadi aplikasi yang headless serta aplikasi berbasis Web. Aplikasi headless adalah aplikasi yang tidak menggunakan user interface untuk si pemakai karena memang tidak dikhususkan untuk pemakai biasa. Pemakai menggunakan aplikasi ini, tetapi tidak menyadari jika aplikasi ini ada. Contoh sederhana aplikasi ini antara lain aplikasi crawler dari berbagai situs mesin pencari. Pemakai hanya perlu ke (misalnya) google, dan mencari kata kunci yang dikehendaki. Mekanisme dan penyediaan infrastruktur dari aplikasi tersebut kebanyakan tidak diketahui dan dipahami pemakai biasa. Aplikasi Web pada dasarnya menyediakan user interface untuk berkomunikasi dengan pemakai.

Apa keterkaitan antara kedua hal itu? Web menyedian berbagai macam sumber daya yang sangat melimpah ruah, mulai dari sumber daya yang hanya bisa dipahami oleh manusia (era Syntactic Web dengan HTML tanpa kandungan semantik) maupun sumber daya yang berupa sumber daya yang bisa "dipahami" mesin (dikenal dengan istilah sumber daya semantik - Semantic Web). Nah sekarang, kondisi seperti ini bisa memungkinkan orang untuk berpikir dalam kerangka teori agensi di atas. Pemakai menjadi pincipal, sementara agents akan berupa software: "saya ingin sesuatu dari Web, kerjakan dan berikan ke saya hasilnya" dengan seminimal mungkin intervensi ke software tersebut. Tugas para pengembang barangkali untuk memungkinkan hal-hal di atas bisa terjadi serta memungkinkan otomasi di Internet/Web seperti yang dicetuskan oleh Tim Berners-Lee pada tahun 2001:
  1. Merealisasikan software agent, dalam konteks ini sofware agent yang bisa berkomunikasi dengan si pemakai. Riset di bidang human-agent communication ini juga diperlukan, bersamaan dengan NLP (Natural Language Processing). Pemakai "berbicara" dan menyuruh agen untuk mengerjakan sesuatu on behalf of its owner. Pada konteks ini, penelitian yang dulu pernah dikembangkan oleh Terry Winograd menjadi penting (LAP - Language-Action Perspective).
  2. Merealisasikan aplikasi Web yang juga sebenarnya merupakan salah satu agen pada suatu masyarakat MAS. Agent ini mempunyai dua "muka", satu merupakan aplikasi Web dengan user interface HTML-CSS-JavaScript-etc, muka yang lain adalah agen. Agen ini merupakan wakil dari pemilik Web yang siap berkolaborasi dengan software agent dari pemakai. Komunikasi Agent-to-Agent ini juga merupakan hal yang kompleks dan merupakan salah satu standar yang dihasilkan oleh FIPA (http://www.fipa.org) berupa ACL (Agent Communication Language).
Nah, silahkan mulai bersiap-siap jika memang (berniat) terjun ke dunia pengembangan software. That should be pretty interesting. :p

Juli 21, 2013

Using Vim for Java + Gradle

Short posting. I've created a repo so that I can clone it everytime I want to create new project. See here:

https://github.com/bpdp/vim-java

Juli 19, 2013

Basis Data Graf: Titan dengan Apache Cassandra Sebagai Storage Backend

Tulisan ini merupakan kelanjutan dari tulisan sederhana tentang basis data graf sebelumnya. Kali ini saya akan menuliskan sedikit tentang memulai menggunakan Titan [1] yang merupakan basis data graf dengan kapabilitas penyimpanan dan pemrosesan data masif (web scale atau big data). Titan adalaha softwae bebas dengan lisensi Apache [2].

Titan sebenarnya terdiri atas 2 bagian:

  1. Distribusi Titan
  2. Storage backend

Distribusi Titan

Titan bisa diperoleh dari repositori Titan [3]. Versi rilis terakhir adalah 0.3.1. Hasil download adalah sebagai berikut:

$ ls
total 74744
drwxr-xr-x  2 bpdp bpdp     4096 Jul 11 06:57 .
drwxr-xr-x 25 bpdp bpdp     4096 Jul 18 10:37 ..
-rw-r--r--  1 bpdp bpdp 76521205 May 14 22:48 titan-all-0.3.1.zip
-rw-r--r--  1 bpdp bpdp       64 Jun 24 12:43 url
$ cat url 
http://s3.thinkaurelius.com/downloads/titan/titan-all-0.3.1.zip
$ 


Mendownload distribusi ini saja tidak cukup, karena distribusi ini "hanya" menyediakan core dari Titan, tidak ada komponen dari software yang berfungsi sebagai native storage backend. Secara umum, penggunaan Titan meliputi aktivasi storage backend (baik secara lokal maupun cluster) kemudian mengkonfigurasi Titan untuk menggunakan storage backend tersebut.

Storage Backend

Titan menggunakan basis data lainnya sebagai "tempat" untuk menyimpan data. Software yang bisa digunakan untuk keperluan ini adalah:
1. Apache Cassandra [4]
2. Apache HBase [5]
3. Oracle BerkeleyDB [6]
Mempelajari Titan saja tidak cukup, pemahaman yang memadai tentang storage backend juga diperlukan. Titan adalah basis data untuk data yang masif sehingga storage backend-nya pun juga software basis data kelas berat. Tingkat kompleksitas dari storage backend bervariasi, tetapi Apache HBase barangkali merupakan storage backend yang paling kompleks.

Memulai Storage Backend

Storage backend yang akan digunakan disini adalah Apache Cassandra. Versi yang digunakan adalah versi terakhir saat tulisan ini ditulis: 1.2.6. Langkah untuk memulai Apache Cassandra sangat mudah dan pada dasarnya hanya meliputi konfigurasi PATH serta file konfigurasi cassandra.yaml. Tarball dari Apache Cassandra pada tulisan ini akan diekstrak di $HOME/software/apache-cassandra-1.2.6 (direktori ini akan dirujuk dengan variabel $CASSANDRA_HOME). Data akan disimpan di $HOME/db/cassandra. Konfigurasi:

$HOME/.bash_profile

...
...
$CASSANDRA_HOME=$HOME/software/apache-cassandra-1.2.6
export PATH=$PATH:$CASSANDRA_HOME/bin
...
...


cassandra.yaml

Ada banyak konfigurasi yang bisa diatur pada file ini [7], tetapi pada bagian ini hanya 4 saja yang akan saya ubah:

cluster_name: 'KintamaniCluster'
data_file_directories:
    - /home/bpdp/db/cassandra/data
# commit log
commitlog_directory: /home/bpdp/db/cassandra/commitlog
saved_caches_directory: /home/bpdp/db/cassandra/saved_caches


Catatan: direktori-direktori diatas dibuat dulu jika belum ada.

Setelah itu, untuk memulai Apache Cassandra, login ke shell baru, setelah itu:

$ cassandra -f

Argumen -f digunakan untuk menampilkan hasil eksekusi di latar depan sehingga kita bisa melihat jika terjadi masalah. Hasilnya nanti akan banyak sekali, saya tampilkan bagian akhirnya saja:

...
...
INFO 05:07:53,670 Node localhost/127.0.0.1 state jump to normal
INFO 05:07:53,686 Startup completed! Now serving reads.
INFO 05:07:53,948 Starting listening for CQL clients on localhost/127.0.0.1:9042...
INFO 05:07:54,010 Binding thrift service to localhost/127.0.0.1:9160
INFO 05:07:54,083 Using TFramedTransport with a max frame size of 15728640 bytes.
INFO 05:07:54,090 Using synchronous/threadpool thrift server on localhost : 9160
INFO 05:07:54,090 Listening for thrift clients...
INFO 05:12:51,681 Compacting [SSTableReader(path='/home/bpdp/db/cassandra/data/system/schema_columnfamilies/system-schema_columnfamilies-ic-15-Data.db'), SSTableReader(path='/home/bpdp/db/cassandra/data/system/schema_columnfamilies/system-schema_columnfamilies-ic-13-Data.db'), SSTableReader(path='/home/bpdp/db/cassandra/data/system/schema_columnfamilies/system-schema_columnfamilies-ic-16-Data.db'), SSTableReader(path='/home/bpdp/db/cassandra/data/system/schema_columnfamilies/system-schema_columnfamilies-ic-14-Data.db')]
INFO 05:12:52,233 Compacted 4 sstables to [/home/bpdp/db/cassandra/data/system/schema_columnfamilies/system-schema_columnfamilies-ic-17,].  20,712 bytes to 6,933 (~33% of original) in 550ms = 0.012021MB/s.  10 total rows, 4 unique.  Row merge counts were {1:2, 2:0, 3:0, 4:2, }


Titan

Setelah men-donwload Titan, ekstrak hasil download tersebut di suatu direktori tertentu (penulis menempatkan di $HOME/software/titan, selanjutnya akan disebut $TITAN_HOME). Saya juga menempatkan variabel lingkungan PATH di .bash_profile sebagai berikut:

...
...
$TITAN_HOME=$HOME/software/titan
export PATH=$PATH:$TITAN_HOME/bin
...
...


Titan mendukung penuh TinkerPop stack sehingga kita bisa menggunakan tools dari TinkerPop stack, baik untuk REPL (menggunakan Gremlin) maupun dalam source code. Contoh sesi REPL dari Gremlin adalah sebagai berikut:

$ gremlin.sh 

         \,,,/
         (o o)
-----oOOo-(_)-oOOo-----
gremlin> conf = new BaseConfiguration();
==>org.apache.commons.configuration.BaseConfiguration@13015e8
gremlin> conf.setProperty("storage.backend","cassandra");
==>null
gremlin> conf.setProperty("storage.hostname","127.0.0.1");
==>null
gremlin> g = TitanFactory.open(conf);
13/07/20 06:29:02 INFO impl.ConnectionPoolMBeanManager: Registering mbean: com.netflix.MonitoredResources:type=ASTYANAX,name=ClusterTitanConnectionPool,ServiceType=connectionpool
13/07/20 06:29:02 INFO impl.CountingConnectionPoolMonitor: AddHost: 127.0.0.1
13/07/20 06:29:02 INFO impl.ConnectionPoolMBeanManager: Registering mbean: com.netflix.MonitoredResources:type=ASTYANAX,name=KeyspaceTitanConnectionPool,ServiceType=connectionpool
13/07/20 06:29:02 INFO impl.CountingConnectionPoolMonitor: AddHost: 127.0.0.1
==>titangraph[cassandra:127.0.0.1]
gremlin> bambang = g.addVertex(null);
==>v[360004]
gremlin> domain = g.addVertex(null);
==>v[360008]
gremlin> bambang.setProperty("name", "Bambang Purnomosidi");
==>null
gremlin> domain.setProperty("name", "Pragmatic Web");
==>null
gremlin> e = g.addEdge(null, bambang, domain, "researching");
==>e[7ygD-1vEw-2F0LaTPQTs][360004-researching->360008]
gremlin> print e.getVertex(Direction.OUT).getProperty("name") + "---" + e.getLabel() + "-->" + e.getVertex(Direction.IN).getProperty("name");
Bambang Purnomosidi---researching-->Pragmatic Web==>null
gremlin> 


Jika ingin membuat program yang memanfaatkan Titan dan storage backend-nya ini, pengetahuan yang diperlukan  akan lebih kompleks dan memerlukan tulisan tersendiri. We'll talk about it later. Stay tune.

Proses Selanjutnya

Setelah berbagai setting ini, jika komputer mati (untuk server seharusnya tidak :-D), setiap kali login, kita sudah bisa langsung mengeksekusi Apache Cassandra, setelah itu mengaktifkan Titan (tidak perlu konfigurasi ribet lagi):

$ cassandra -f
$ gremlin.sh


Hanya itu saja, kecuali anda ingin coding, tentu perlu langkah lain.

So, Enjoy big data!

Referensi

[1] http://titan.thinkaurelius.com
[2] http://www.apache.org/licenses/LICENSE-2.0.html
[3] http://s3.thinkaurelius.com/downloads/titan/titan-all-0.3.1.zip
[4] http://cassandra.apache.org
[5] http://hbase.apache.org
[6] http://www.oracle.com/technetwork/database/berkeleydb/overview/index-093405.html
[7] http://wiki.apache.org/cassandra/StorageConfiguration

Juli 15, 2013

Menggunakan Gradle untuk Grizzly

Tulisan sederhana ini akan menjelaskan penggunaan Gradle dalam konteks sebagai build tool, khususnya untuk membangun aplikasi server yang scalable berbasis NIO. NIO atau lebih lengkapnya NIO.2 adalah pustaka untuk I/O di Java yang dispesifikasikan pada JSR 203. Jika dulu pilihan untuk membangun aplikasi server - khususnya server web - terbatas pada penggunaan JSP dan Servlet container seperti Tomcat, Jetty, atau Resin, sekarang pilihan lebih luas lagi karena tersedia berbagai macam framework yang disediakan (dan kebanyakan software bebas!) untuk membangun aplikasi server yang scalable. Beberapa framework yang bisa digunakan antara lain adalah:
  1. Apache MINA [1]
  2. Grizzly [2]
  3. Netty [3]
  4. xSocket [4]
Sekilas Grizzly

Grizzly adalah software bebas untuk membangun aplikasi server yang scalable. Grizzly digunakan juga dalam proyek Glassfish. Grizzly menggunakan Java NIO dan menyediakan berbagai macam pustaka untuk mengembangkan aplikasi server yang menurut saya relatif lengkap:
  1. Aplikasi web dengan HTTP maupun HTTPS
  2. Ajax
  3. Comet (untuk teknologi push)
  4. WebSocket
  5. JAXWS (Web Services)
  6. AJP (Apache JServ Protocol)
  7. SPDY [5], protokol dalam tahap eksperimen dari proyek Chromium untuk mengurangi latensi dari halaman Web.
Artikel ini tidak bermaksud untuk melakukan komparasi antara berbagai framework NIO sehingga saya tidak akan menguraikan perbandingan antar framework tersebut. Pembaca yang berminat bisa melihat pada tulisan yang dibuat oleh Trustin Lee [6]. Meskipun demikian, perlu diingat bahwa perbandingan-perbandingan seperti ini biasanya hanya akan menimbulkan flame wars sehingga saya lebih menyarankan untuk memahami kebutuhan software yang akan dibuat dan kemudian menggunakan tools yang sesuai dengan kebutuhan.

Tentang Gradle

Gradle [5] merupakan software yang menurut pembuatnya (Gradleware) merupakan software bebas yang digunakan sebagai "The Enterprise Automation Tool". Software seperti ini berfungsi untuk peranti otomatisasi dalam berbagai tahap pengembangan software, mulai dari pengelolaan source code di komputer lokal developer, mengelola dependensi pustaka, testing, deployment, dan lain-lain. Software ini menarik bagi saya karena script yang digunakan dalam mendefinisikan berbagai tasks dalam pengembangan software merupakan kode sumber Groovy sehingga jika diperlukan kita bisa menggunakan berbagai fasilitas dari Groovy untuk mengelola proyek kita. Ini berbeda dengan Apache Ant [] + Ivy yang berfungsi sebagai build tools sekaligus mengelola dependensi pustaka serta Apache Maven yang mempunyai fungsi sama dengan Gradle tetapi menggunakan XML untuk mengelola dan mendefinisikan berbagai tasks. 

Meski tersedia untuk berbagai macam IDE besar dalam bentuk plugin (Eclipse, Netbeans, Intellij IDEA), saya merasa lebih nyaman menggunakan perintah di shell karena lebih fleksibel (that's YMMV!). Untuk mengikuti tulisan ini, pastikan anda sudah menginstall Gradle menggunakan langkah-langkah yang telah diuraikan di manual [7]. Untuk memeriksa apakah instalasi anda sudah betul atau belum, ketikkan perintah berikut:

$ gradle --version
------------------------------------------------------------
Gradle 1.6
------------------------------------------------------------
Gradle build time: Tuesday, May 7, 2013 9:12:14 AM UTC
Groovy: 1.8.6
Ant: Apache Ant(TM) version 1.8.4 compiled on May 22 2012
Ivy: 2.2.0
JVM: 1.7.0_25 (Oracle Corporation 23.25-b01)
OS: Linux 3.9.9-1-ARCH i386
$

Tentu bagian-bagian tertentu akan berbeda (misalnnya OS dan/atau versi JVM). Lainnya seharusnya sama. Jika sudah berada pada posisi ini, kita siap menggunakan Gradle. 

Contoh Source Code Aplikasi Grizzly

Untuk keperluan artikel ini, saya akan menggunakan contoh source aplikasi semacam echo server yang bersifat blocking / synchronous. Aplikasi ini terdapat dalam contoh yang terdapat pada distribusi Gradle [8]. Struktur direktori dari aplikasi ini adalah sebagai berikut:


Gradle menggunakan file build.gradle untuk mengelola proyek (kelak jika sudah lebih kompleks, ini bisa dikembangkan menjadi lebih dari satu file konfigurasi). Jika melihat struktur direktori tersebut, kita akan melihat letak dari source code (BlockingHttpHandlerSample.java) di direktori $PROJECT_ROOT_DIR/src/main/name/bpdp/grizzly/. Secara default, source code akan diletakkan pada direktori $PROJECT_ROOT_DIR/src/main/java/. Pada struktur diatas, source code diletakkan pada paket name.bpdp.grizzly sehingga source code BlockingHttpHandlerSample,java perlu diubah sedikit pada bagian package dengan isi berikut: 

package name.bpdp.grizzly;

File build.gradle

File build.grade digunakan untuk mengelola proyek. Proyek pada contoh ini berada pada direktori $HOME/kerjaan/src/java/grizzly/ dan setiap penyebutan $PROJECT_ROOT_DIR akan mengacu ke lokasi tersebut. Isi dari file tersebut adalah sebagai berikut:

apply plugin: 'java'

version = "0.0.1"
group = "name.bpdp.grizzly"
 
dependencies {
  compile group: 'org.glassfish.grizzly', name: 'grizzly-framework', version: '2.3.3'
  compile group: 'org.glassfish.grizzly', name: 'grizzly-http-server', version: '2.3.3'
  testCompile group: 'junit', name: 'junit', version: '4.11'
  testCompile group: 'org.glassfish.grizzly', name: 'grizzly-framework', version: '2.3.3'
  testCompile group: 'org.glassfish.grizzly', name: 'grizzly-http-server', version: '2.3.3'
}
repositories {
  mavenCentral()
}
task(runApp, dependsOn: 'classes', type: JavaExec) {
  main = 'name.bpdp.grizzly.BlockingHttpHandlerSample'
  classpath = sourceSets.main.runtimeClasspath
}
test {
  maxParallelForks = 5
  maxHeapSize = '1024m'
}

Source code Groovy di atas relatif lebih mudah dipahami. Untuk mengelola proyek Java, kita perlu menggunakan plugin java kemudian didefinisikan berbagai dependensi pustaka yang digunakan dalam proyek. Lihat pada bagian dependencies, yang kita tulis disitu mirip dengan definisi XML dari repositori Maven (silahkan lihat di website Grizzly pada bagian download). Kita juga menggunakan repositori Maven untuk mengambil berbagai dependensi pustaka, kemudian membuat task 'runApp' untuk menjalankan aplikasi yang telah kita build. Pada bagian 'runApp' kita definisikan nama kelas main yang akan dijalankan dengan classpath sesuai dengan classpath runtime (lokasi dari berbagai hasil kompilasi).

Membangun (Build) Aplikasi

Untuk membangun aplikasi tersebut, kita hanya perlu menjalankan perintah dari shell: 'gradle build' dan Gradle akan mengambil berbagai pustaka yang kita perlukan dari repositori Maven kemudian mengkompilasi. Jika menjalankan ini untuk pertama kali, mungkin akan sedikit lama apalagi jika pustaka yang akan diambil banyak. Pustaka-pustaka tersebut nantinya akan diletakkan di $HOME/.gradle.

$ gradle build
:compileJava
Download http://repo1.maven.org/maven2/org/glassfish/grizzly/grizzly-framework/2.3.3/grizzly-framework-2.3.3.pom
Download http://repo1.maven.org/maven2/org/glassfish/grizzly/grizzly-project/2.3.3/grizzly-project-2.3.3.pom
Download http://repo1.maven.org/maven2/org/glassfish/grizzly/grizzly-bom/2.3.3/grizzly-bom-2.3.3.pom
Download http://repo1.maven.org/maven2/net/java/jvnet-parent/3/jvnet-parent-3.pom
Download http://repo1.maven.org/maven2/org/glassfish/grizzly/grizzly-http-server/2.3.3/grizzly-http-server-2.3.3.pom
Download http://repo1.maven.org/maven2/org/glassfish/grizzly/grizzly-http/2.3.3/grizzly-http-2.3.3.pom
Download http://repo1.maven.org/maven2/org/glassfish/grizzly/grizzly-rcm/2.3.3/grizzly-rcm-2.3.3.pom
Download http://repo1.maven.org/maven2/org/glassfish/grizzly/grizzly-framework/2.3.3/grizzly-framework-2.3.3.jar
Download http://repo1.maven.org/maven2/org/glassfish/grizzly/grizzly-http-server/2.3.3/grizzly-http-server-2.3.3.jar
Download http://repo1.maven.org/maven2/org/glassfish/grizzly/grizzly-http/2.3.3/grizzly-http-2.3.3.jar
Download http://repo1.maven.org/maven2/org/glassfish/grizzly/grizzly-rcm/2.3.3/grizzly-rcm-2.3.3.jar
:processResources UP-TO-DATE
:classes
:jar
:assemble
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test
Download http://repo1.maven.org/maven2/junit/junit/4.11/junit-4.11.pom
Download http://repo1.maven.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.pom
Download http://repo1.maven.org/maven2/org/hamcrest/hamcrest-parent/1.3/hamcrest-parent-1.3.pom
Download http://repo1.maven.org/maven2/junit/junit/4.11/junit-4.11.jar
Download http://repo1.maven.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar
:check
:build
BlUILD SUCCESSFUL
Total time: 48.44 secs
$

Hasil proses build di atas akan diletakkan pada direktori build sebagai berikut:


Jika sudah mengkompilasi tanpa error, kita bisa menjalankan aplikasi tersebut menggunakan task yang telah kita definisikan (runApp):

$ gradle runApp
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:runApp
Jul 15, 2013 8:39:56 PM org.glassfish.grizzly.http.server.NetworkListener start
INFO: Started listener bound to [0.0.0.0:8080]
Jul 15, 2013 8:39:56 PM org.glassfish.grizzly.http.server.HttpServer start
INFO: [HttpServer] Started.
Client connected!
Writing request:
HttpRequestPacket (
  method=POST
  url=/echo
  query=null
  protocol=HTTP/1.1
  content-length=-1
  headers=[
    Host=localhost:8080]
)
contentA-
contentB-
contentC-
contentD


Echoed POST Data: contentA-contentB-contentC-contentD
Jul 15, 2013 8:39:56 PM org.glassfish.grizzly.http.server.NetworkListener stop
INFO: Stopped listener bound to [0.0.0.0:8080]
BUILD SUCCESSFUL
Total time: 7.916 secs
$

And that's the end of this simple story. Happy hacking!

Referensi

[4] http://xsocket.org - tidak dikembangkan lagi, hanya sebatas bug fixes.
[8] https://maven.java.net/content/repositories/releases/org/glassfish/grizzly/samples/ - atau yang spesifik digunakan pada tulisan ini adalah BlockingHttpHandlerSample.java di file grizzly-http-server-samples-2.3.3-sources.jar.

Juli 14, 2013

Pengantar Teknologi Basis Data Graf

Artikel ini merupakan pengantar ke basis data graf yang sekarang mulai marak dibicarakan dan diimplementasikan. Pengantar ini diperlukan sebelum membahas software basis data graf terdistribusi menggunakan Titan [1]. Jika akan dikategorikan, Titan ini masuk ke dalam kategori basis data NOSQL (Not Only SQL) untuk membedakan dengan basis data relasional (RDBMS) seperti PostgreSQL, MySQL, Oracle Database 10g yang menggunakan SQL sebagai bahasa untuk query (DDL maupun DML). Jika sudah terbiasa dengan "standar" SQL, bersiap-siaplah kaget dengan dunia NOSQL yang sangat bervariasi [2]. Artikel ini akan terdiri atas beberapa seri dan nantinya akan lebih dikonsentrasikan ke penggunaan Titan.

Big Data

Tulisan ini sama sekali tidak untuk menunjukkan bahwa RDBMS adalah teknologi yang sudah usang dan tidak pantas dipakai, tapi saya lebih meyakini bahwa setiap kreasi itu mempunyai kesesuaian dalam menyelesaikan masalah tertentu. Demikian juga dengan NOSQL yang kebanyakan berasal dari kebutuhan dari pengelolaan data yang masif. Pengelolaan data yang masih ini dikenal juga dengan 2 istilah:
  1. "Web scale" untuk menunjukkan kemampuan skalabilitas pada aplikasi yang memerlukan data sangat besar yaitu aplikasi Web. Tentu ini bukan aplikasi Web yang bersifat personal (seperti wiki sederhana, CMS dengan ruang lingkup kecil, dan sejenisnya), tetapi lebih pada aplikasi Web skala besar dengan akses dan keanggotaan sampai ke seluruh dunia (misal: Facebook, Twitter).
  2. "Big data", untuk menunjukkan kebutuhan data yang sangat masif karena seringkali data bersifat realtime dan berjumlah sangat besar sehingga harus dikelola dalam cluster-cluster. Istilah ini mulai populer seiring dengan paper dari Google: MapReduce (framework untuk model pemrograman bagi pemrosesan data yang sangat besar) [3]  dan BigTable [4].

Basis Data Graf

Basis data graf (Graph Database) adalah basis data yang menggunakan graf dalam pemodelan data. Graf merupakan cabang ilmu dari matematika yang dikenal mempunyai keterkaitan aplikasi dengan banyak disiplin ilmu lainnya. Teori graf sudah berumur panjang. Teori graf ini pertama kali dikenal sejak Leonhard Euler menulis paper "Seven Bridges of K√∂nigsberg" pada tahun 1736. Dalam matematika, graf ini merupakan bagian utama dari Matematika Diskrit. Meski banyak buku yang ditulis terkait dengan teori graf, buku dari Frank Harary tentang teori graf pada 1969 membuat banyak peneliti dari berbagai disiplin ilmu menyadari pentingnya teori graf terkait dengan berbagai macam disiplin ilmu. Teori graf ini juga dikembangkan di dunia software untuk pemodelan data, terutama untuk pemodelan dan analisis yang memerlukan keterkaitan dalam bentuk graf. Perkembangan akhir-akhir ini menunjukkan bahwa teori graf ini bisa diterapkan untuk basis data dan membentuk basis data graf. 

Pada basis data graf, data akan dimodelkan dalam bentuk graf (terdiri atas sekumpulan vertex (node) dan dihubungkan dengan dengan edge / arc) yang memungkinkan berbagai macam operasi dilakuan pada struktur data tersebut, misalnya traversal, pattern matching, penemuan "knowledge" baru (reasoning), dan lain-lain. Banyak aspek kehidupan manusia pada dasarnya bisa dimodelkan dengan graf. Contoh paling sederhana, fasilitas rekomendasi teman pada Facebook adalah hasil dari penerapan teori graf: saya mengenal A, A mengenal B, B mengenal C, C mengenal D, dan seterusnya, kemudian dicari pola yang sama antar individu tersebut sehingga bisa dihasilkan rekomendasi bahwa saya mungkin juga mengenal D.

Beberapa basis data yang menggunakan graf untuk pemodelan data antara lain:
  1. OrientDB [5]
  2. Neo4J [6]
  3. AangoDB [7]
  4. HyperGraphDB [8]
  5. InfiniteGraph [9]
  6. Titan
Kebanyakan basis data graf disediakan untuk keperluan Big Data, meski ada juga in-memory graph database yang cocok untuk pemrosesan yang cepat dan tidak untuk keperluan pengelolaan data masif.

Bentuk Spesifik dari Basis Data Graf: TripleStore dan QuadStore

TripleStore merupakan pemodelan data yang berdasarkan pada spesifikasi dari W3C yaitu RDF (Resource Description Framework). Pada pemodelan ini, pemodelan akan didasarkan pada S-P-O (Subyek Predikat Obyek), misalnya "Bambang menulis artikel". QuadStore adalah TripleStore yang menyertakan dukungan Named Graph yang memungkinkan suatu graf diidentifikasikan berdasarkan pada URI. Contoh dari basis data QuadStore ini adalah OpenLink Virtuoso [10]. Beberapa contoh TripleStore:

1. Bigdata [11]
2. AllegroGraph [12]
3. Meronymy - sekarang berganti nama menjadi SparkleDB [13] - sekaligus QuadStore

"Standar" Basis Data Graf: Tinkerpop Stack

Dengan adanya banyak implementasi tersebut, tentu akan mulai banyak kesulitan karena akan muncul berbagai macam implementasi dan pada akhirnya menyebabkan para pengguna dan developer untuk mempelajari basis data tersebut secara spesifik. Saat ini, dikembangkan "standar" untuk pengelolaan basis data graf tersebut. Saya tulis "standar" menggunakan tanda petik karena standar disini tidak diimplementasikan dalam suatu organisasi standar seperti ANSI atau ISO, tetapi lebih ke aarah kesepakatan antara banyak developer yang bekerja dengan basis data graf dan dilakukan oleh komunitas. Standar yang banyak dianut saat ini dikembangkan oleh Tinkerpop [14] dan mempunyai standar paling mendasar yang dikenal dengan sebutan Blueprints [15].

Standar dari Tinkerpop ini terdiri atas berbagai lapisan (sehingga sering disebut sebagai 'stack'). Standar paling mendasar adalah Blueprints. Standar lainnya bisa dilihat di website Tinkerpop. Pada artikel ini saya lebih menekankan pada kedudukan dari berbagai macam standar tersebut. Standar Tinkerpop ini jika diibaratkan dalam dunia pemrograman yang melibatkan SQL di Java, mempunyai kedudukan yang setara dengan JDBC. Dengan demikian, skema dari standar ini adalah sebagai berikut:

Source code <-----> Tinkerpop API <-----> basis data graf

Dengan demikian, source code akan bersifat portable dan tidak terlalu tergantung pada basis data graf tertentu. Vendor basis data graf perlu mengimplementasikan "driver" Tinkerpop supaya bisa diakses menggunakan API Tinkerpop. Pada saat ini, banyak sekali software basis data graf yang mengimplementasikan API tersebut [16].

Bagaimana dengan TripleStore dan QuadStore pada Tinkerpop?

Sebagai bagian dari basis data graf, TripleStore dan QuadStore juga mendapatkan perhatian dari Tinkerpop. Tinkerpop menyediakan Ouplementations [17] yang menggunakan SAIL dari Sesame [18] sehingga RDF ini juga bisa diakses melalui stack Tinkerpop meskipun relatif lebih rumit. 

Referensi

[2] Lihat misalnya di http://www.nosql-databases.org

Juni 18, 2013

Battery Warning Notification for Awesome Window Manager

Just a quick hack for my awesome window manager configuration. There are some widget libraries for awesome that can be used, but this configuration doesn't need them. If you have awesome, then you are set. What I did was reading battery status ("Discharging" or "Charging") and also battery capacity and then put them in awesome timer, call it every 2 minutes. In each call, it will detect the status and capacity. If below 10% and Discharging, then awesome will notify user using Naughty (comes preinstalled in awesome 3.5). Here's the relevant part of the rc.lua:


-- battery warning
-- created by bpdp

local function trim(s)
  return s:find'^%s*$' and '' or s:match'^%s*(.*%S)'
end

local function bat_notification()
  
  local f_capacity = assert(io.open("/sys/class/power_supply/BAT0/capacity", "r"))
  local f_status = assert(io.open("/sys/class/power_supply/BAT0/status", "r"))

  local bat_capacity = tonumber(f_capacity:read("*all"))
  local bat_status = trim(f_status:read("*all"))

  if (bat_capacity <= 10 and bat_status == "Discharging") then
    naughty.notify({ title      = "Battery Warning"
      , text       = "Battery low! " .. bat_capacity .."%" .. " left!"
      , fg="#ff0000"
      , bg="#deb887"
      , timeout    = 15
      , position   = "bottom_left"
    })
  end
end

battimer = timer({timeout = 120})
battimer:connect_signal("timeout", bat_notification)
battimer:start()

-- end here for battery warning


In my laptop, I put rc.lua in $XDG_CONFIG_HOME/.awesome/ (usually it will reside in $HOME/.config/awesome/rc.lua). Just put the script above at the end of rc.lua and you are all set. When awesome detects that battery capacity fall below or the same with 10% and the status is "Discharging" (means the laptop has not been charged), then it will show this notification in the bottom of the monitor, left side:


You may change some properties of naughty.notify if you want.