|
| 1 | +# Creating an RPM for a Java Application |
| 2 | + |
| 3 | +Herein lays an example of creating an RPM for Java Applications with Gradle. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +Creating a RPM that can run a Java application requires two steps. The first is to create a jar file that can be ran. The second is to create a RPM that installs this jar file and its dependecies on the target system. This certainly isn't the only way to do this, but it seems to be the easiest. |
| 8 | + |
| 9 | +## Creating a runnable JAR file |
| 10 | + |
| 11 | +There are many resources out there for creating a runnable JAR file. The Gradle application plugin will even create a jar for you out of the box. A regular JAR file isn't enough, you need a JAR file that also contains all of it dependecies. This kind of Jar file is often called a fat or uber JAR because of these extra dependecies. Luckly for us, a gradle plugin called **Shadow** takes care of this. |
| 12 | + |
| 13 | +You can add shadow to your gradle file by adding the following lines to the beginning of your *.gradle file: |
| 14 | + |
| 15 | +``` |
| 16 | +plugins { |
| 17 | + id 'com.github.johnrengelman.shadow' version '2.0.1' |
| 18 | +} |
| 19 | +``` |
| 20 | + |
| 21 | +Assuming you have the rest of your gradle set up to run your java application, you can immediately use Shadow after adding this line. Shadow adds a few gradle tasks, the one we are interested in is `gradle shadowJar`. See `gradle tasks` for all the exposed tasks shadow introduces. |
| 22 | + |
| 23 | +Try it out. Run `gradle shadowJar` and look in your `build/libs` folder for the newly generated JAR file. you can run this jar file with `java -jar somefile.jar`. |
| 24 | + |
| 25 | +## Creating an RPM package |
| 26 | + |
| 27 | +To create an RPM package I used the `ospackage` gradle plugin. The plugin can be added to your gradle file by editing the plugins field we added in the last section. Modify it to look like: |
| 28 | + |
| 29 | +``` |
| 30 | +plugins { |
| 31 | + id "nebula.ospackage" version "4.4.2" |
| 32 | + id 'com.github.johnrengelman.shadow' version '2.0.1' |
| 33 | +} |
| 34 | +``` |
| 35 | + |
| 36 | +Unlike the shadow plugin, ospackage requires the user to apply this plugin. I did so by adding the following line: |
| 37 | + |
| 38 | +``` |
| 39 | +apply plugin: "nebula.ospackage" |
| 40 | +``` |
| 41 | + |
| 42 | +ospackage doesn't know how to create an RPM specific to your project, it requires some extra configuration. See the [RPM packaging guide](http://rpm-guide.readthedocs.io/en/latest/rpm-guide.html) for information on how to configure it. Give it your best shot, here Is what I came up with: |
| 43 | + |
| 44 | +``` |
| 45 | +ospackage { |
| 46 | + release '1.el7' |
| 47 | + user 'foo' |
| 48 | + permissionGroup "foo" |
| 49 | + summary 'Testing that RPMs can be created and ran using Java.' |
| 50 | +
|
| 51 | + arch 'X86_64' |
| 52 | + os 'LINUX' |
| 53 | + type 'BINARY' |
| 54 | +
|
| 55 | + from (shadowJar.outputs.files) { |
| 56 | + into "/opt/test" |
| 57 | + } |
| 58 | +
|
| 59 | + from("scripts/rpmtest") { |
| 60 | + into "/opt/test" |
| 61 | + fileMode = 0755 |
| 62 | + } |
| 63 | +
|
| 64 | +} |
| 65 | +
|
| 66 | +buildRpm { |
| 67 | + requires("some-dep", "0.2.7", GREATER | EQUAL) |
| 68 | + directory("/opt/test", 0755) |
| 69 | + link("/usr/bin/rpmtest", "/opt/test/rpmtest") |
| 70 | +} |
| 71 | +buildRpm.dependsOn(shadowJar) |
| 72 | +``` |
| 73 | + |
| 74 | +There are a few things to point out in my configuration. First buildRpm.dependsOn(shadowJar). This is required so you can copy the JAR that shadow creates into your RPM. Second, I had to create a script to acutally run my fat JAR. This script is really simple, it just runs: |
| 75 | + |
| 76 | +``` |
| 77 | +#!/usr/bin/env sh |
| 78 | +
|
| 79 | +java -jar /opt/test/rpmtest-* |
| 80 | +``` |
| 81 | + |
| 82 | +After I finished this configuration I tested this approach by installing the rpm and attempting to run it. After a few permissions tweaks and trial and error, I got it running with the solution above. |
| 83 | + |
| 84 | +## References |
| 85 | + |
| 86 | +- [Creating Unix Services and RPM/DEB Packages with Spring Boot and Gradle](https://www.ccampo.me/java/spring/linux/2016/02/15/boot-service-package.html) |
| 87 | +- [Ccampo Example Application](https://github.com/ccampo133/boot-daemon-demo) |
| 88 | +- [Gradle ospackage RPM documentation](https://github.com/nebula-plugins/gradle-ospackage-plugin/wiki/RPM-Plugin) |
| 89 | +- [Shadow (fat) jar documentation](http://imperceptiblethoughts.com/shadow/) |
| 90 | +- [RPM packaging guide](http://rpm-guide.readthedocs.io/en/latest/rpm-guide.html) |
0 commit comments