Social Icons


Featured Posts

Tuesday, October 20, 2015

Building Akka bundle with all dependencies using Gradle

One of the issues I ran into recently while building an Akka remoting application with Gradle was to deal with having multiple reference.conf files within the jar file. This is clearly documented on the Akka documentation here. But was a bit hard to figure out a good solution that works with Gradle.

For example, I was creating the jar bundle using the standard fatJar task:
  task fatJar(type: Jar) {
    manifest {
      attributes 'Main-class': 'your-main-class'
    from {
      configurations.compile.collect { it.isDirectory()  ?  it  :  zipTree(it) }
    with jar  

But when tried to run the Akka application, ran into errors that are not quite obvious. For example:

No configuration setting found for key 'akka.remote.untrusted-mode'
No configuration setting found for key 'akka.version'


The issue is because Akka bundles reference.conf in each jar files (e.g: akka-actor.jar, akka-remote.jar etc). If all these jar files are merged into one, as one will do with jar-with-dependencies, then it requires the different reference.conf also should be merged. If not, the class loader will pick one of the reference.conf files. The results are un-predictable as the Akka system will be missing the needed default informations.

The solution was to use gradle-shadow plugin.

Here is the solution that worked:
buildscript {
  repositories {
  dependencies {
    classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.2'

apply plugin: 'com.github.johnrengelman.shadow'

shadowJar {
  transform(com.github.jengelman.gradle.plugins.shadow.transformers.AppendingTransformer) {
    resource = 'reference.conf'
Then build the application with gradle shadowJar

Tuesday, August 18, 2015

Ubuntu + Jenkins + Gradle + Embedded Tomcat + Port 80

Port 80 is a privileged port and normal users cannot listen on this port. I had a recent requirement to run some test cases on an embedded tomcat running on Port 80 during Jenkins build. Here is the steps worked for me to achieve this.

Gradle File

apply plugin: 'java'
apply plugin: 'war'

buildscript {
  repositories {
  dependencies {
    classpath 'com.bmuschko:gradle-tomcat-plugin:2.2.2'

apply plugin: 'com.bmuschko.tomcat'

tomcat {
  httpPort = 80
  contextPath = "/"

Setup authbind

authbind will allow non-root user to listen on privileged ports.
sudo apt-get install authbind
sudo touch /etc/authbind/byport/80
sudo chmod 500 /etc/authbind/byport/80 
sudo chown jenkins /etc/authbind/byport/80

Configure Jenkins

Modify the Jenkins run command (last line in do_start routine)to the following
$SU -l $JENKINS_USER --shell=/bin/bash -c "$DAEMON $DAEMON_ARGS -- authbind --deep $JAVA $JAVA_ARGS -jar $JENKINS_WAR $JENKINS_ARGS" || return 2

Monday, August 10, 2015

Docker Tips

Detaching from a docker container without killing it

Use keys Control-Q Control-P to detach from the container
~docker-host> docker attach 
root@3727bb82884: ^Q^P

Copy a text file from host to container

cat my-test-file.txt | docker exec -i 3727bb82884 sh -c 'cat > /root/my-test-file.txt'

Friday, July 17, 2015

Upgrading CrashPlan App on Qnap TS-251

I started to notice lately that my Qnap is not backing up to CrashPlan. I had set up my Qnap TS-251 and have Qnap app properly installed and configured. It was backing up properly, but for the last couple of months it has not been backing up, even though there are data changes in my NAS. Digging further, I noticed CrashPlan app tries to upgrade to a new version and the upgrade is failing. Backup was not happening when there is a pending upgrade.

When ever I tried to do an upgrade from the UI, CrashPlan service completely stops. I had to manually restart the CrashPlan service, but then it will go back to do the upgrade!!

Digging further, I noticed that there are issues with the upgrade script and it fails. I had to do the following steps to upgrade the Qnap app and restart my backup.


  • Qnap Version: TS-251 4.1.4 (2015/05/22)
  • CrashPlan app version: 4.2.0_35

Upgrading CrashPlan App

The following steps were needed to this upgrade working

  1. Start the CrashPlan app using the Qnap UI
  2. ssh to the Qnap Server
  3. Stop the CrashPlan service
  4. Modify the config file
  5. Modify the startup script
  6. Change the upgrade script
  7. Manually run the upgrade script(s)
  8. Stop the service using Qnap UI
  9. Modify the config file
  10. Start the CrashPlan app from Qnap UI
  11. Configure the client
  12. Adopt the existing computer if needed
  13. Start the backup
ssh your-qnap-ip
cd /share/CACHEDDEV1_DATA/.qpkg/CrashPlan/conf
/etc/init.d/ stop
Modify the my.service.xml and change the <location> and <serviceHost> tag values to:
Modify the /etc/init.d/
  1. Comment out the line which modifies the <location> in the my.service.xml file. Look for the line starting /bin/sed -i "s/<location.* and put a '#' at the begining of the line
  2. Repeat the same to comment out the place it replaces the <serviceHost>

Modify the upgrade scripts Go to the CrashPlan/upgrade directory and find out the latest directory created by the upgrade script. E.g. Run 'ls -lart' and take the last directory and go into that directory Modify the with the following:
  1. Remove the "-v" parameter from the RM command E.g. RM = "rm -f"
  2. Modify the INIT_SCRIPT value E.g. INIT_SCRIPT = /etc/init.d/
  3. Modify the INSTALL_VARS value E.g. INSTALL_VARS = ../../crashplan.vars
Run the upgrade script
Repeat the same modification to the for any other upgrades. Typically, the upgrades are packaged into jar files and they will be downloaded to the upgrade directory. When one upgrade is done, the system automatically starts the next one. But for this also I had to modify the upgrade script. So need to stop the crash plan and the upgrade script before modifying it.
ps -aef | grep -i upgrade
# And kill the upgrade process if any, modify the upgrade script and run it
Finally modify the conf/my.service.xml and /etc/init.d/ as described before, if the upgrade script has modified these files.

To configure the client, (on MacOS)
  1. Modify the /Applications/ and add the serviceHost to the IP address of the Qnap NAS.
  2. Copy the values from /share/CACHEDEV1_DATA/.qpkg/CrashPlan/var/.ui_info from the Qnap server to the /Library/Application Support/CrashPlan/.ui_info file on the Mac client

Friday, April 24, 2015

Testing POP3 from command line

Without SSL

To test a POP3 account from command line follow these steps. This will connect to the POP3 server using telnet, list the available emails, and retrieve the first one.
telnet <your-email-server>:110
Connected to your-email-server-ip...
Escape character is '^]'.
user <your-mail-server-username>
pass <your-mail-server-pass>
retr 1

With SSL

If you are getting the following error, you will need to access your POP3 server using SSL
user <user-mail-server-username>
- ERR Command is not valid in this state.
To use SSL, use OpenSSL to connect to the server
openssl s_client -crlf -connect <your-email-server>:995
+ OK The Microsoft Exchange POP3 service is ready.
user <your-mail-server-username>
pass <your-mail-server-pass>
+OK User successfully logged on.
retr 1