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.

0 comments:

Poskan Komentar