Suresh Payankannur

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'

etc.

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 {
    jcenter()
  }
  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

0 comments:

Post a Comment

Blog Archive

Scroll To Top