Living life and Make it Better

life, learn, contribute

Endy Muhardin

Software Developer berdomisili di Jabodetabek, berkutat di lingkungan open source, terutama Java dan Linux.

Project Setup dengan Gradle

Project Setup dengan menggunakan Gradle dan Git

Hal pertama yang kita lakukan sebelum mulai bekerja tentunya adalah menyiapkan meja kerja dan peralatannya. Sama juga dengan mulai membuat aplikasi. Kita harus menyiapkan struktur folder, library dan framework, dan mengatur semuanya agar siap dikerjakan di meja kita, dalam hal ini IDE.

Di ArtiVisi, biasanya ini dikerjakan oleh programmer senior, yaitu Martinus atau saya sendiri. Kegiatan project setup ini tidak terlalu tinggi frekuensinya, karena biasanya coding project yang existing jauh lebih sering daripada memulai project baru.

Yang jarang dikerjakan biasanya cepat dilupakan. Inilah alasan utama saya menulis posting kali ini, sebagai pengingat buat diri sendiri. Selain itu, mudah-mudahan ada manfaatnya juga untuk para pembaca sekalian.

Sebagai gambaran, tipikal aplikasi di ArtiVisi menggunakan stack standar 2011. Jadi, project setup ini akan dibuat mengikuti stack standar tersebut.

Pertama kali, kita buat dulu projectnya. Satu aplikasi biasanya kita pecah menjadi beberapa komponen, yaitu :

  • Domain Model dan Service API : ini kita pisahkan untuk memudahkan distribusi ke aplikasi client. Perhatikan bahwa yang saya maksud client di sini bukanlah customer pembeli aplikasi, melainkan aplikasi di sisi hilir misalnya user interface yang dibuat dengan Swing. Di sisi client, tidak perlu ada detail implementasi. Cukup class-class domain seperti Produk, Kategori, dsb. Juga kita sediakan service interface, yaitu method yang bisa digunakan untuk menjalankan proses bisnis.

  • Implementasi Service : ini adalah implementasi dari service interface di atas. Implementasi biasanya hanya ada di sisi server. Jadi, jar yang dihasilkan project ini tidak kita distribusikan ke client

  • Konfigurasi : file konfigurasi seperti jdbc.properties, logback-test.xml, smtp.properties, dan setting-setting lain kita juga pisahkan ke project sendiri. Ini tujuannya untuk memudahkan deployment. Seperti kita tahu, biasanya ada beberapa environment seperti development di laptop programmer, testing server, dan production server. Dengan memisahkan konfigurasi, kita bisa menghindari mendeploy konfigurasi development ke server production. Yang perlu diperhatikan di sini, hibernate.cfg.xml dan applicationContext.xml bukanlah file konfigurasi. Itu adalah file aplikasi, walaupun bentuknya xml dan tidak perlu dikompilasi.

  • User Interface : kalau aplikasi desktop, ini hanya satu project saja. Atau mungkin dua dengan konfigurasinya. Tapi untuk web, biasanya kita pecah dua juga. Yang satu berisi source code java, satu lagi berisi aplikasi web. Dengan demikian, bila ada perubahan di controller, kita cukup deploy 1 jar, tidak perlu upload 1 war.

Sebagai ketentuan lain, biasanya nama package selalu kita awali dengan com.artivisi, dan struktur folder mengikuti standar Maven.

Mari kita mulai, berikut rangkaian perintah di linux untuk membuat struktur awal project.

mkdir -p project-contoh/com.artivisi.contoh.{config,domain,service.impl,ui.springmvc,ui.web}/src/{main,test}/{java,resources}
mkdir -p project-contoh/com.artivisi.contoh.ui.web/src/main/webapp/WEB-INF

Outputnya bisa kita lihat sebagai berikut

find . 
.
./com.artivisi.contoh.service.impl
./com.artivisi.contoh.service.impl/src
./com.artivisi.contoh.service.impl/src/test
./com.artivisi.contoh.service.impl/src/test/java
./com.artivisi.contoh.service.impl/src/test/resources
./com.artivisi.contoh.service.impl/src/main
./com.artivisi.contoh.service.impl/src/main/java
./com.artivisi.contoh.service.impl/src/main/resources
./com.artivisi.contoh.domain
./com.artivisi.contoh.domain/src
./com.artivisi.contoh.domain/src/test
./com.artivisi.contoh.domain/src/test/java
./com.artivisi.contoh.domain/src/test/resources
./com.artivisi.contoh.domain/src/main
./com.artivisi.contoh.domain/src/main/java
./com.artivisi.contoh.domain/src/main/resources
./com.artivisi.contoh.ui.springmvc
./com.artivisi.contoh.ui.springmvc/src
./com.artivisi.contoh.ui.springmvc/src/test
./com.artivisi.contoh.ui.springmvc/src/test/java
./com.artivisi.contoh.ui.springmvc/src/test/resources
./com.artivisi.contoh.ui.springmvc/src/main
./com.artivisi.contoh.ui.springmvc/src/main/java
./com.artivisi.contoh.ui.springmvc/src/main/resources
./com.artivisi.contoh.config
./com.artivisi.contoh.config/src
./com.artivisi.contoh.config/src/test
./com.artivisi.contoh.config/src/test/java
./com.artivisi.contoh.config/src/test/resources
./com.artivisi.contoh.config/src/main
./com.artivisi.contoh.config/src/main/java
./com.artivisi.contoh.config/src/main/resources
./com.artivisi.contoh.ui.web
./com.artivisi.contoh.ui.web/src
./com.artivisi.contoh.ui.web/src/test
./com.artivisi.contoh.ui.web/src/test/java
./com.artivisi.contoh.ui.web/src/test/resources
./com.artivisi.contoh.ui.web/src/main
./com.artivisi.contoh.ui.web/src/main/java
./com.artivisi.contoh.ui.web/src/main/webapp/WEB-INF
./com.artivisi.contoh.ui.web/src/main/resources

Berikutnya, kita lengkapi dengan dependensi jar. Di ArtiVisi, kita menggunakan Gradle. Gradle meminta kita untuk mendaftarkan project yang terlibat dalam settings.gradle

include "com.artivisi.contoh.config"
include "com.artivisi.contoh.domain"
include "com.artivisi.contoh.service.impl"
include "com.artivisi.contoh.ui.springmvc"
include "com.artivisi.contoh.ui.web"

Dan ini build file Gradle.


springVersion = "3.0.5.RELEASE"
springSecurityVersion = "3.0.5.RELEASE"
slf4jVersion = "1.6.1"
logbackVersion = "0.9.27"
jodaTimeVersion = "1.6.2"
sourceCompatibility = 1.6
 
subprojects {
    apply plugin: 'java'
    apply plugin: 'eclipse'
 
    configurations {
        all*.exclude group: "commons-logging", module: "commons-logging"
    }
 
    repositories {
        mavenCentral()
    }
 
    dependencies {
        compile "org.slf4j:jcl-over-slf4j:$slf4jVersion",
                "org.slf4j:jul-to-slf4j:$slf4jVersion"
                
        runtime "joda-time:joda-time:$jodaTimeVersion"        
                
        runtime "ch.qos.logback:logback-classic:$logbackVersion"
  
        testCompile 'junit:junit:4.7'
    }
 
    group = 'com.artivisi.contoh'
    version = '1.0-SNAPSHOT'
    sourceCompatibility = 1.6
    
    task wrapper(type: Wrapper) {
        gradleVersion = '0.9.1'
        jarFile = 'wrapper/wrapper.jar'
    }
}

project('com.artivisi.contoh.domain') {
    dependencies { 
        compile "org.hibernate:hibernate-entitymanager:3.4.0.GA"
     
        compile "org.springframework:spring-tx:$springVersion",
                "org.springframework:spring-orm:$springVersion",
                "org.springframework:spring-jdbc:$springVersion"
                
     
    }
}

project('com.artivisi.contoh.service.impl') {
    dependencies { 
        compile project(':com.artivisi.contoh.domain')
        compile "org.hibernate:hibernate-entitymanager:3.4.0.GA"
     
        compile "org.springframework:spring-tx:$springVersion",
                "org.springframework:spring-orm:$springVersion",
                "org.springframework:spring-jdbc:$springVersion"
                
     
    }
}

project('com.artivisi.contoh.ui.springmvc') {
    dependencies {
        compile project(':com.artivisi.contoh.service.impl')
     
        compile "org.springframework:spring-webmvc:$springVersion",
                "org.springframework:spring-aop:$springVersion"
     
        compile "org.springframework.security:spring-security-web:$springSecurityVersion",
                "org.springframework.security:spring-security-config:$springSecurityVersion"
     
        compile "javax.validation:validation-api:1.0.0.GA",
                "org.hibernate:hibernate-validator:4.0.2.GA"
     
    }
}

project('com.artivisi.contoh.ui.web') {
    apply plugin: 'war'
    apply plugin: 'jetty'
     
    dependencies {
        compile project(':com.artivisi.contoh.ui.springmvc')
        runtime project(':com.artivisi.contoh.config')
      
        runtime "javax.servlet:jstl:1.1.2",
                "taglibs:standard:1.1.2",
                "opensymphony:sitemesh:2.4.2"
     
        providedCompile "javax.servlet:servlet-api:2.5"
    }
}

Build file ini sudah mendeskripsikan semua sub-projectnya. Sebetulnya kita bisa membuat buildfile di masing-masing project, tapi saya lebih suka terpusat seperti ini supaya terlihat keterkaitan antar project.

Karena saya menggunakan Eclipse, saya menambahkan metadata supaya projectnya bisa dibuka di Eclipse. Ini bisa kita lakukan dengan cara menjalankan perintah

gradle eclipse

dalam masing-masing folder project. Tapi karena terlalu malas, saya gunakan satu baris perintah ini.

for d in */; do cd "$d"; gradle eclipse; cd ..; done

Untung saja pakai linux, jadi bisa coding di command prompt :D

Selanjutnya, kita bisa test dengan melakukan build di project paling hilir, yaitu ui.web

cd com.artivisi.contoh.ui.web
gradle war

Hasilnya ada di folder build/libs Kita cek apakah semua dependensi sudah terpenuhi dengan perintah berikut.

jar tvf build/libs/com.artivisi.contoh.ui.web-1.0-SNAPSHOT.war

Ini juga bisa langsung dijalankan dengan plugin Jetty yang ada dalam Gradle.

cd com.artivisi.contoh.ui.web
gradle jetty

Outputnya bisa kita lihat di browser, dengan port 8080.

Di situ ada link menuju aplikasi kita. Silahkan diklik.

Folder WEB-INF masih terlihat, karena kita belum membuat web.xml. Berikut isi web.xml, masukkan dalam folder com.artivisi.contoh.ui.web/src/main/webapp/WEB-INF


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

	<!-- Reads request input using UTF-8 encoding -->
	<filter>
		<filter-name>characterEncodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>

	<filter-mapping>
		<filter-name>characterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	
	<!-- Handles all requests into the application -->
	<servlet>
		<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>
				/WEB-INF/springmvc-context.xml
			</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

</web-app>

Sekalian saja kita konfigurasi Spring MVC. Pasang file springmvc-context.xml ini di sebelahnya web.xml


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

	<!-- Scans the classpath of this application for @Components to deploy as beans -->
	<context:component-scan base-package="com.artivisi.contoh.ui.web" />

	<!-- Configures the @Controller programming model -->
	<mvc:annotation-driven />
	
	<!-- mengganti default servletnya Tomcat dan Jetty -->
	<!-- ini diperlukan kalau kita mapping DispatcherServlet ke / -->
	<!-- sehingga tetap bisa mengakses folder selain WEB-INF, misalnya img, css, js -->
	<mvc:default-servlet-handler/>

	<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources/ directory -->
	<mvc:resources mapping="/resources/**" location="/resources/" />

	<!-- Application Message Bundle -->
	<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
		<property name="basename" value="/WEB-INF/messages/messages" />
		<property name="cacheSeconds" value="0" />
	</bean>

	<!-- Resolves view names to protected .jsp resources within the /WEB-INF/views directory -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/templates/jsp/"/>
		<property name="suffix" value=".jsp"/>
	</bean>
	
	<!-- Forwards requests to the "/" resource to the "hello" view -->
	<mvc:view-controller path="/" view-name="hello"/>

</beans>

Kita cek juga apakah projectnya sudah bisa dibuka di Eclipse. Mari kita import.

Pertama, arahkan workspace ke folder project-contoh.

Setelah Eclipse terbuka, kita pilih menu Import Project, untuk membuka 4 project yang tadi sudah kita buat.

Pilih folder induknya.

Selesai, semua project kita bisa dibuka. Bahkan kita bisa menjalankan project ui.web dengan cara klik kanan Run in Server. Ini bisa dilihat dari icon project tersebut yang berbentuk bola dunia.

Selesai sudah, mari kita share dengan rekan yang lain.


Konsep Clustering

Di milis JUG, lagi-lagi ada yang tanya tentang load balancing, failover, dan clustering. Jawabannya masih sama sejak 10 tahun saya berkecimpung di urusan coding-mengcoding. Jadi, baiklah saya tulis di blog saja, supaya next time bisa jadi referensi.

Ini sebetulnya dua hal yang berbeda. Load balancing ya membagi beban. Failover ya mencegah single point of failure.

Load Balancing

Load balancer terdiri dari satu balancer dan banyak worker. Bebannya dibagi2 ke semua worker dengan algoritma yang biasanya bisa dipilih. Bisa merata (round robin) bisa juga dengan bobot (weighted), misalnya worker X mendapat 2 kali worker Y karena dia specnya lebih tinggi. Atau bisa juga dynamic, artinya si LB akan mengetes kondisi semua worker, mana yang kira2 sedang idle itu yang dikasi. Mana yang sedang idle ini nanti ada lagi settingnya, apakah melihat CPU usage pakai SNMP, melihat ping response time, whatever.

Failover minimal harus ada 2 titik. Kalo kita implement LB aja, point of failure (POF) nya adalah si LB. Begitu LB nya mati, ya udah semua worker gak bisa diakses. Untuk mencegah ini, LB nya harus ada 2, satu aktif satu standby (pasif).

Contoh aplikasi load balancer :

  • HAProxy
  • ldirectord (Ultra Monkey)
  • Pound

Contoh aplikasi lain yang bisa jadi load balancer :

  • Apache (mod_proxy_balancer)
  • Nginx
  • lighttpd
  • bind (DNS Server)

Failover

Contoh aplikasi failover :

Failover artinya mengatasi kalau ada service yang mati. Ada dua jenis aplikasi untuk menangani failover :

  • Network Oriented : keepalived, ucarp
  • Cluster Oriented : corosync, heartbeat

Penjelasan lengkapnya bisa dibaca di sini. Namun ringkasnya seperti ini:

Network oriented failover memastikan minimal satu service aktif, dan tidak apa-apa bila ada lebih dari satu service yang aktif. Ini cocok untuk dipasang di load balancer, karena load balancer tidak menyimpan state. Tidak masalah kalau user melihat ada dua LB, kadang diarahkan ke LB-1 dan kadang ke LB-2.

Cluster oriented failover memastikan hanya satu service yang aktif, dan tidak apa-apa bila tidak ada service yang aktif. Ini cocok untuk dipasang di database server, karena kita tidak mau database utama dan cadangan dua-duanya aktif. Bisa-bisa datanya tidak tersimpan dengan benar (split brain). Untuk lebih jelas tentang cara kerja cluster-oriented failover, bisa dibaca di sini.

Nah, mudah2an sampe di sini jelas bahwa load balancing dan failover itu dua hal yang tidak saling terkait (orthogonal) dan biasanya dikombinasikan untuk mendapatkan konfigurasi yang robust dan performant.

Setahu saya konsep2x Clustering diatas berlaku pada saat hit pertama. Pertanyaan saya.. Bagaimana jika request sudah terlayani tetapi ditengah-tengah proses server tiba2x down.. Apakah proses tersebut langsung di alihkan ke server yang lagi up? Jika iya apakah proses akan di restart dari awal atau server yang sedang up bisa melanjutkan sisa dari proses yang belum dikerjakan di server yang telah down?

Sticky Session

Tidak selalu, tergantung konfigurasinya. Ada konfigurasi sticky session. Artinya, pada hit pertama, si user akan diberikan penanda, biasanya berbentuk cookie. Pada hit berikutnya, LB akan melihat cookienya, dan mengarahkan ke server yang sebelumnya sudah mengurus si user ini.

Ada juga konfigurasi non-sticky. Artinya tiap hit dianggap hit baru, dan didistribusikan ke semua server sesuai algoritma yang dipilih, round robin, weighted, atau dynamic, sesuai penjelasan di atas.

Mau pilih yang mana? Ya tergantung kemampuan LB nya. Ada yang bisa 2-2 nya sehingga bisa pilih, dan ada juga yang rada stupid sehingga terpaksa pakai non-sticky. Istilahnya, LBnya layer berapa? Kalo layer 7 biasanya bisa sticky, kalo layer 4 ya gak bisa. Lebih jauh tentang urusan layer-layeran ini bisa dibaca di sini dan di sini

Nah, apa impact sticky vs non-sticky? Ini pengaruhnya ke session data. Session data adalah data sementara masing-masing user. Karena sifatnya sementara, maka biasanya tidak disimpan secara persistent di tabel database. Contoh paling klasik adalah isi shopping cart. Itu barang belum diorder, tapi sudah dipilih, sehingga biasanya belum disimpan di database.

Kalo pake non-sticky, si user pertama milih barang di server X. Pada saat dia pilih barang kedua, dilayani server Y. Karena pilihan pertama ada di server X, ya pas dia pilih barang kedua, cuma tercatat 1 barang padahal harusnya 2.

Ini tidak terjadi kalo kita pakai sticky balancer. Request kedua dan seterusnya akan diarahkan ke server X lagi.

Jadi, sticky atau non-sticky itu impactnya ke temporary data user, sering disebut dengan istilah session data atau user state.

Nah, setelah jelas apa dampaknya sticky vs non-sticky, mari kita lanjut ke pertanyaan selanjutnya.

Kalau untuk Java EE Application Server apakah untuk pertanyaan saya di atas sudah ada featurenya atau perlu ada tambahan produk lagi untuk bisa sharing informasi terhadap state suatu proses yang dijalankan di satu server sehingga jika server tersebut down proses bisa dilanjutkan di server yang lain tanpa merestart proses?

Session Replication

Mengenai urusan session/state management, ini sangat tergantung merek application server yang digunakan. Secara umum, settingan standar appserver biasanya simpan data session di memori. Kalau kita enable cluster, misalnya terdiri dari 4 worker, maka data session ini biasanya akan direplikasi ke satu worker lain. Pada saat worker utama mati, request berikutnya akan diarahkan ke worker cadangannya, sehingga user gak kehilangan data belanjaan. Biasanya, satu state itu disimpan ke 2 worker saja, bukan direplikasi ke semua untuk alasan efisiensi bandwidth.

Pada penjelasan di atas banyak sekali saya gunakan kata ‘biasanya’. Ini karena kapabilitas dan konfigurasi masing-masing merek appserver sangat berbeda sehingga sulit untuk menggeneralisir kondisinya.

Lalu bagaimana? Saya biasanya mengambil pendekatan yang universal, yang jalan di semua appserver, sehingga tidak perlu pusing menghafal appserver apa bisa apa settingnya gimana. Teknik universalnya sederhana: aplikasi webnya dibuat stateless. Jangan ada simpan data di memori. Simpan semua di database, atau di distributed cache (misalnya memcached).

Di Java, data yang ada di memori antara lain : session variable, static variable, context variable. Di PHP, CMIIW cuma session dan global variable aja.

Karena selama ini saya menggunakan teknik ini, jadi saya kurang up to date terhadap appserver apa bisa apa settingnya gimana. Demikian juga tentang load balancer apa support sticky atau tidak, saya tidak pernah memikirkannya. Pokoknya simpan state di distributed cache atau database, setelah itu mau pakai appserver Tomcat, Jetty, Glassfish, Weblogic, terserah. Mau pakai load balancer Apache HTTPD, Nginx, lighty, HAProxy, Pound, Ultramonkey, juga terserah.

Demikian sekilas sharing mengenai load balancing dan clustering. Semoga menjadi cerah.


Development Stack 2011

Posting ini adalah update dari posting tiga tahun yang lalu. Tidak banyak yang berubah dalam stack ini, yang bisa berarti dua hal: pilihan tiga tahun yang lalu sudah tepat atau malas belajar selama 3 tahun ini. Mudah-mudahan alasannya yang pertama :D

Update : Gradle tidak jadi dipakai, karena kita tidak mau maintain 2 skillset. Maven 2 ternyata stabil dan bekerja sesuai harapan. Hudson terlibat kerusuhan dengan Oracle, akhirnya fork jadi Jenkins.

Presentation Layer

  • Spring MVC

  • SiteMesh

  • Dojo Toolkit

  • ExtJS

  • Spring Security

  • Jasper Report

  • Jackson

Business Layer

  • Spring Framework

  • Hibernate

Library lain yang sering digunakan

  • Logback

  • Joda Time

  • Velocity

  • JPos

Infrastruktur

  • Version Control : Git + Gitosis

  • Testing Tools : JUnit, DBUnit, JMeter, Sonar

  • Issue Tracker : Redmine

  • Build Tools : Gradle, Maven

  • Continuous Integration : Hudson Jenkins

  • OS Programmer : Ubuntu Desktop

  • OS Server : Ubuntu Server, Debian

Deployment Target

  • Database Server : MySQL, Oracle

  • Application Server : Tomcat, Glassfish

Praktis perubahan yang terjadi hanyalah dari Subversion ganti menjadi Git. Nah, bagaimana menurut Anda? Pilihan tepat atau malas belajar?


Sharing Repository Git

Skenario : selama ini kita coding di laptop sendiri saja. Kemudian ada kebutuhan untuk kolaborasi dengan orang lain melalui Git. Bagaimana caranya? Baiklah mari kita bahas di artikel ini.

Inisialisasi Repository Git

Pertama, kita inisialisasi dulu repository Git. Masuk ke dalam folder project dan ketikkan

git init

Git akan membuat repository kosong di dalam folder project, ditandai dengan adanya folder baru bernama .git

Selanjutnya, kita akan memasukkan semua file dan folder project kita ke dalam repository. Yang harus dimasukkan adalah file source code, baik itu Java, HTML, XML, dan sebagainya. Yang tidak perlu dimasukkan adalah file hasil kompilasi atau hasil generate. Kita perlu mendaftarkan file yang tidak ingin disimpan dalam file konfigurasi yang bernama .gitignore

File ini harus kita buat sendiri menggunakan text editor. Berikut contoh isi filenya, bila kita coding menggunakan Eclipse atau Netbeans

[gist id=773975]

Setelah kita setting ignore file, berikutnya kita masukkan semua file dan folder ke dalam antrian.

git add . 

Kemudian, simpan ke repository

git commit -m "commit pertama project XXX"

Project sudah tersimpan di repository Git di komputer lokal kita. Mari kita upload ke server, atau dikenal dengan istilah push.

Share Repository

Kita memerlukan server di mana kita memiliki ijin akses untuk melakukan push. Cara memperoleh ijin akses tidak dibahas pada artikel ini. Silahkan buat account di Github atau Gitorious. Bila ingin push ke repository perusahaan, minta informasinya pada admin Anda.

Setelah kita mendapatkan URL server yang bisa kita gunakan, daftarkan sebagai remote. Berikut perintahnya.

git remote add <namaremote> <URL>

Contohnya seperti ini

git remote add github git@github.com:endymuhardin/project-terbaru-saya.git

Pastikan remotenya sudah terdaftar dengan perintah berikut

git remote -v

Terakhir, mari kita push dengan perintah berikut

git push <namaremote> <namabranch>

Contohnya

git push github master

Hore, project kita sudah naik ke server. Kita tinggal share URL tersebut ke rekan kerja kita.


Menggunakan Gist

Gist adalah fitur yang disediakan oleh Github. Fungsi dasarnya mirip dengan pastebin, yaitu kita bisa paste text di sana, dan disharing dengan orang lain. Keunggulan Gist adalah dia sudah memiliki kemampuan version control dengan Git. Sehingga kita bisa fork, clone, modifikasi, dan push lagi ke repo utama dengan seluruh history tersimpan di sana.

Untuk bisa menggunakan Gist, kita harus memiliki account Github dulu. Setelah itu, kita bisa buat gist di sini.

Cara membuatnya tidak sulit. Cukup entri nama file, keterangan, dan isi text yang mau dishare.

Setelah itu, tekan Create Public Gist. Gist kita akan siap digunakan.

Gist yang sudah dibuat bisa dipasang di blog. Caranya, klik tombol embed.

Nanti akan muncul textfield berisi tag HTML untuk dipasang di blog, kira-kira seperti ini tagnya:

<script src="https://gist.github.com/770832.js?file=HelloWorld.java"></script>

Tag ini bisa langsung dipasang di blog kita. Hasilnya seperti di bawah ini.

Kelemahan cara ini adalah dia membutuhkan javascript, dan isi filenya tidak terindeks oleh spider. Untuk mengatasinya, kita gunakan plugin wordpress ini.

Setelah digunakan, kita cukup memasang tag khusus seperti dijelaskan di websitenya. Ini contoh hasilnya

[gist id=770832]

Sekilas tidak terlihat bedanya antara pakai plugin dan tidak. Tapi coba lihat source halaman ini, klik kanan kemudian View Source. Yang menggunakan plugin, source codenya benar-benar ada tulisannya. Sedangkan yang pakai tag script tidak ada source code hello worldnya.

Nah, kalau sudah pakai ini, tidak perlu bingung lagi mewarnai source code di blog. Kalau mau revisi, tinggal edit aja di Github, dan otomatis di blog langsung terupdate.