The Joel Test : 12 Langkah Untuk Membuat Kode Yang Baik

The Joel Test, sambil me-ngeryitkan dahi saya baca ulang-ulang dengan hati-hati artikel lama ini. Hehe, dulu sempat bikin rame team developer kami tahun 2007, waktu itu para senior sedang heboh berdiskusi,  “Sebaiknya programming yang baik, untuk menghasilkan code yang baik  itu seperti apa?”.

Entahlah sepertinya artikel ini, menurut saya masih sangat relevan untuk tahun 2017 ini, meski artikel tersebut dibuat tahun 2000.

Mr. Joel intinya memberi 12 pertanyaan, yang jawabannya adalah “Yes” atau “No”. Score yang harus anda dapatkan adalah 12, jika 11 saja anda jawab “Ya”, berarti team software development anda masih ditolelir. Namun jika anda menjawab “Ya” minimal 10 soal atau dibawahnya, berarti anda punya masalah di organisasi software development anda.

12 Pertanyaan dari Mr. Joel adalah sebagai berikut :

  1. Do you use source control?
  2. Can you make a build in one step?
  3. Do you make daily builds?
  4. Do you have a bug database?
  5. Do you fix bugs before writing new code?
  6. Do you have an up-to-date schedule?
  7. Do you have a spec?
  8. Do programmers have quiet working conditions?
  9. Do you use the best tools money can buy?
  10. Do you have testers?
  11. Do new candidates write code during their interview?
  12. Do you do hallway usability testing?

 

Membuat perubahan memang sangat sulit, tetapi jika tidak mau berubah, ya tenggelam saja.

Saatnya #Berubah :)

Replace All URL Link WordPress Setelah Migrasi

Beberapa hari kemarin bantu-bantu beberapa project migrasi yang menggunakan wordpress. Export & Import saja tidak cukup apalagi export dari localhost, hum dijamin banyak url yang nyangkut. hehe

Berikut ini salah satu solusi yang saya gunakan untuk mereplace all link ke domain baru.

UPDATE wp_posts SET post_content = REPLACE(post_content,'www.domain.com/wp-content/uploads','www.domain.com/images');

Example Ant Builder J2EE Enterprise Application Archive

Hmm sudah lumayan lama tidak bermain dengan ANT, karena terlalu dimanja dengan Maven. hehe.

Beberapa saat lalu kami memutuskan untuk menggunakan EJB3, JAX-RS dan JAX-WS yang merupakan technology murni bawaan dari J2EE, untuk membuat backend, membuat project kami tidak memerlukan library tambahan yang banyak. Dan sepertinya penggunaan Maven tidak terlalu efektif karena kami hanya menambahkan 5 external library.

Ceritanya 1 hari ini saya agak frustasi, ketika di eclipse untuk build EAR hanya cukup export, ketika saya coba terjemahakan  menggunakan Maven malah  ruwet,  entahlah sepertinya level saya untuk build project EE menggunakan Maven masih perlu belajar lagi, huehue.  Akhirnya saya kangen-kangen sama ANT Builder yang dulu waktu java 1.4, saya sangat berusaha untuk pengen menguasainya. :D Continue reading

Membungkus ulang String HTML ke Element + angular $scope

Menemukan hal baru dan menarik dari angular, dan ingin sekali menulis karena takut lupa, hehe.

Problemnya adalah ada requitement Form yang lumayan komplek, karena form input berkembang yang mengharuskan untuk mengenerate dan menyisipkan html baru (raw DOM element).  Dan bagaimana string html baru itu bisa mengenali function-function atau variable-variable dalam $scope.

Solusi yaitu dengan menggunakan fuction default dari angular yaitu “$compile”, dengan menggunakan “$compile” kita bisa mendaftarkan apapun yang ada dalam $scope kedalam html baru, agar dikenali. :) (*Nice

Syntax
$compile(content)($scope);
Contoh Penerapan
......
var content = '<button ng-click="inputQuotation(value)">Input Quotation</button>';
var cell = document.getElementById('cell_info_' + dus.id);
angular.element(cell).html( $compile(content)($scope) );
.....

AngularJS vs SEO

Sudah lama sebenarnya menyelesaikan masalah  ini baru sempat untuk menulis hari ini. Intinya adalah ketika robot index berkunjung ke website kita,  nginx meredirect ke server Panthomjs. Panthomjs akan me-render secara sempurna html dan memberikan ke robot index.

Configuration di nginx  nginx.conf:

location / {
  try_files $uri @prerender;
}

location @prerender {
 set $prerender 0;
 if ($http_user_agent ~* "baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator") {
  set $prerender 1;
 }
 if ($args ~ "_escaped_fragment_") {
  set $prerender 1;
 }
 if ($http_user_agent ~ "Prerender") {
  set $prerender 0;
 }
 if ($uri ~ "\.(js|css|xml|less|png|jpg|jpeg|gif|pdf|doc|txt|ico|rss|zip|mp3|rar|exe|wmv|doc|avi|ppt|mpg|mpeg|tif|wav|mov|psd|ai|xls|mp4|m4a|swf|dat|dmg|iso|flv|m4v|torrent|ttf|woff)") {
  set $prerender 0;
 }
 if ($prerender = 1) {
  set $prerender "127.0.0.1:8888";
  proxy_pass http://$prerender$request_uri;
 }
 if ($prerender = 0) {
  rewrite .* /index.html break;
 }
}

 

Script phantomjs render.js :

var system = require('system');

if (system.args.length < 3) {
    console.log("Missing arguments.");
    phantom.exit();
}

var server = require('webserver').create();
var port = parseInt(system.args[1]);
var urlPrefix = system.args[2];

var parse_qs = function(s) {
    var queryString = {};
    var a = document.createElement("a");
    a.href = s;
    a.search.replace(
        new RegExp("([^?=&]+)(=([^&]*))?", "g"),
        function($0, $1, $2, $3) { queryString[$1] = $3; }
    );
    return queryString;
};

var renderHtml = function(url, cb) {
    var page = require('webpage').create();
    page.settings.loadImages = false;
    page.settings.localToRemoteUrlAccessEnabled = true;
    page.onCallback = function() {
        cb(page.content);
        page.close();
    };
//    page.onConsoleMessage = function(msg, lineNum, sourceId) {
//        console.log('CONSOLE: ' + msg + ' (from line #' + lineNum + ' in "' + sourceId + '")');
//    };
    page.onInitialized = function() {
       page.evaluate(function() {
            setTimeout(function() {
                window.callPhantom();
            }, 10000);
        });
    };
    page.open(url);
};

server.listen(port, function (request, response) {
    var route = parse_qs(request.url)._escaped_fragment_;
    var url = urlPrefix
      + request.url.slice(1, request.url.indexOf('?'))
      + '#!' + decodeURIComponent(route);
    renderHtml(url, function(html) {
        response.statusCode = 200;
        response.write(html);
        response.close();
    });
});

console.log('Listening on ' + port + '...');
console.log('Press Ctrl+C to stop.');


Error JBOSS Timeout after 300 And Operation roll back

Error diatas terjadi jika proses deployment atau  application run di JBoss terlalu lama dan melebihi batas waktu default dari jboss yaitu 300 detik.

Problem saya diatas terjadi ketika mau menjalankan aplikasi backend, karena memang cukup banyak sql command yang harus dijalankan untuk mengisi master data. :P

Berikut ini adalah tambahan configurasi yang saya lakukan agar error di atas tidak muncul lagi.

Program Argument

-mp "D:/Source/jboss-eap-6.4/modules" -jaxpmodule javax.xml.jaxp-provider org.jboss.as.standalone 
-b localhost --server-config=standalone.xml -Djboss.server.base.dir=D:\Source\jboss-eap-6.4\standalone 
-Djboss.as.management.blocking.timeout=1200 

VM Argument

"-Dprogram.name=JBossTools: JBoss Enterprise Application Platform 6.1+" -server -Xms1024m -Xmx1024m 
-XX:MaxPermSize=256m -Dorg.jboss.resolver.warning=true -Djava.net.preferIPv4Stack=true 
-Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 
-Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true "
-Dorg.jboss.boot.log.file=D:/Source/jboss-eap-6.4/standalone/log/boot.log" 
"-Dlogging.configuration=file:/D:/Source/jboss-eap-6.4/standalone/configuration/logging.properties" 
"-Djboss.home.dir=D:/Source/jboss-eap-6.4" -Dorg.jboss.logmanager.nocolor=true 
-Djboss.bind.address.management=localhost 

Good Luck :)

How to avoid a MySQL deadlock

Sudah banyak teori yang menjelaskan mengenai Deadlock di Database, hampir semua DBMS menerapkannya. Deadlock sangat penting bagi DBMS untuk menjaga konsistensi data. Tetapi jika sering mengalami deadlock tidak nyaman juga, karena applikasi anda akan muncul pensan error.

Menurut DZone.com dalam artikel How to Deal With MySQL Deadlocks berikut ini adalah cara menguranginya : Continue reading

JPA 2.0 SELECT IN, How to used?

Cara menggunakan JPA SELECT IN adalah sebagai berikut :

String qlString = "select foo from Foo foo where foo.name IN :names"; 
Query q = em.createQuery(qlString, Item.class);

List<String> names = Arrays.asList("ba", "bi", "bu", "be", "bo");

q.setParameter("names", names);
List<Foo> actual = q.getResultList();