Saturday, August 4, 2018

Stack Trace got eaten up in the log

During the production troubleshooting today, we found out in the log that NPE was logged occasionally, but without detailed stack trace. We've made sure that we always log the stack trace in our code. So, what was going on?

After searching back in our log history (we have a log aggregation service that keeps log history), we found there were NPEs with the full stack trace, then after some time, the stack trace was gone.

In this end, this turns out to be caused by a Hotspot JIT compiler optimization, when a particular exception keeps being thrown up to a threshold, the same exception stack trace will not be filled anymore due to performance impact of throwing exceptions.

The solution is to turn off this optimization by providing this JVM option:

 -XX:-OmitStackTraceInFastThrow

References:

1. Stackoverflow post on "NullPointerException in Java with no StackTrace"
2. A more detailed analysis with a demo app




Friday, August 3, 2018

scheduled task silently died with ScheduledThreadPoolExecutor

We had a very annoying bug lately where a scheduled job silently stopped executing without our knowledge. After debugging and carefully reading Javadoc again, it turns out that the task throws an Exception thus suppressing the subsequent executions of the task.

Javadoc for ScheduledExecutorService.scheduleWithFixedDelay (scheduleAtFixedRate has the same issue):

ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
                                          long initialDelay,
                                          long delay,
                                          TimeUnit unit)
Creates and executes a periodic action that becomes enabled first after the given initial delay, and subsequently with the given delay between the termination of one execution and the commencement of the next. If any execution of the task encounters an exception, subsequent executions are suppressed. Otherwise, the task will only terminate via cancellation or termination of the executor.

So, the quick fix is to add a try-catch block around the task execution logic to catch Exception. I have created a simple demo app to show this issue and how the fix works with some analysis why it happens:

https://github.com/guozheng/scheduledjob

The lesson learned is that we need to read doc more carefully and read source code to understand the library behavior closely.

Saturday, February 3, 2018

Interview Preparation for Tech Companies

For a candidate, to find a job in tech industry is not easy. From the hiring company's point of view, it is even more challenging to find qualifying candidates. In a very short process of phone interview and onsite interviews, it is very difficult to properly judge a candidate. Companies today mostly rely on short algorithmic or system design questions, here are some resources that I found quite useful and hopefully will be helpful to you as well.

Books



Elements of Programming Interviews: Java version and Python version



Free Online Resources

5-star Comprehensive Tech Interview Handbook

Assorted Notes from rafal.io

System Design Gitbook by soulmachine (Online, PDF and epub)

Leetcode Algorithmic Questions and Solutions Gitbook by soulmachine (Online, PDF and epub)

Top 10 Algorithms for Coding Interview from programmingcreek, also Leetcode grouped by type

Cracking the coding interview questions and answers by Hawstein (in C++, Chinese)

Top 10 algorithms in Interview Questions from GeeksforGeeks (a very good resource, also groups questions by type, e.g. dynamic programming, etc.)

Algorithms@tutorialhorizon

Massive Technical Interviews Tips (very good coverage of system design problems)

Learn for Master
Leetcode questions organized by companies


There are also lots of video tutorials that gives more in-depth explanation how to solve problems. One good example is Huahua's Tech Road, it has the latest collection of Leetcode problems as well. If you search on Youtube, there are tons of similar resources as well.

Online Judge and Test Sites


- Leetcode
- Lintcode
- POJ
- Interview Cake
- Hacker Rank
- TopCoder
- Kaggle (for data science and machine learning)

Tuesday, September 26, 2017

Probabilistic Data Structures and Stream Data Processing






















The scale and the new way of stream processing has given rise to many interesting data structures and algorithms.

Here are some good resources that cover the topics like:

"Some Important Streaming Algorithms You Should Know About", covers several essential data structures and algorithms, from Ted Dunning

"Probabilistic Data Structures for Web Analytics and Data Mining", a really nice overview from Highly Scalable Blog:

A comprehensive list of the papers, presentations and talks by debasishg

Stanford CS369G: Algorithmic Techniques for Big Data

Stanford CS168: The Modern Algorithmic Toolbox

MIRI Seminar on Data Streams (Spring 2015 Edition)

Counting Items, Cardinality

- HashSet
- Linear Probabilistic Counter
- LogLog and HyperLogLog

Frequency Estimate, Top K

- Count Min Sketch
- Count Mean Min Sketch

Membership Query

- Bloom Filter
- Cuckoo Filter

Percentile and Quantile

- Q-digest
- t-digest



Thursday, December 8, 2016

Linksfest to Get Started with Apache Flink


Flink, another great data processing platform, has been a rising star this year. It is a high performance stream and batch data processing data platform, with fault-tolerant, scalable, distributed data stream computation at its core.

Here are several links and resources to get you started.

Company and Community
dataArtisans, company behind Flink
Google Trends comparing Flink, Spark and Storm (Spark is still way more popular)


Books

Introduction to Apache Flink, book from Flink core developers, highly recommend to start your Flink journey with. It is a Free download from MapR.

Flink in Action (MEAP, available in Spring 2017), the first chapter (PDF) is Free and gives a good overview.


Quick start guide


Talks and Videos


Slides
Alibaba slides on Blink, their fork of Flink, Alibaba is one of the biggest online e-commerce site in China.


Performance and Benchmark


Setup

2016 Holiday Guide for Robot Toys

Holiday is just around the corner and it's time to order gifts from "Santa". This year, I decided to give my son something different, something other than candies, chocolates, pokemon cards, lego, etc.

Since he has been exposed to basic programming concepts through code.org and Scratch. So..., how about a programmable Robot for this Christmas? Sounds good.

After doing some research and comparison, we ordered Ozobot Evo. To get started out of box, it supports a color-code based language for various actions, e.g. follow the black line and move forward, stop at the red color, rotating at the blue color and play color light and music, etc. You can also customize the action with a mobile app on the phone or tablet with an environment similar to Scratch.

When he grows up a bit more, we might introduce marty the robot to him. It looks and works more like the robots we know about. It also teaches some real mechanical dynamics for the kids.



Here are some notes I took during the research, hope it will be useful to you.


Ozobot Bit
only supports the colored line language
both 1.0 and 2.0 available on amazon (around $60)






Ozobot Evo
More advanced than Bit, supports the colored line language and a Scratch like visual programming language, can control the robot using a mobile app, supports social interactions with friends’ robots.
available on amazon (around $100):





Codeybot
available on amazon: $169.99





Cozmo
A playful companion, a robot that has personality, very cute!
available on amazon (around $300):




marty the robot
This is for more grown-up kids, more makebot-like robot, fully programable, start with Scratch, then move to Python. The way they dance together looks so funny ;-)
not available yet, currently on crowdsourcing





Honeybot
kids education robot and companion, not that programmable.
Founder from Shenzhen, China (around $230)
小哈早教机器人





aido family robot
size of a toddler, family robot, assistant, voice control, helper, etc. Reminds me of Baymax in Big Hero 6 ;-)
available for pre-order (around $600): will ship in early 2017




Saturday, November 26, 2016

Java Concurrency Counters Benchmark




















Java concurrency utilities have kept evolving and provides many different ways to achieve similar tasks. Recently, we had a task to implement a concurrent counter. This triggered my interest in comparing different ways and their performance under various read and write workload.


The end result is a simple concurrent counter implemented in various ways:
The benchmark is implemented using JMH, the standard way for reliable Java performance microbenchmark. You can find several really nice tutorials on JMH in the References section.


In my benchmark, there are write and read operations on the counter. The write takes 10ms and read takes 2ms. I set the number of read and write threads to simulate different mix of the workload scenarios using JMH group.

Both the source code and benchmark raw data, Excel sheets and visualizations can be found in the git repo: java-concurrency-counters-benchmark.

Here is a quick summary based on my experiment (I only set 2 rounds of warmups and 2 rounds of benchmark due to limited time):
  • AtomicLong and LongAdder has similar throughput. In read-heavy workloads, AtomicLong has better read and write throughput than LongAdder. In write-heavy workloads, LongAdder has slightly better write throughput.
  • Fair lock has lower throughput than regular lock in general, but not always.
  • Consider using ReentrantLock or ReentrantReadWriteLock if you need high read throughput and the concurrency level is high.
  • StampedLock provides very good write throughput in all the read-write mixes, if write throughput is important to you, you can try it. At the same time, if you need comparatively good read throughput, try optimistic read StampedLock. It has really good read throughput when concurrency level is high compared with regular StampedLock.

Special thanks and references:

Tuesday, May 17, 2016

Learning Data Visualization

Data visualization provides insightful tools to visually analyze the data, observe the trend, compare the data series, filter out the data noise, etc.

I spent some time learning several most commonly used JavaScript data visualization libraries. It is really exciting to turn monotonous numbers into beautiful charts.

Here is the git repo that has the sample charts I am playing with: https://github.com/guozheng/learn-dataviz

If you want to quickly create charts using available ones, I'd recommend using either HighCharts or Google Charts. If you need to do heavy customization, or you need to create new chart types, then D3.js, NVD3, C3.js, React D3 provides the D3.js based solutions, very powerful and flexible.

Thursday, December 24, 2015

Set up a Python dev environment easily for data scientist

More than 3 years ago, I wrote about how to set up Python3 dev environment on the Mac OSX. You need to jump through several hoops to get the job done.

Now, driven by the needs of data science, Python has become the 4th most popular language (according to TIOBE Index for Dec) and there have been a lot of interesting work to improve the usability of the tools.

Based on the homework I did today, the easiest way to set up your python dev environment is simply by using Anaconda. It is a great open source analytics platform from Continuum Analytics. It comes with toolings such as conda, the package manager, and many popular python libraries for data science needs. The company also offers cloud-based services for life cycle management of python packages, notebooks, etc.

Fat Installation with Anaconda

Simply follow the instructions here: http://docs.continuum.io/anaconda/install. By default it installs to your home directory (~/anaconda), which can be customized with the installer. You need to add ~/anaconda/bin to your PATH if the installer does not patch your PATH environment setting.

To update your Anaconda installation, simply run:
>conda update anaconda

Conda is a great package manager for Python, more details on conda later in the post.

So, what got installed? You can find the detailed list here. If you also need to work with R, you can install r-essentials by running:
>conda install -c r r-essentials

This installs "IRKernel and over 80 mostly used R packages including dplyr, shiny, ggplot2, tidyr, caret and nnet".

Slim Installation with Miniconda

If you do not want to use the fat installation from Anaconda, you can also install Miniconda, which only includes Python and several essential packages. You can download the installer for your platform, see instructions here.

Using Anaconda

With Anaconda or Miniconda installed, you are all set for development. Several quick notes that could help you have more fun.

conda, a package manager to rule them all

Conda is the command line package manager that solves a lot of issues with package and library management with Python. It is actually a package manager not just for Python, I even found NodeJS libraries there.

A quick list of features conda provides:
  • virtual environments: it enables you to create separate environments with different Python version, list of libraries, etc. Something Virtualenv tries to provide, but much easier.
  • package management
  • build and distribute packages: you can either use Anadonda Cloud service, or host your own easily.

To learn more, check out conda cheat sheet (PDF), read conda official doc and watch the demo video (around 20 min, highly recommend).

Anaconda Cloud

Anaconda cloud (previously known as Binstar) is a hosted package management service for notebooks, environments, conda and PyPI packages, etc. Several quick links:




IDE integration

Anaconda can be easily integrated with your favorite IDEs, as mentioned here. To be frank, I am not aware of so many Python IDEs. I mostly use either text editor (such as VIM) or PyCharm from JetBrains.

The latest PyCharm already supports conda. All you need to do is add a new interpreter in preferences, and set it to your Anaconda python installation (e.g. ~/anaconda/bin/python) or the specific conda environment python installation (PyCharm supports both VirtualEnv and Conda env).


Ok, that's about it, hope you enjoy Anaconda and Python without the hassle of dev environment setup anymore.

Tuesday, December 22, 2015

how Dropbox and Evernote file sync works

Spent some time trying to understand better how Dropbox and Evernote sync changes across different devices (mobile, desktop client, Web browser, etc.). Here are some of the interesting papers and articles that I found. Note that they might be outdated a little (you can see the timestamps).

Dropbox:


1. IMC'12 paper "Inside Dropbox: Understanding Personal Cloud Storage Services" by Idilio Drago, etc. (Nov 2012).

The paper studies the Dropbox architecture and traffic by intercepting and analyzing traffic data. It provides many insights about various control and data flow, service components, protocols, etc.

2. "Streaming File Synchronization" from Dropbox tech blog (July 2014).

This blog post gives an overview of file sync and presents a new stream-based sync mechanism that improves latency by upto 2X.

3. "Inside LAN Sync" from Dropbox tech blog (Oct 2015).

This blog post describes a new enhancement called LAN sync, which allows devices on the same network to share files without upload/download through Dropbox servers.

Evernote:


1. Core Concepts in dev API doc, especially the Data Model, which defines various data structures, familiar to you if you use Evernote a lot, like me.

2. Synchronization specification in dev doc: "Evernote Synchronization via EDAM" (Jan 2013)


If you are interested, you can also look into FUSE, which is a user space filesystem abstraction. You can build your own Dropbox and Evernote ;-)

Sunday, September 27, 2015

order of event queue in Node.JS event loop

I was reading the book "Node.JS in Practice", in Chapter 2, Technique 14, it talks about the order of scheduling I/O events, setImmediate, setTimeout/setInterval and process.nextTick. Like in the following screenshot from the book:


However, it seem that the ordering is a bit different, from my test, it is more like: process.nextTick, setTimeout/setInterval, setImmediate.

Here is the sample test code and result (Node.JS v4.1.0):

setImmediate(function() {
    console.log("from setImmediate");
});

setTimeout(function() {
    console.log("from setTimeout");
}, 10);

process.nextTick(function() {
    console.log("from process.nextTick");
});

console.log("hello");

output:
hello
from process.nextTick
from setTimeout
from setImmediate


Monday, September 21, 2015

A retouch of JavaScript and Node

It has been more than two years since I last touched JavaScript and Node. My current projects are mostly centered around Java. But it was always fun to come back and refresh my memory and knowledge about it.

It almost feels like traveling through time machine, too many things have changed over the past two years. Node was forked into io.js and ES6 has been out and getting traction. And there are new frameworks out each week. Frontend engineers must have been having a tough life to keep up, and tons of fun as well.

Here I just keep some book notes for my reading through the book "Node.js in Action". The book itself turned out to be a bit outdated, but many basics are still valid. There is also another more recent Manning book "Node.js in Practice".

Difference between exports and module.exports
exports is a reference to module.exports, so as long as you do not reassign it to something different, they are the same.

Module search sequence
search for node_modules recursively from current directory, if not found, then search for environment variable NODE_MODULE or NODE_PATH.

Module require search sequence
Search for index.js, then inside package.json to find the "main" definition.

Flow control libraries
See article for a discussion about how to handle async programming with JavaScript: How to survive asynchronous programming in JavaScript

unit test frameworks
should.js: assertion lib: https://github.com/tj/should.js/

functional test frameworks

Keep app running/restart


Node Web frameworks, so many of them
Hapi from walmartlabs: http://hapijs.com
A good intro about why Hapi was created: http://hueniverse.com/2012/12/20/hapi-a-prologue/

Kraken from paypal: http://krakenjs.com
Koa, next gen Node Web framework using ES6: http://koajs.com
LoopBackhttp://loopback.io
Sailsjs, MVC pattern similar to RoR: http://sailsjs.org





Performance comparison of Express, hapi, and Restify: https://raygun.io/blog/2015/03/node-performance-hapi-express-js-restify/

Monday, April 20, 2015

Performance Testing with JMeter for REST Services - A Quick Start Guide

Started to pick up JMeter for a project that exposes a REST API. It is a quite versatile and popular performance and stress test tool. And people have built plugins to extend it.

Official guide: https://jmeter.apache.org/index.html
Extra plugins: https://github.com/undera/jmeter-plugins
Two books by Bayo Erinle: Performance Testing with JMeter 2.9 (2nd edition is coming out soon) and JMeter Cookbook

1. Install JMeter and Plugins

If you are on a Mac, using Homebrew is the easiest way, it installs both vanilla JMeter and extra plugins:

brew install jmeter --with-plugins
==> Downloading https://www.apache.org/dyn/closer.cgi?path=jmeter/binaries/apache-jmeter-2.13.tgz
==> Best Mirror http://mirrors.sonic.net/apache/jmeter/binaries/apache-jmeter-2.13.tgz
######################################################################## 100.0%
==> Downloading http://jmeter-plugins.org/downloads/file/JMeterPlugins-Standard-1.2.1.zip
######################################################################## 100.0%
==> Downloading http://jmeter-plugins.org/downloads/file/ServerAgent-2.2.1.zip
######################################################################## 100.0%
==> Downloading http://jmeter-plugins.org/downloads/file/JMeterPlugins-Extras-1.2.1.zip
######################################################################## 100.0%
==> Downloading http://jmeter-plugins.org/downloads/file/JMeterPlugins-ExtrasLibs-1.2.1.zip
######################################################################## 100.0%
==> Downloading http://jmeter-plugins.org/downloads/file/JMeterPlugins-WebDriver-1.2.1.zip
######################################################################## 100.0%
==> Downloading http://jmeter-plugins.org/downloads/file/JMeterPlugins-Hadoop-1.2.1.zip
######################################################################## 100.0%
🍺  /usr/local/Cellar/jmeter/2.13: 1926 files, 115M, built in 74 seconds

If you are on other platforms, do these:

  1. download JMeter from the official site.
  2. download and install extra plugins based on your use cases. These plugins are grouped into several packages, see the detailed plugins package content page to decide what you need. I only installed "Standard Set" and "Extra Set". Installing these plugin packages is simply unzipping them to the installation directory of JMeter, e.g. they install jars into install_dir/lib/ext, or install_dir/bin, etc., see plugin installation guide for more details and minor config changes. The download page has all the links for the plugin packages.
  3. ServerAgent-X.X.X.zip contains the PerfMon Sever Agent that you need to run on the server under test. To run the agent, no special permissions are required. After the agent is running, you can use PerfMon Metrics Collector Listener to connect to the agent and monitor various metrics for CPU, Memory, Swap, Disk and Network I/O, etc. See the document for PerfMon Server Agent and Servers Performance Monitoring for more details.


2. Using JMeter and Plugins

JMeter runs in various modes, you can use with a GUI client or without, you can also set up remote test clients for distributed testing to simulate a more practical workload and traffic pattern.

Here is a basic test for HTTP GET request for a sample service API from geonames.org:

URL: http://api.geonames.org/citiesJSON?north=44.1&south=-9.9&east=-22.4&west=55.2&lang=de&username=demo

Here is the screencast (click on it), note those listeners starts with "jp@gc" are from the non-standard plugins we installed above.





3. Other Interesting Tools and Resources


gatling.io: another high performance open source load testing framework based on Scala, Akka and Netty. It has a DSL based on Scala. It also has nice integration with Jenkins.

yandex-tank: Load testing tool written in Python. For more details, check out its documents.

BlazeMeter: a hosted performance testing service, you can easily reuse your JMeter test scripts with it. It also provides integration with Jenkins CI/CD and supports mobile performance testing. Here is a quick screencast from its website:





Loadsophia: This is a service provided by BlazeMeter, it stores and visualizes the performance test results. The organic visualization in JMeter is quite limited and non-interactive. This service makes analyzing performance data intuitive and fun. It supports test results from tools like JMeter, Apache Benchmark and Yandex.Tank. You can see examples provided publicly by existing users here: http://loadosophia.org/examples/

flood.io: Cloud load testing tool, it supports JMeter and Gastling. Here is a sample report: https://flood.io/d384673f64e3a3


Sunday, February 22, 2015

Insights into the success of Storm

Just read through Nathan Marz's post about the history of Storm. This is really a nice recap of how to successfully start, grow and maintain a great open source project. Technical excellence is important, but the marketing, growing the community and adoption is even more critical.

Here is his post "History of Apache Storm and Lessons Learned".

I am really looking forward to his new book on the lambda architecture: Big Data, principles and best practices of scalable realtime data systems.

Tuesday, December 30, 2014

Swift coding style guide













Found two coding styles for Swift:
Interesting notes:

1. In github style, it suggests that let should be used over var binding whenever possible. This is to explicitly show the intent that a value is supposed to or not supposed to change.


2. In raywenderlich style, when declaring protocol conformance, use separate extension instead of declaring all together. Also, do not forget to add // MARK comments.

Preferred:
class MyViewcontroller: UIViewController {
  // class stuff here
}

// MARK: - UITableViewDataSource
extension MyViewcontroller: UITableViewDataSource {
  // table view data source methods
}

// MARK: - UIScrollViewDelegate
extension MyViewcontroller: UIScrollViewDelegate {
  // scroll view delegate methods
}
Not Preferred:
class MyViewcontroller: UIViewController, UITableViewDataSource, UIScrollViewDelegate {
  // all methods
}

3. In raywenderlich style, when unwrapping the optional, shadow the original name instead of using a new name.

Preferred:
var subview: UIView?

// later on...
if let subview = subview {
  // do something with unwrapped subview
}
Not Preferred:
var optionalSubview: UIView?

if let unwrappedSubview = optionalSubview {
  // do something with unwrappedSubview
}

4. In github style, prefer implicit getters on read-only properties.

Preferred:
var myGreatProperty: Int {
    return 4
}

subscript(index: Int) -> T {
    return objects[index]
}
Not Preferred:
var myGreatProperty: Int {
    get {
        return 4
    }
}

subscript(index: Int) -> T {
    get {
        return objects[index]
    }
}

5. In github style guide, it is mentioned to prefer structs over classes. Since I am still quite new to Swift, I will need to learn a bit more to really understand it.

Saturday, November 29, 2014

book notes for Building Applications with iBeacon

I am always very interested in the location-based mobile applications, in particular indoor location apps. I've even explored a little bit about creating a mobile app that helps locating and assembling colleagues in a crowded cafeteria during lunch. At that time, what I learned is that indoor tracking is still an area being actively researched and explored, many solutions use wifi router capabilities specific to vendors such as Cisco.

Lately, I have quickly went through Matt Gast's book on iBeacon: Building Applications with iBeacon. This is a very concise book on the topic, only 80 pages. It gives a quick overview about iBeacon technology mainly focused on iOS.


Here are the book notes I took:

Companies

Estimote
One of the earliest developers of beacon technology. Estimote beacons have fixed configuration parameters and, in particular, administrators cannot set the UUID.

RadBeacon
RadBeacon is a $29 USB dongle that performs the transmission functions of an iBeacon. All you have to supply is USB power. Configuration of the beacon’s numbers is done through an app.

Kontakt
Kontakt sells an ARM-based iBeacon as well as tools for manag ing iBeacons and analyzing user interactions with them.

Also compatible with android

Gelo
Gelo’s Beacons are waterproof and designed for both indoor and outdoor use, and the batteries can be replaced manually using simple tools.





Hardware
  • Mac (Yosemite stops supporting Mac as iBeacon)
  • iOS devices
  • Raspberry Pi
  • Arduino: BLEduino, BLE Mini from RedBearLab
  • Nordic Semi nRF1822


iOS Apps

- A personal notification beacon for the iPhone. It comes with a beacon device and Geohopper for iOS. It sends notification based on your geo-location. It also integrates with web services for automated workflow.

(Developer Tools)

There are lots of developer util tooks that turns iOS devices into iBeacons. The list can go on and on, here are some apps I found in the app store:
  • Beacon Broadcaster
  • Locate Beacon (from Radius Networks)
  • Beacon Manager
  • My Beacon
  • Beacon Toolkit
  • Beacon Harvester: help you find and save iBeacons around you
  • Beacon Bits
(Games)

One interesting use case for iBeacon is the treasure hunt games. There are several demoes during the mobile developer conferences, very interesting to connect mobile and real world in a playful way. For example, Beacon Scavenger Hunt (from Radius Networks) is a treasure hunt game to collect scavenger hunt’s badges.



Mac Apps

It was very bad that Yosemite does not support turning a Mac into an iBeacon. Maybe this is one of the bugs with Yosemite?


Mavericks as an iBeacon: https://github.com/mttrb/BeaconOSX



a nice thread on StackOverflow about turning your mac into iBeacon: http://stackoverflow.com/questions/19410398/turn-macbook-into-ibeacon


Use Cases


10 things to do with iBeacon: http://blog.twocanoes.com/post/68861362715/10-awesome-things-you-can-do-today-with-ibeacons



Other Useful Resources

Apple's Official Doc on iBeacon: https://developer.apple.com/ibeacon/
Radius Networks Developer Guides: http://developer.radiusnetworks.com
beekn.net: a website dedicated to topics on beacons with Bluetooth Low Energy tech (BLE)

Friday, October 31, 2014

Exposing RDBMS over REST HTTP API

I was working on a Storm project where the work nodes run in a tightly controlled grid environment. So, directly RDBMS access through traditional mechanism is prohibited since only certain ports are open for inbound and outbound traffic. So, I ended up writing a quick and dirty HTTP proxy that exposes certain MySQL database operations using REST API calls.

Then I just found this is actually quite a common use case and several people have written generic HTTP servers to expose REST APIs for database access.

One such project is jdbc-http-server, really handy. I will see if I can replace my own version with that.

Thursday, August 28, 2014

Friday, March 14, 2014

Twisting Maven pom.xml for your legacy code

Recently, I have been working on a legacy project which was not using the standard Maven pom conventions, source code and test code are located at separate paths, the directory structure is also not follow the standard.

So, now we are starting to add more unit tests and integrate that with CI pipeline. The code base is ~200MB including everything. Instead of restructuring the whole project layout, which could block the active development and introduce unpredictable bugs, we decided to twist the pom as best as we can. Here are some nice tips I learned (I am a Maven newbie).

-1. Refactor Your Code

Testing should not be an after-thought. It should be considered along the initial code design and implementation. Apply design patterns, use modular designs and other techniques so that writing tests  become possible in the first place.

0. Writing Unit Tests

There are many unit testing frameworks. Two of the popular ones we use in the company are JUnit and TestNG. Here is a nice StackOverflow comparison for them. Note that if you are using Eclipse, you will need to install TestNG plugin, while JUnit support is built-in. Other IDEs like IntelliJ and Netbeans support both too.

There are several mocking frameworks as well: Mockito, Powermock, EasyMock, jMock, just to name a few. We are using Mockito and Powermock. Here is a nice quick guide how to use them. If you are wondering why we need both, it's because Powermock addresses several features missing from Mockito, such as mocking static methods, etc.

Vogella has several short but useful guides on unit testing, highly recommend:


1. Maven Surefire Plugin with both JUnit and TestNG tests

This is the plugin that runs the unit tests and publish test results. The plugin is documented well on its website, so I am not going to repeat anything here. Quick summary:

  • It can easily include, exclude tests, skip tests (think twice before you do), etc.
  • It support JUnit, TestNG, plain POJO tests. The report format is compatible with JUnit output, so it can be easily integrated with CI tools.
  • It also supports parallel test runs.
  • etc.
Here is a list of all the configuration options for Surefire plugin, very useful.

Normally, you would pick a testing framework and stick to it. But in our case, we have both tests written in JUnit and TestNG under the same test directory. So, how to support that?

Luckily, Marcin has found a solution already to have JUnit and TestNG tests live happily together, see his post here for details. He also has a sample pom that you can use as boilerplate. Basically, you declare dependencies inside Surefire plugin:

...
<properties>
    <surefire.version>2.16</surefire.version>
</properties>

...

<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>${surefire.version}</version>
    <dependencies>
        <dependency>
            <groupId>org.apache.maven.surefire</groupId>
            <artifactId>surefire-junit47</artifactId>
            <version>${surefire.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven.surefire</groupId>
            <artifactId>surefire-testng</artifactId>
            <version>${surefire.version}</version>
        </dependency>
    </dependencies>
</plugin>
...

2. Maven compiler plugin

Maven compiler plugin is used to compile your source code. Here are the lists of configuration options for its compiler:compile and compiler:testCompile goals:

But our problem is that it turns out the compiler plugin assumes the source code and test should live under the same root source code directory. In our case, this is not the case. I tried various options such as "testSource", "testIncludes" to specify the test path, but without luck.

Finally, I found a plugin build-helper-maven, which allows customized source and test directories. And it worked like a charm (borrowing from its website):

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>build-helper-maven-plugin</artifactId>
        <version>1.8</version>
        <executions>
          <execution>
            <id>add-test-source</id>
            <phase>generate-test-sources</phase>
            <goals>
              <goal>add-test-source</goal>
            </goals>
            <configuration>
              <sources>
                <source>some directory</source>
                ...
              </sources>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

3. Maven Clover Plugin for Code Coverage

To generate code coverage, you can use the Maven Clover plugin, note that Clover is free for non-commierical use, for commercial use, you will need to obtain a license and configure the plugin to point to the license file.


4. Maven FindBugs Plugin

FindBugs is a code analysis tool to find potential bugs in your code. It has nice IDE integration and it also integrates well with Maven. You can set it up as a step in CI so that if the bugs will fail the build. I actually scanned our code base and found several severe bugs (one is a switch statement without break, similar to Apple's recent SSL bug).

Please see the plugin website to set it up, quite straightforward.


5. "One Last Thing"

Another useful tip I found out is that when some of the plugin runs, e.g. test, code coverage, findbugs, etc. they require a fair amount of memory. Take the Surefire for example, depending on your configuration, it will fork separate JVM and threads to run the tests. I had JVM exited abruptly in several cases due to this reason.

Refer to the above configuration options to add customized JVM options. For example, for Maven compiler plugin:

<argLine>-Xmx2048m -XX:MaxPermSize=1024m</argLine>

For Maven compiler plugin:

</compilerArgs><arg>-Xms2048m</arg><arg>-XX:MaxPermSize=1024m</arg></compilerArgs>

Friday, December 27, 2013

hadoop shell commands auto-completion

For many users including myself, one of the nice features of BASH is its tab completion, which saves us so much typing. So, when I switched to the Hadoop Shell, it feels so inconvenient since there are many commands and options to remember.

Then I searched around and found one hadoop completion script from Facebook hadoop-20 github repo, but the script does not work for my hadoop installed using Homebrew.

So, I modified it to make it work. You can try it out from my hadoop-completion repo on github. All the installation instructions are there:

https://github.com/guozheng/hadoop-completion

BTW, Bash-Completion includes a collection of similar auto-completion scripts, highly recommend to use it. You will find your life with git cli, ssh, etc. much easier.


References:

- Programmable Bash Completion Buildins (for compgen and complete commands)

- Write your own Bash Completion Function (how to write a customized Bash completion script)

- Get Bash Completion for Mac OS X (a set of built-in scripts for commonly used tools, svn, make, gzip, ssh, git, etc., note that you will need to install git CLI using Homebrew to install the git completion scripts)