Home

Awesome

Creating bespoke applications with the org.beryx.runtime plugin

This simple Windows application shows how to create multiple executable images, each one customized for a different client.

For each customer, we store its specific resources and configuration files in a subdirectory of the config directory. The name of the subdirectory is given by the customerId. In our example, we consider three customers: Amazon, Facebook, and Google, where the customerId is the customer name in lowercase.

The bespoke executables display the customer logo and a greeting. The greeting message is provided by a DLL available in the dll directory. The color of the greeting message is configured in the customer.properties file available in each customer-specific subdirectory.

customerId: amazoncustomerId: facebookcustomerId: google
amazonfacebookgoogle

To create the bespoke executables run:

gradlew jpackageAll

The images will be available in build\jpackage. You can start the applications by executing:

build\jpackage\amazon\demoProject\demoProject.exe
build\jpackage\facebook\demoProject\demoProject.exe
build\jpackage\google\demoProject\demoProject.exe

You can also run the applications directly from Gradle:

gradlew -P customerId=amazon run
gradlew -P customerId=facebook run
gradlew -P customerId=google run

As you can see, we use the customerId property to tell Gradle which bespoke application to run. A default value for the customerId property is provided in gradle.properties:

customerId=google

You can also use the installDist task to create bespoke distributions:

gradlew -P customerId=amazon installDist
gradlew -P customerId=facebook installDist
gradlew -P customerId=google installDist

The Gradle script takes care of several things:

run {
    jvmArgs "-Djava.library.path=$projectDir/dll"
}
test {
    jvmArgs "-Djava.library.path=$projectDir/dll"
}
tasks.processResources {
    from "config/$customerId"
    into sourceSets.main.java.outputDir
}
tasks.installDist {
    doLast {
        copy {
            from "dll"
            into "$destinationDir/bin"
        }
    }
}
tasks.startScripts {
    def gen = windowsStartScriptGenerator
    gen.template = resources.text.fromString(gen.template.asString().replace(
    	'DEFAULT_JVM_OPTS=${defaultJvmOpts}',
    	'DEFAULT_JVM_OPTS="-Djava.library.path=%APP_HOME%\\\\bin" ${defaultJvmOpts}'))
}
tasks.jpackageImage {
    doLast {
        copy {
            from "dll"
            into "$jpackageData.imageOutputDir/$jpackageData.imageName"
        }
    }
}

Note that there is no need to set java.library.path, because it already includes the directory of the executable image.

task jpackageAll(group: 'distribution', description: 'Creating packages for all customers') {
    doFirst {
        file("config").eachDir {
            def customer = it.name
            GradleRunner.create()
                        .withDebug(true)
                        .withProjectDir(projectDir)
                        .forwardOutput()
                        .withArguments("-is", "-P", "customerId=$customer", "build", "jpackage")
                        .build();
        }
    }
}