Tuan Anh Tran I make computers and phones do things

Some useful use cases for Java Reflection

While most will recommend you not to use Reflection because:

  • Lose ability to refactoring because you hard-code the name of class/method as String.

  • Lower runtime performance,

  • No compile time safety check.

However, there’re many cases Reflection can become very useful that it pros might outweight its cons. Or it’s just cool to show colleagues some new cool tips.

Easier to implement toString() method for debugging

You can use Reflection to loop through an Object’s attribute and print it out instead of using StringBuilder to append it yourself. This feature is available in Apache Common Lang. Or you can write it yourself if all you need is this method.

public String toString() {
  return ReflectionToStringBuilder.toString(this);
}

Note: This is actually not used often because modern IDE(IntelliJ, Eclipse, NetBean, …) already has ‘generator’ for this kind of thing.

Create object/call method using name

This is one of the reasons why Reflection exists in the first place. It’s useful in case like you have some configuration stored in database and you want to create object using class name (e.g.: like building cache using class name and table name on startup).

Or another case would be like: You get tired of calling .add for BigDecimal so you write a function to sum it up, taking an ArrayList of BigDecimal as parameter. But it’s not convenient because in reality, you have object of other data type and you will have to create the ArrayList of BigDecimal by looping through the collection. This is when Reflection comes in handy. You can use Reflection to create a function, passing a collection of anything and a method name to get the BigDeicmal value out.

@SuppressWarnings({ "rawtypes", "unchecked" })
  public static <T> BigDecimal getSumBigDecimal(ArrayList<T> bcArr, String methodName) {
    BigDecimal sum = BigDecimal.ZERO;
    if (null != bcArr && bcArr.size() != 0 && !StringUtil.isEmpty(methodName)) {
      try {
        T firstItem = bcArr.get(0);
        Class klass = firstItem.getClass();
        Method method = klass.getMethod(methodName);

        for (T each : bcArr) {
          BigDecimal bc = (BigDecimal) method.invoke(each);
          sum = sum.add(bc == null ? BigDecimal.ZERO : bc);
        }
      }
      catch (NoSuchMethodException | SecurityException | IllegalAccessException
          | IllegalArgumentException | InvocationTargetException e) {
        // do what you must here, I'm catching because it's an example
        e.printStackTrace();
      }
    }
    return sum;
  }
}

Reflection is cool and all but please use it with care. Make sure the pros outweight the cons. Know what you’re doing.

Poker 2 keyboard with Granite and Dolch keycaps

I’m thinking of getting a Poker 2 keyboard and a Granite keycap set just for the sake of looking at “her”. She’s so beautiful, it hurts.

Poker 2 keyboard with Granite and Dolch keycaps
1 - Poker 2 keyboard with Granite and Dolch keycaps - credit of SpaceCadet2000

My current favorite keyboard is the Laptop Pro with the Matias Silent Switch. It’s so fun to type on though I prefer the shape of the HHKB Pro 2. The downside of HHKB Pro 2 is the lack of supply for novelty keycaps. Poker 2 is the closest thing to HHKB’s form factor at the moment I believe. Plus, there are plenty of novelty keycaps made for MX Cherry including the beautiful, gorgeous Granite keyset above.

Poker 2 is currently available for around $110 on mechanicalkeyboards.com. Used one goes for around $60. Granite keyset will cost another $120-$130, makes it a total of $240 for a new one and $190 for a used one. For reference, it costs 1 HHKB Pro 21

Totally worth it for such beauty IMO.

  1. I got mine through a Japanese proxy call WhiteRabbitExpress. They quoted me $220 for the keyboard (shipping included) and $20 for their proxy service, which is very reasonable I believe.

Force Safari to refresh website's favicon

Force Safari to remove its website’s favicon database by issuing this command in Terminal.

rm ~/Library/Safari/WebpageIcons.db

How to setup your VPS as a seedbox in under 15 mins

Zero (well, almost) Linux knowledge required!!!

This script is not mine. I just stumbled upon it and found it rather useful. If you are afraid about malicious script, you should download and verify it yourself.

This script will setup basically everything you need for a seedbox from thin client, web ui as well as FTP.

All you need to do is logging in and copy, paste these commands below, answer a few questions, then wait.

wget https://raw.githubusercontent.com/SeedboxCreator/SeedboxCreationScript/master/seedbox-setup
chmod +x seedbox-setup
./seedbox-setup

Read and follow the instruction. The installation instruction is very straight forward and easy to understand. Upon finish, the setup script will also print out the information about web url, FTP address, etc… Note it down somewhere if you’re not sure.

I’ve tested this with Ubuntu 14.04 x64 on DigitalOcean and it works flawlessly. It should work on any other VPS as well.

Looking for a VPS provider? Check Hetzner or OVH out. RamNode is also good if you’re looking for a low cost VPS provider. For $15 a year, you can setup yourself a rather decent seedbox.

rutorrent
Fig.1 - ruTorrent web ui upon finished

LaunchRocket

A Mac PreferencePane for managing services with launchd/launchctl. LaunchRocket was primarily created for managing various services installed by Homebrew, though it should work with most launchd-compatible plists.

A poor man's seedbox for $15 a year

Seedbox is basically just a server with torrent client installed. A seedbox usually goes for $15 a month for a decent one and $7 a month for a cheap one. It’s rather easy to setup a VPS as a seedbox and save yourself some money.

I have a pretty good experience with RamNode. In fact, I’m running my website on one of their VPS right now. Though it’s cheap but it’s actually more than what I need for my static website.

For $15 a year, you will get 80GB of space/500GB bandwidth monthly, 128MB RAM and 100Mbps ethernet, which is ok if you’re just a casual torrent downloader like me. If you’re looking for more, I suggest you take a look at Hetzner or OVH.

Get a VPS at RamNode

Sign up for the massive plan (cheapest one) for $15 a year and select the geolocation closeast to your location. There are 4 datacenters that you can select from which are NYC, ATL, SEA and NL. Also, select Ubuntu 14.04 64bit as OS for the sake of this tutorial. Enter your domain if you have one. If not, you’re going to access to your seedbox by IP address.

I got myself one at Atlanta and the speed is very decent from Thailand.

download speed from seedbox

RamNode will send you an email with the VPS’s login information few minutes after signing up.

Connecting to your VPS

If you’re on Linux or Mac, ssh is pre-installed and ready to use. To connect on Mac/Linux, use the command below. Enter password when asked.

ssh username@ip-address

If you’re using Windows, you need to download a SSH client to connect to your VPS and set it up. PuTTY is a decent one.

Open PuTTY, enter IP address you get from the email and click open. Enter username and password you get from the email.

PuTTY

Now if you’re panic about server’s security, you can go ahead and follow this tutorial to add a few extra layers. As for me, I usually just installed fail2ban, disable login by password, and using public key authentication only.

Installing deluge and deluge-web

I’m going to ignore all the security practices so that this tutorial can be as simple as possible. I’m assuming you’re still using root account for now.

Copy and paste the commands below, press Y when asked. These commands will update/upgrade to lateast package and then install deluge, deluge-weband nginx. Append sudo if needed.

apt-get update
apt-get upgrade
apt-get install deluged
apt-get install deluge-web 
apt-get install nginx

deluge is a torrent client, deluge-web is deluge’s web interface for easy management and nginx allows you to download files to your computer.

rtorrent is another decent torrent client (better web ui, lower memory footprint) but requiring a bit more work to setup it up and running. Also, you can setup FTP and download your files using FTP instead of direct HTTP. I choose direct HTTP simply because I have nginx server already installed so less work for me. You can also secure your public folder in nginx by following this tutorial.

Once finished, start deluged and deluge-web.

service nginx start
deluged
deluge-web --fork

You can access your deluge-web at your seedbox’s IP address, default port 8112 with default password deluge.

Now, in order to download your files from seedbox, you will move the download folder of deluge into nginx www folder. For example: downloads folder (/usr/share/nginx/www/downloads). Your files will be accessible at http://ip-address/downloads.

If you hit any problem, feel free to drop me an email or tweet me at @tuananh_org. I’ll be happy to help.

Update: I added a blog post for those who doesn’t want to tinker much with command line.

Download accelerators, managers for Mac

Maxel - $7.99

This is my favorite download accelerator by far. I usually do a lot of torrenting on my VPS and download them later via direct HTTP. I just need some basic features of a download accelerator. Heck, axel was working well enough for me, except the part that I have to manually parse the link1 to it.

Maxel offers Safari/Chrome extension (Firefox is currently in beta-testing phase) and they are quite good. You can select some text on the website and right click -> Download selected links with Maxel. Maxel will identify the selected text and filter out the links for you. This is what make Maxel a little better than Fat Pipe below.

Maxel doesn’t offer speed control but it’s on checklist of the developer.

Fat Pipe Downloader - Free

Another decent download accelerator, Fat Pipe is very similar to Maxel above in term of features. I find it a bit unstable and the browser extension is less convenient than Maxel.

Fat Pipe is currently (as of this post) free on Mac App Store.

Folx - $19.99

Some notable features:

  • Tagging system
  • iTunes integration
  • Scheduling
  • Speed control

Offers more features than most. More expensive than most ($19.99). The app can download torrent files as well as creating it. Though, if you’re using a private tracker, there’s a fat chance that the app is not white-listed. None of the private trackers that I use (WhatCD, BTN, PTP, etc..) whitelist Folx.

SpeedTao - Free (beta)

SpeedTao is currently in beta (for quite awhile now). SpeedTao also support torrent download but struggles with the same problem of private trackers as Folx.

SpeedTao has an unique feature: remote download, which allows you to add transfer to a remote machine via iCloud or Dropbox.

Personally, I don’t really like SpeedTao because the app seems like an abandonware already.

iGetter - $25

iGetter is feature-rich, works fairly well except the interface looks like it was made in the 90s. Between iGetter and Folx, I’d say go with Folx. Call me cheap but I don’t want to pay $25 for a software that was last updated over a year ago.

Conclusion

I pick Maxel simply because I don’t need more features than that. Your mileage may vary. Maxel does one thing and does it very well for me.

  1. I wrote a small bash script to parse a file contains a list of links, new line seperated to axel and let it download one by one.

How to lazy-load CSS with JavaScript

Prioritize above the fold content and defer loading CSS can significantly improve your site’s rendering speed (impression, at the very least) and PageSpeed score. Basically, you will inline those CSS rules so that content above the fold (content visible without scrolling down) can be render right away (instead of getting blocked while waiting for the whole CSS file being downloaded), making visitors feel that the site is responsive.

You can use this bookmarklet to identify the critical CSS rules. Note that this will not pickup the @media query. That, you will have to do by yourself for now.

Once you’ve finished identifying those above-the-fold CSS rules and inline them, you will have to lazy-load the rest of the CSS with JavaScript.

If you’re using jQuery, put this in your ready block. Otherwise, write your own version of ready and put it there

This is an example of ready in pure JavaScript. I don’t need jQuery anywhere else on my site so including jQuery is too much overhead for this purpose.

(function(funcName, baseObj) {
  funcName = funcName || "isReady";
  baseObj = baseObj || window;
  var readyList = [];
  var readyFired = false;
  var readyEventHandlersInstalled = false;
  function ready() {
    if (!readyFired) {
      readyFired = true;
      for (var i = 0; i < readyList.length; i++) {
        readyList[i].fn.call(window, readyList[i].ctx);
      }
      readyList = [];
    }
  }

  function readyStateChange() {
    if ( document.readyState === "complete" ) {
      ready();
    }
  }

  baseObj[funcName] = function(callback, context) {
    if (readyFired) {
      setTimeout(function() {callback(context);}, 1);
      return;
    } else {
      readyList.push({fn: callback, ctx: context});
    }
    if (document.readyState === "complete") {
      setTimeout(ready, 1);
    } else if (!readyEventHandlersInstalled) {
      if (document.addEventListener) {
        document.addEventListener("DOMContentLoaded", ready, false);
        window.addEventListener("load", ready, false);
      } else {
        document.attachEvent("onreadystatechange", readyStateChange);
        window.attachEvent("onload", ready);
      }
      readyEventHandlersInstalled = true;
    }
  }
})("isReady", window);

Function to lazy-load CSS

function loadCSS(href){
  var ss = window.document.createElement('link'),
      head = window.document.getElementsByTagName('head')[0];

  ss.rel = 'stylesheet';
  ss.href = href;

  // temporarily, set media to something non-matching to ensure it'll
  // fetch without blocking render
  ss.media = 'only x';

  head.appendChild(ss);

  setTimeout( function(){
    // set media back to `all` so that the stylesheet applies once it loads
    ss.media = 'all';
  },0);
}

Once ready, load the rest of the CSS

isReady(function() {
  loadCSS('/assets/css/main.css');
});

Java 9 is coming with money API

Java provides you two exchange providers which are ECB (European Central Bank) and IMF (International Monetary Fund). You also can write our own class implementing ExchangeRateProvider interface. The biggest problem here is the data though, not the implementation . If you work for a bank, problem is solved.

ExchangeRateProvider imfRateProvider = MonetaryConversions
                          .getExchangeRateProvider("IMF"); 
ExchangeRateProvider ecbRateProvider = MonetaryConversions 
                          .getExchangeRateProvider("ECB"); 

SafariTabSwitching

Safari Tab Switching is a Safari SIMBL plugin which allow switching between tabs using Cmd+1-9.

The most annoying thing (aside the web inspector) when I switch back to Safari due to a power consumption issue with Chrome.