Determine Which JDK Version a JAR/Class File Was Compiled With

Today I came across a nasty error which occurred in a deployed Java application only but not during development or integration tests. The error went something like the following:

java.lang.NoSuchMethodError: java.nio.ByteBuffer.rewind()Ljava/nio/ByteBuffer;
at nx.serializerkryo.internal.InternalKryoSerialzer.performToStream(
at nx.serializerkryo.internal.InternalKryoSerialzer.serialize(
at nx.serializerkryo.internal.InternalKryoSerialzer.serialize(
at nx.persistence.jre.internal.OptimizedPersistedNodeSerializer.serialize(
at nx.persistence.jre.internal.OptimizedPe<span 				data-mce-type="bookmark" 				id="mce_SELREST_end" 				data-mce-style="overflow:hidden;line-height:0" 				style="overflow:hidden;line-height:0" 			></span>rsistedNodeSerializer.serialize(

Now I had a feeling that this had something to do with me trying to be ahead of the curve and use a Java 9 JDK to compile the application. In order to debug this, I had to confirm which with JDK the classes I was using were compiled with. Thankfully I found a handy thread of StackOverflow.

Unfortunately, it wasn’t immediately obvious to me which solution listed there would work best, so I decided to provide the solution here in a more condensed form. Simply use the following command:

javap -v [path to your class file]

The output will then contain the following line (towards the top of the file):

public class ...
minor version: 0
major version: 50

The major version and minor version indicates which version of Java the class was compiled with. The following contains a list of which Java versions which major versions relate to.

Java SE 9 = 53 (0x35 hex),
Java SE 8 = 52 (0x34 hex),
Java SE 7 = 51 (0x33 hex),
Java SE 6.0 = 50 (0x32 hex),
Java SE 5.0 = 49 (0x31 hex),
JDK 1.4 = 48 (0x30 hex),
JDK 1.3 = 47 (0x2F hex),
JDK 1.2 = 46 (0x2E hex),
JDK 1.1 = 45 (0x2D hex).

Interestingly my files were apparently compiled for Java 6 (Maven compiler plugin was responsible). The problem was that the files were compiled with JDK 9 (though they were compiled for 1.6). Downgrading the JDK used to do the compilation to JDK8 fixed the problem.

A Handy Reference of Maven Parameters

I cannot count the times I have looked up the following through Google. Thus I decided to put together a few handy parameters (or properties or whatever is the correct term) for Maven builds.

All the below are given with the goal install but they can safely be used with any other Maven goal as well.

Skip Tests

mvn install -DskipTests

Build Only From Specified Project

This is only relevant in a multi pom.

mvn install -rf :[artifactId]

Don’t Compile JavaDoc


Don’t Compile GWT



Good Web Design: PayPal Developer Documentation

I find that developer documentation is often not very pleasant to look at and, more importantly, often very difficult to navigate. I worked briefly with the PayPal REST API and, while I found that at times it can be confusing to deal with the numerous APIs PayPal offers, aesthetically their developer documentation is clear and effective.

What I Like

Clear Overall Design

paypal developer documentation

Overall the documentation looks nice and clear. I like the fonts and colours used. The multi-level menu on the left fits in well and provides good means of navigation without feeling overwhelming.

Good Instructions and Code Examples

paypal developer documentation 2

The subheadings are easy to spot and the step-by-step instructions weave code into them quite nicely. Code examples stand out due to the different background colour.

Clear and Informative Footer

Paypal developer documentation 3

The footer for the page fits nicely into the overall design and gives access to a wide range of resources.


Installing Jenkins on Centos 7

I set up a Jenkins server on a brand new Centos 7 VPS. In the following the instructions for doing this in case you are looking at doing the same:

Setting up Jenkins Server

sudo yum install java-1.8.0-openjdk
sudo wget -O /etc/yum.repos.d/jenkins.repo
sudo rpm --import
sudo yum install jenkins

Or for stable version (link did not work for me when I tried it)

sudo wget -O /etc/yum.repos.d/jenkins.repo
sudo rpm --import
yum install jenkins
  • Start Jenkins server
sudo systemctl start jenkins

You should now be able to access Jenkins at (if not, see troubleshooting steps at the bottom).

If you want to access your server more securely on port 80, you can do so by installing ngnix as outlined in this article in step 4: How to Install Jenkins on CentOS 7.

Connecting to a Git Repo

You will probably want to connect to a git repository next. This is also somewhat dependent on the operating system you use, so I provide the steps to do this on CentOS as well:

  • Install git
sudo yum install git
  • Generate an SSH key on the server
ssh-keygen -t rsa
  • When prompted, save the SSH key under the following path (I got this idea from reading the comments here)
  • Assure that the .ssh directory is owned by the Jenkins user:
sudo chown -R jenkins:jenkins /var/lib/jenkins/.ssh
  • Copy the public generated key to your git server (or add it in the GitHub/BitBucket web interface)
  • Assure your git server is listed in the known_hosts file. In my case, since I am using BitBucket my /var/lib/jenkins/.ssh/known_hosts file contains something like the following, ssh-rsa [...]
  • You can now create a new project and use Git as the SCM. You don’t need to provide any git credentials. Jenkins pulls these automatically form the /var/lib/jenkins/.ssh directory. There are good instructions for this available here.

Connecting to GitHub

  • In the Jenkins web interface, click on Credentials and then select the Jenkins Global credentials. Add a credential for GitHub which includes your GitHub username and password.
  • In the Jenkins web interface, click on Manage Jenkins and then on Configure System. Then scroll down to GitHub and then under GitHub servers click the Advanced Button. Then click the button Manage additional GitHub actions.

additional actions

  • In the popup select Convert login and password to token and follow the prompts. This will result in a new credential having been created. Save and reload the page.
  • Now go back to the GitHub servers section and now click to add an additional server. As credential, select the credential which you have just selected.
  • In the Jenkins web interface, click on New Item and then select GitHub organisation and connect it to your user account.

Any of your GitHub projects will be automatically added to Jenkins, if they contain a Jenkinsfile. Here is an example.

Connect with BitBucket

  • First, you will need to install the BitBucket plugin.
  • After it is installed, create a normal git project.
  • Go to the Configuration for this project and select the following option:

BitBucket trigger

  • Log into BitBucket and create a webhook in the settings for your project pointing to your Jenkins server as follows: (note the slash at the end)

Testing a Java Project

Chances are high you would like to run tests against a Java project, in the following, some instructions to get that working:


  • If you cannot open the Jenkins web ui, you most likely have a problem with your firewall. Temporarily disable your firewall with: `sudo systemctl stop iptables` and see if it works then.
  • If it does, you might want to check your rules in `/etc/sysconfig/iptables` and assure that port 8080 is open
  • Check the log file at:
sudo cat /var/log/jenkins/jenkins.log


Continuous Integration Server Overview

Since I plan to set up a continuous integration server in the near future, I had a quick look around for open source and cloud-based solutions; my main concern was finding something which will work for a small scale project and result in reasonable costs.

Jenkins (Open Source)

The best choice if you are looking for an open source CI server. If you are familiar with Java, setting up and running Jenkins on your own is in all likeliness much cheaper than any cloud-based alternative.

Buildbot (Open Source)

Jenkins looks to be more widely used than Buildbot. However, if you have a Python project, Buildbot might be worth considering.

Travis CI (Cloud)

My top choice for open source projects. For commercial projects, however, the costs seem to be quite high starting with US$69 per month.

Circle CI (Cloud)

They offer one build container for free which seems like a very generous offer to me. I haven’t explored though how powerful this container is and how long builds would take.

AWS CodePipeline and AWS CodeDeploy (Cloud)

The best choice if you are using an AWS environment.

Codeship (Cloud)

They offer 100 builds per month for free which seems to be quite reasonable. However, since builds are triggered automatically this figure can be reached relatively quickly even with smaller projects.


Test Latency Between Two Servers (Linux)

Today I was looking for a simple way to test the latency and bandwidth between two Linux servers.

The easiest way, of course, is to just use ping. The ping utility should be available on almost any Linux server and is extremely easy to use. Just login to one of your servers and then execute the following command using the IP address of your second server:

ping x.x.x.x

You can leave this running for a while and when you have seen enough data, just hit Ctrl + C to interrupt the program. This will result in an output such as the following:

PING ( 56(84) bytes of data.
64 bytes from icmp_seq=1 ttl=64 time=0.180 ms
64 bytes from icmp_seq=2 ttl=64 time=0.150 ms
64 bytes from icmp_seq=3 ttl=64 time=0.148 ms
64 bytes from icmp_seq=4 ttl=64 time=0.150 ms
--- ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3000ms
rtt min/avg/max/mdev = 0.148/0.157/0.180/0.013 ms

Important to note here are are the latencies for the individual tests as well as the overall average which are highlighted in bold in the above. This shows us that there is an average latency of 0.157 between the two servers tested.

In order to test the bandwidth and get some more information about latencies, you might also want to install the iperf tool.

Good Web Design: Squarespace

I want to start a new category of articles for this blog where I record web or user experience design I come across and which impresses me. I will start today with the homepage of Squarespace. Since they are a web design company, good design can be expected of course. Some things which I noticed where the following:

Nice Fonts


For headings, they use an all-caps, spaced out font: Gotham with font size 22px, line height 1.6em and letter spacing of 0.2em. The body text is also Gotham with font size 14px and line height of 1.8em.

Simple but Effective Buttons


Buttons come either with a white background and black text or the other way around. The font size used is 11px.

Nice and Clean Gallery of Templates


What I didn’t Like

I think the lack of a main menu makes it quite difficult to find the things one is looking for. To find the gallery of templates, one needs to scroll all the way down to the bottom of the page and then select ‘Websites’. Also the pricing information is not easily accessible.


Free Cloud-based Log and Metrics Management Solutions

I have been looking around for a while for a cloud-based service which allows collecting logs and metrics and analysing them. I am particularly interested in a solution which can be deployed for free for smaller applications/amounts of data.

Here are some of the solutions I came across:



  • Store and analyse logs and metrics
  • Free plan available: For 200MB/day, 7 day data retention
  • It looks to me like the Free plan does not allow using the Loggly API!



  • One of the first and most popular solutions in the space
  • Store and analyse logs and metrics
  • Free version available; allows storing up to 500MB/day; I don’t think there is any limitation on data retention
  • Note that free version requires to install the Splunk server on your own server



  • Based on popular open source ELK stack
  • Free plan allows monitoring up to 5 hosts, but only comes with 30 min data retention


  • Also based on ELK stack
  • Free plan allows 3GB upload per day; data retention limited to 3 days.

Overall, I am not too happy with these offerings. In particular, the short data retention periods seem to make some of these offerings too limited to be useful.

Maybe the best option here would be to install your own ELK stack or Graylog. Here are some guides for that:

Task Management, Planning and Time Tracking

I’ve long been looking for a tool that allows me to plan tasks, manage them and track time for myself and for a small team. Unfortunately, I have not been very successful thus far to find a effective, robust and affordable solution for this.

The latest setup I am using is to use Checkvist for planning and managing tasks and timetrack for tracking time. However, unfortunately I found it becomes a bit cumbersome to plan and manage larger projects with Checkvist and there is no integration between Checkvist and timetrack.

Given these limitations with my current setup, I decided to once again look around for a new tool. Some of my key requirements are:

  • Tracking time per project and task
  • Being able to plan a large number of tasks. Specifically I often have to deal with a lot of ‘optional’ tasks, so tasks which might or might not have to be done.
  • Being able to track the completion status of tasks
  • Nice visualizations and dashboards to see how much time is spent on projects and tasks and how overall project completion is coming along.
  • Cross-platform support, in particular an option to access the tool through a web interface.
  • Ideally they offer a free plan or basic plan that allows creating unlimited projects and tasks
  • Exporting tracked time and projects

With that in mind, I explored the options in the following. To make a long story short, the only solution I could find which satisfied my requirements was MeisterTask.



MeisterTask is a task management solution which integrates with the mind mapping solution MindMeister. I have always been fond of mind maps, so I was excited to investigate this solution further.

I was delighted to find out that meistertask comes with Time Tracking. This works very well.

For planning tasks, I like the feature that it is possible to define relationships between tasks, such as ‘is blocked by’. If tasks, which block another task, are not completed, the blocked task is visually marked as being blocked:


Unfortunately, the free account of MindMeister is quite limited; it is only possible to create three mind maps or so. Also I found the feature to create tasks from mind map nodes not all that useful. However, I don’t think MindMeister integration is necessary to work productively with MindMeister.

The biggest disadvantages of MindMeister as far as I can see is that the Developer API is quite limited. For instance, I can’t find ways to retrieve and write time tracking data.


It seemed to me that Asana does not support time tracking. I tried setting up time tracking with Hubstaff, which seemed quite promising to me. Unfortunately, after creating a new task on a project in Asana, there was a significant delay until that task was available in Hubstaff. I think it is quite critical to being able to create new tasks and report time into them straight away.


It looks like time tracking in Wrike is only available for Business accounts. These currently start at $24.80 pm which I think is a bit pricey.


Avanza does not support unlimited number of projects for their basic accounts.


Too many limitations on the free account for my liking!



Install PHP Application and WordPress Alongside Each Other


You have a webpage like and you would like to serve both WordPress and files from a PHP application from the root domain. For instance, opening

will open a post on WordPress and

will open a page in a PHP application.


  • Set up your php application in /var/www/html
  • Install WordPress /usr/share/wordpress
  • Put the following lines into /usr/share/wordpress/.htacces before # BEGIN WordPress.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond "/var/www/html%{REQUEST_URI}" -f
RewriteRule ^/?(.*)$ /app/$1 [L]


# BEGIN WordPress
  • Put the following line into /etc/httpd/conf/httpd.conf
Alias /app /var/www/html
  • Add the following configuration file to /etc/httpd/conf.d/wordpress.conf
Alias /wordpress /usr/share/wordpress
DocumentRoot /usr/share/wordpress

<Directory /usr/share/wordpress/>
 AddDefaultCharset UTF-8

AllowOverride All

Require all granted


Restart httpd and you are all done!