Maret 30, 2016

Arch Linux, Mplayer, and Chromium Sound Problem

This post is just a reminder whenever one day I get the same problem: no sound in browser (in this case: Chromium) while the sound is normal using mplayer (or any other command line player). Some configurations:

$HOME/.asoundrc
# Use PulseAudio by default
pcm.!default {
  type pulse
  fallback "sysdefault"
  hint {
    show on
    description "Default ALSA Output (currently PulseAudio Sound Server)"
  }
}
ctl.!default {
  type pulse
  fallback "sysdefault"
}
/etc/mplayer/mplayer.conf
ao=pulse
/etc/pulse/default.pa
.ifexists module-udev-detect.so
load-module module-udev-detect tsched=0
.else
load-module module-detect
.endif
Restart pulseaudio:
pulseaudio -k
pulseaudio --start
Restart browser. There you go. Enjoy the sound!

Februari 20, 2016

Multiple Go versions in Linux

Currently, there are trends on software development that tend to release their SDK on regular basis. Rust for example, also Go with 6 month release cycle. This predictable release is good and I personally like it since I can predict on features availability and use them for my software development project. The downside of this approach is there are many versions availablle that install them using OS package manager is proved to be pain in the ass.

Some of developers then create tools to manage multiple versions of the SDK, see GVM (Go Version Manager) and multirust (for Rust) for example. They are good of course but I probably choose not to use them since probably someday they won't be developed (see the latest commit if you want). My approach is simpler but only for Linux with Bash. If you use Windows, you may adopt my approach using SET to setup env variables and put them in batch file (.BAT). Explanation follows.

Directory Setup

I put all of my Go related software inside /opt/software/go-dev-tools. Here's the structure:


Directory Contents

I put Go SDK inside go, all Go related tools inside go-tools, liteide for LiteIDE, and tmp for temporary pkg dir whenever I want to compile and put Go tools inside go-tools.

Inside go-version (go1.2.2, go1.3.3, etc), I extract all of downloaded SDK from Go download page.

Environment Variables

In my $HOME/env dir, I created go directory to manage environment variables for my Go version. They usually have the same env variables, except for version pre 1.5, 1.5 (for vendor experimentation) and  1.6.

Pre 1.5 and > 1.6

$ cat ~/env/go/go1.2.2
GODEVTOOLS_HOME=/opt/software/go-dev-tools

GO_HOME=$GODEVTOOLS_HOME/go/go1.2.2
LITEIDE_HOME=$GODEVTOOLS_HOME/liteide
GOTOOLS=$GODEVTOOLS_HOME/go-tools

export GOROOT=$GO_HOME
export GOOS=linux
export GOARCH=amd64
export GOHOSTOS=linux
export GOHOSTARCH=amd64
export GOBIN=$GOROOT/bin

export PATH=$PATH:$GO_HOME/bin:$LITEIDE_HOME/bin:$GOTOOLS

alias go=colorgo$

1.5

$ cat ~/env/go/go1.5.3
GODEVTOOLS_HOME=/opt/software/go-dev-tools

GO_HOME=$GODEVTOOLS_HOME/go/go1.5.3
LITEIDE_HOME=$GODEVTOOLS_HOME/liteide
GOTOOLS=$GODEVTOOLS_HOME/go-tools

export GOROOT=$GO_HOME
export GOOS=linux
export GOARCH=amd64
export GOHOSTOS=linux
export GOHOSTARCH=amd64
export GOBIN=$GOROOT/bin

export PATH=$PATH:$GO_HOME/bin:$LITEIDE_HOME/bin:$GOTOOLS

alias go=colorgo

export GO15VENDOREXPERIMENT=1
$

Usage 
Open new shell - terminal, and source environment variables:

$ source env/go/go1.2.2
11:25:22-bpdp@archer:~$ go version
go version go1.2.2 linux/amd64
11:25:25-bpdp@archer:~$

Open another new shell - terminal, and source env vars:

$ source env/go/go1.6.0
11:25:59-bpdp@archer:~$ go version
go version go1.6 linux/amd64
11:26:01-bpdp@archer:~$

and so on.

Go Tools

When you see something interesting for your Go project, just go to /opt/software/go-dev-tools/tmp and the Go get them and copy the files inside /opt/software/go-dev-tools/go-tools:

$ cd /opt/software/go-dev-tools/tmp/
$ export GOPATH=`pwd`
$ go get github.com/smartystreets/goconvey
$ mv ../go/go1.6/bin/goconvey ../go-tools/
$ which goconvey
/opt/software/go-dev-tools/go-tools/goconvey
$

I don't know whether my approach is the best, but it proves to be comfortable for me. As always, YMMV. Happy hacking!












Februari 08, 2016

Supervisor Dengan Multiple Workers pada Elixir

Beberapa hari ini saya mencoba otak atik Elixir setelah sekian lama mengamati. Untuk yang sudah terbiasa dengan Erlang, barangkali menyesuaikan diri tidak akan terlalu sulit, sementara bagi yang belum pernah mengenal Erlang, konsep let it crash dari Erlang untuk fault tolerant systems perlu proses pembelajaran yang lumayan.

Konsep supervisor tree untuk proses di Elixir tidak ada hubungannya dengan proses di sistem operasi. Persamaannya hanya pada struktur tree. Pada proses di sistem operasi, tidak ada mekanisme untuk mengelola proses-proses tersebut, sedangkan pada Elixir, proses-proses tersebut dikelola menggunakan proses supervisi: ada proses untuk me-restart secara otomatis proses anak yang mati. Bagian ini mempunyai banyak pilihan, tetapi di tulisan ini saya hanya akan menampilkan mekanisme untuk membuat software menggunakan Elixir dengan banyak proses anak (sering disebut child process, sering juga disebut worker). Saya menulis ini karena tidak ada penjelasan yang jelas untuk materi ini. Pemula biasanya akan merasa kebingungan.

Program yang akan dibuat ini sebenarnya sederhana saja: membuat 3 worker process yang akan melakukan proses penambahan, pembagian, dan perkalian. Kode sumber bisa diperoleh di https://github.com/bpdp/elixir-playground. Pada dasarnya, hal-hal yang perlu diperhatikan pada repo tersebut adalah:
  1. Repo workers saya buat menggunakan mix new workers --sup karena sejak awal dimaksudkan untuk membangun aplikasi menggunakan beberapa worker dengan supervisi.
  2. Tidak ada perubahan pada hasil mix new di atas kecuali pada file-file berikut ini:
    • lib/workers.ex => saya ubah hanya berisi satu callback function (start, sudah ketentuan dari Elixir bahwa callback function bernama start dengan 2 argumen). Di callback function ini saya definisikan beberapa worker yang saya letakkan di file lib/workers/worker1.ex - sampai worker3.ex. Sesuai ketentuan dari Elixir, penamaan file dan nama module harus sesuai: workers/worker1.ex => Workers.Worker1
    • Worker process saya letakkan pada workers/worker1.ex - worker3.ex. Setiap worker menggunakan GenServer yang mengharuskan adanya function start_link dan init.
Untuk menjalankan:

$ mix run
Elixir.Workers.Worker1 started
7
Elixir.Workers.Worker2 started
3.0
Elixir.Workers.Worker3 started
60
Silahkan melihat halaman-halaman manual untuk penjelasan lebih lanjut.




Desember 04, 2015

Swift in Arch Linux

Following its open source release, Swift can be downloaded at http://www.swift.org. I am lucky enough to see that there is Linux version available for download. The binary version was developed in Ubuntu, so I tried to grab the binary release and then have them installed to no luck. It was some problems with some libraries: libpanel (from ncurses5), libedit.so.2 and libicuuc. Being a bleeding edge distro does mean that I may not be able to run binary files from older libs in my Arch box. That was the case with Swift, it was compiled under Ubuntuwith older libs.

Here's what I did to make Swift able to run without recompiling in Arch Linux:
  1. Whenever Swift complain about no libs available, go to rpmfind.net and then find one. Here's an example: http://www.rpmfind.net/linux/RPM/mageia/cauldron/x86_64/media/core/release/lib64ncurses5-5.9-24.mga6.x86_64.html. Get the rpm, rpmextract.sh rpmfile, the put all of the files inside, let's say $HOME/lib/swift
  2. Exception for libedit, just make a symlink from /usr/lib/libedit.so to libedit.so.2 (this should be done inside $HOME/lib/swift.
  3. Create a file, mine is $HOME/env/swift:
export PATH=$PATH:/opt/software/swift/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/lib/swift
 That's all. Now, just "source ~/env/swift" to use Swift.




Mei 03, 2015

ArangoDB for Arch Linux - Binary Version Without Manual Compilation (AUR)

I was once the maintainer of ArangoDB package in AUR. While the package was fine (I think), I am quite tired of having it compiled myself. It's just I am getting older, I guess. Then I prefer binary version after leaving maintainer role. Now I can use it using RPM file of OpenSuSE Factory version - available from ArangoDB download page. Some tweaks are needed anyway. I will give you some tweaks that I successfully use to make it works. In this post, I put all of installation files under /home/bpdp/software/arangodb (a.k.a $ARANGO_HOME).

  • cd $ARANGO_HOME
  • Install rpmextract package: # pacman -S rpmextract
  • Extract RPM file: $ rmpextract.sh path/to/arangodb-2.5.3-12.1.i586.rpm
  • Move conf files into etc: $ mv etc/arangodb/*.conf etc/
  • Delete init.d dir (we don't need that): $ rm -rf etc/int.d
  • All database will reside in db, so: $ mkdir db
  • Here's the dir structure:

$ ls
total 48
drwxr-xr-x  9 bpdp bpdp  4096 May  4 10:31 .
drwxr-xr-x 91 bpdp bpdp  4096 May  4 10:16 ..
drwxr-xr-x  2 bpdp bpdp  4096 May  4 10:12 bin
drwxr-xr-x  2 bpdp bpdp  4096 May  4 10:19 db
drwxr-xr-x  2 bpdp bpdp  4096 May  4 10:30 etc
drwxr-xr-x  4 bpdp bpdp  4096 May  4 10:12 lib
drwxr-xr-x  2 bpdp bpdp  4096 May  4 10:12 sbin
drwxr-xr-x  5 bpdp bpdp  4096 May  4 10:12 share
drwxr-xr-x  4 bpdp bpdp  4096 May  4 10:12 var
$

  • Create all needed dirs: cluster and mri (ruby): $ mkdir -p share/arangodb/mr/client/modules; mkdir -p shar/arangodb/mr/common/modules.
  • $ mkdir -p var/log/arangodb/cluster; mkdir -p lib/arangodb/cluster
  • Edit etc/*.conf to reflect all of those dir location.
  • Delete unneeded dirs/files: $ rm -rf lib/systemd/; rm -rf etc/init.d/; rm -rf sbin/rcarango.
  • Set PATH and MANPATH. You may put this inside $HOME/.bashrc:

export ARANGO_HOME=$HOME/software/arangodb
export PATH=$PATH:$ARANGO_HOME/bin:$ARANGO_HOME/sbin
export MANPATH=$MANPATH:$ARANGO_HOME/share/man
Installation finish. You should source .bashrc or open another terminal and then you may active the server daemon and / or arango shell:

  • Activate arango daemon: $ arangod -c ~/software/arangodb/etc/arangod.conf
  • Enter arango shell: $ arangosh -c ~/software/arangodb/etc/arangosh.conf
That's all I guess, you may now use ArangoDB. 


Uf wiederluege! Na shledanou! Auf Wiedersehen! Bye Bye! Adiau! ¡Hasta luego! Au revoir!
Arrivederci! להתראות! Tot ziens! Adjö! Εις το επανιδείν! さようなら До свидания!

April 26, 2015

Atom for 32bit Arch Linux (or other Linux 32bit distros)

Actually, there's a package in AUR (https://aur.archlinux.org/packages/atom-editor/) but I am too lazy to compile it myself, so here it goes.

Atom is available in binary releases for 64bit only for Linux. Luckily, WebUpd8 team provides binary packages for 64bit and 32bit Ubuntu. Get the package here: https://launchpad.net/~webupd8team/+archive/ubuntu/atom/+packages. For this article, I downloaded 32bit binary for Vivid. We will convert this file using deb2targz utility. You should get it first. If you are in Arch Linux, get from AUR (yaourt -S deb2targz), if you are not from Arch fame (:p) get it here: http://www.miketaylor.org.uk/tech/deb/deb2targz. The .deb file that was just downloaded:

-rw-r-----   1 bpdp bpdp 49547144 Apr 26 17:16 atom_0.194.0-1-webupd8-1_i386.deb

Put it somewhere wherever you like. Once you get deb2targz working, follow these steps:
  1. Convert .deb to tar.xz: $ deb2targz atom_0.194.0-1-webupd8-1_i386.deb
  2. Extract .xz file: $ tar -zvf atom_0.194.0-1-webupd8-1_i386.tar.xz. You will have two dirs: usr and opt. In opt dir, extract file atom/atom-linux32.tar.xz: $  tar -xvf atom-linux32.tar.xz.
  3. Put those two dirs inside whatever dir you like, mine is /home/bpdp/software/atom. We call this $ATOM_DIR (not necessarily exist, just for this article only).
  4. This .deb package search atom binary at /tmp/atom-build/atom, which is surely doesn't exist. To make it works, we should edit usr/bin/atom file. Find the line which says [ -x "$ATOM_PATH" ] || ATOM_PATH="/tmp/atom-build/atom" and change it to [ -x "$ATOM_PATH" ] || ATOM_PATH="/home/bpdp/software/atom/opt/atom/atom" (well of course you should put your own location of atom binary (mine is /home/bpdp/software/atom/opt/atom/atom).
  5. Now you should be able to run atom from $ATOM_DIR/usr/bin: $ ./atom. If you want, you may also put that dir in your PATH env variable: export PATH=$PATH:/home/bpdp/software/atom/usr/bin inside $HOME/.bashrc.

Setting Printer Network HP LaserJet P2035n di Arch Linux

Install paket: hplip dan cups

Aktifkan CUPS dengan menjalankan daemon:

# cupsd

Install driver HP. Siapkan file ppd (hp-laserjet_p2035n-hpijs-pcl3.ppd), diperoleh di /usr/share/ppd/HP/hp-laserjet_p2035n-hpijs-pcl3.ppd.gz. Ekstrak file tersebut di suatu lokasi, setting permission access ke user. Untuk kasus ini, saya meletakkan file tersebut di /home/bpdp/ppd/hp-laserjet_p2035n-hpijs-pcl3.ppd. Ikuti langkah2 berikut:

[root@bpdp-arch ~]# hp-setup -i
HP Linux Imaging and Printing System (ver. 3.15.2)
Printer/Fax Setup Utility ver. 9.0
Copyright (c) 2001-15 Hewlett-Packard Development Company, LP
This software comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to distribute it
under certain conditions. See COPYING file for more details.
(Note: Defaults for each question are maked with a '*'. Press to accept the default.)
--------------------------------
| SELECT CONNECTION (I/O) TYPE |
--------------------------------
  Num       Connection  Description                                              
            Type                                                                
  --------  ----------  ----------------------------------------------------------
  0*        usb         Universal Serial Bus (USB)                              
  1         net         Network/Ethernet/Wireless (direct connection or JetDirect)
  2         par         Parallel Port (LPT:)                                    
Enter number 0...2 for connection type (q=quit, enter=usb*) ? 1
Using connection type: net
Using device: hp:/net/HP_LaserJet_P2035n?ip=172.17.51.109
Setting up device: hp:/net/HP_LaserJet_P2035n?ip=172.17.51.109

---------------------
| PRINT QUEUE SETUP |
---------------------
Please enter a name for this print queue (m=use model name:'HP_LaserJet_P2035n'*, q=quit) ?
Using queue name: HP_LaserJet_P2035n
Locating PPD file... Please wait.
error: No PPD found for model laserjet_p2035n using old algorithm.
error: Unable to find an appropriate PPD file.
Would you like to specify the path to the correct PPD file to use (y=yes, n=no*, q=quit) ? /home/bpdp/ppd/hp-laserjet_p2035n-hpijs-pcl3.ppd
error: Please press or enter 'y', 'n', or 'q'.
Would you like to specify the path to the correct PPD file to use (y=yes, n=no*, q=quit) ? y
Please enter the full filesystem path to the PPD file to use (q=quit) :/home/bpdp/ppd/hp-laserjet_p2035n-hpijs-pcl3.ppd
Description for the file: HP LaserJet p2035n hpijs pcl3, 3.15.2, requires proprietary plugin
Use this file (y=yes*, n=no, q=quit) ? y
Enter a location description for this printer (q=quit) ?Ruang SI Jaringan
Enter additonal information or notes for this printer (q=quit) ?
Adding print queue to CUPS:
Device URI: hp:/net/HP_LaserJet_P2035n?ip=172.17.51.109
Queue name: HP_LaserJet_P2035n
PPD file: /home/bpdp/ppd/hp-laserjet_p2035n-hpijs-pcl3.ppd
Location: Ruang SI Jaringan
Information:

---------------------
| PRINTER TEST PAGE |
---------------------
Would you like to print a test page (y=yes*, n=no, q=quit) ? n
Done.
[root@bpdp-arch ~]#

Setelah itu, setiap kali print, akan muncul printer tersebut. Enjoy!

November 15, 2014

Mengakses Engine Prolog (tuProlog) dari Scala

Prolog merupakan bahasa pemrograman komputer generasi awal, dibuat oleh Alain Colmerauer pada sekitar awal tahun 1970-an dan dikembangkan oleh Alain bersama dengan Phillipe Roussel pada tahun 1972. Prolog pada awalnya memang dikembangkan untuk aplikasi AI (Artificial Intelligence) dengan kekhususan pada formalisme linguistik. Prolog banyak digunakan pada berbagai universitas dan pendidikan tinggi dan seakan-akan jauh dari industri meskipun banyak cerita kesuksesan dari Prolog (misalnya penggunaan Sicstus Prolog atau SWI Prolog). Di Indonesia, bisa dibilang Prolog memang murni masih berada di "dunia imajinasi" karena hanya digunakan pada banyak mata kuliah di berbagai perguruan tinggi tetapi jauh dari dunia industri (as always, CMIIW).

Saat ini Prolog mulai banyak dikembangkan untuk aplikasi tingkat lanjut karena kemampuan internal dari bahasa pemrograman tersebut yang sesuai untuk pemecahan masalah kompleks yang melibatkan reasoning serta berbagai fasilitas lainnya yang sesuai untuk keperluan aplikasi terdistribusi di Intenet (DCG untuk parsing dan menghasilkan list, pemrosesan data, declarative programming untuk komunikasi dan interaksi agent, dan lain-lain). Interpreter dan compiler Prolog juga banyak dikembangkan dan tersedia untuk berbagai platform. Untuk tulisan ini kita akan menggunakan tuProlog. tuProlog merupakan sistem Prolog yang dikembangkan untuk Java (dan .NET). Hal yang menarik dari tuProlog, sistem ini menyediakan sistem Prolog yang ringan dan hanya mengkonsentrasikan diri pada fitur standar (ISO Prolog) sedangkan bagian lainnya bisa menggunakan Java. Untuk artikel ini kita akan menggunakan Scala yang merupakan bahasa obyek-fungsional untuk aplikasi yang dijalankan di atas JVM.

Untuk mengikuti artike ini, ada beberapa yang harus dipersiapkan:

  1. Install JDK (saya menggunakan versi 1.8.0_25)
  2. Install Scala (saya menggunakan versi 2.11.4)
  3. Download tuProlog (saya menggunakan versi 2..9.1)
  4. Hmm ... saya menggunakan Linux - bash, jika anda menggunakan tools selain itu silahkan buat penyesuaian sendiri.


Artikel ini hanya menjelaskan cara mengakses Prolog engine melalui Scala. Setelah memahami artikel ini, anda bisa menggunakan fitur dari sistem tuProlog, menuliskan kode Prolog yang dijalankan melalui tuProlog dan kemudian menjalankan engine Prolog melalui Scala sekaligus mengambil hasil dari hasil eksekusinya. Untuk artikel ini, kita belum menggunakan sbt sehingga setting CLASSPATH harus dilakukan secara manual. Artikel menggunakan sbt semoga bisa segera menyusul.

Copy file 2p.jar dan tuprolog.jar

$ ls
total 744
drwxr-xr-x  2 bpdp bpdp   4096 Nov 16 08:04 .
drwxr-xr-x 19 bpdp bpdp   4096 Nov 16 07:58 ..
-rw-r--r--  1 bpdp bpdp 547424 Nov 16 08:00 2p.jar
-rw-r--r--  1 bpdp bpdp    392 Nov 16 08:04 HelloProlog.scala
-rw-r--r--  1 bpdp bpdp 198340 Nov 16 08:00 tuprolog.jar
$


Setting CLASSPATH

$ export CLASSPATH=$CLASSPATH:.:2p.jar:tuprolog.jar
$


Kode Sumber

File Scala berikut ini (HelloProlog.scala) saya terjemahkan dari manual untuk kode sumber Java hal 166. Interoperabilitas Scala dan Java sangat bagus sehingga penggunaan tuProlog engine berjalan dengan baik dan kode sumber Scala relatif lebih mudah dipahami.


import alice.tuprolog._
import scala.util.control._

object HelloProlog {

  def main(args: Array[String]) {

    val pEngine = new Prolog
    var info = pEngine.solve("append(X,Y,[1,2]).")
    val loop = new Breaks

    loop.breakable {
      
      while (info.isSuccess()) {

        println("solution: " + info.getSolution() + 
          " - bindings: " + info)
        if (pEngine.hasOpenAlternatives()) {
          info = pEngine.solveNext()
        } else {
          loop.break
        }

      }

    }

  }

}


Penggunaan tuProlog engine sesederhana mendefinisikan engine Prolog (new Prolog) dan kemudian menggunakan method solve untuk mengeksekusi kode sumber Prolog.

Kompilasi

$ scalac HelloProlog.scala
$ ls -la
total 756
drwxr-xr-x  2 bpdp bpdp   4096 Nov 16 08:43 .
drwxr-xr-x 19 bpdp bpdp   4096 Nov 16 07:58 ..
-rw-r--r--  1 bpdp bpdp 547424 Nov 16 08:00 2p.jar
-rw-r--r--  1 bpdp bpdp   1930 Nov 16 08:16 HelloProlog$$anonfun$main$1.class
-rw-r--r--  1 bpdp bpdp    657 Nov 16 08:16 HelloProlog.class
-rw-r--r--  1 bpdp bpdp   1140 Nov 16 08:16 HelloProlog$.class
-rw-r--r--  1 bpdp bpdp    520 Nov 16 08:16 HelloProlog.scala
-rw-r--r--  1 bpdp bpdp 198340 Nov 16 08:00 tuprolog.jar
$


Running

$ scala HelloProlog
solution: append([],[1,2],[1,2]) - bindings: yes.
X / []  Y / [1,2]
solution: append([1],[2],[1,2]) - bindings: yes.
X / [1]  Y / [2]
solution: append([1,2],[],[1,2]) - bindings: yes.
X / [1,2]  Y / []


Menggunakan tuProlog akan memungkinkan aplikasi kita menggunakan berbagai fitur AI yang bermanfaat untuk memperbaiki kinerja software yang kita aplikasikan. Happy hacking!

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. :)