Building Enterprise Mule Apps with Gradle – Part 3

motif

This is the third post on the Gradle Plugin Series, and a lot has happened to the plugin since the first article of the series was published. Today, I’m announcing exciting new features useful for tackling enterprise users’ needs. For more information on how to get started on building apps with , please check the previous blog post and specially the project’s readme file. Now let’s get started.

Fine tuning Dependencies

This plugin is designed to be future-proof and still remain concise, so we’ve introduced a DSL for customizing the mule dependencies to be included as part of the build. This allows users to (in a very concise way) fine-tune the modules, transports and connectors included when unit-testing, compiling your code and running your app.

Also, this DSL enables inclusion of Devkit-generated modules as zip plugins, improving the classloading isolation and allowing you to separate the libraries you define as dependencies from the transitive dependencies included in the plugins; at the same time reducing the amount of files retrieved from the remote server.

Shared Resources (aka Domains)

Mule 3.5.0, introduced the ability to share resources, connectors and libraries between mule projects. It also introduced a new project structure and deployment procedure. The gradle plugin supports this entirely and even allows you to create a template domain project so you can quickly learn what the new structure looks like.

In order to leverage domain projects, the plugin takes advantage of gradle’s ability to build multi-module projects. This way, all the semantics are kept while enabling features such as a single build.gradle file and also compatibility with IDE’s that support gradle.

You simply need to define a standard build.gradle that applies the ‘mule-domain’ plugin and a standard ‘settings.gradle’ to define the project’s modules.

The domain plugins have several goodies including the ability to check if the modules are correctly configured for the domain, fixing the configuration to make sure it works and installing the resulting zip file into a given mule server.

Upload your apps to the Mule Management Console

This feature is, at the moment of writing this post, exclusively available only to ones who choose to build with gradle. The mule gradle plugin offers a very simple DSL for defining your environments, and uploading artifacts into the Management console of the given environment, this feature is similar to the one offered by Anypoint Studio but available for your automated builds. The following is an example of what this DSL looks like:

With this definition in place, we may simply use the ‘uploadToRepository’ task and the app will be built, tested, packaged and uploaded to MMC’s repository.

Deploy your apps to !

This feature is also, at the moment of writing this post, available only for users building their apps with gradle. This plugin now offers the ability to deploy your app to a given CloudHub domain, and through a simple DSL, define multiple environments where the app could be deployed. The following is an example on how to define and use the CloudHub plugin:

//standard plugin definition
apply plugin: 'cloudhub'

//standard plugin configuration

cloudhub. {
    myapp  username: 'login-username', password: 'pass'
    'myapp-dev' username: 'dev-username', password: 'pass'

    defaultDomain = 'myapp-dev'
}

With this definition in place, we may simply invoke the ‘deploy’ task and the app will be built, tested, packaged and uploaded into the configured CloudHub domain.

Unit test apps with DataMapper

Automating unit tests with maven and DataMapper isn’t really a piece of cake. There are several configurations to be created and tested. This is simply because the DataMapper runtime needs to be present (in a non-standard way) when running the unit tests. With this pain in mind, the gradle plugin leverages the tasks required to properly set the testing environment for running DataMapper tests with no additional configuration! The only thing required is to have a valid mule license with DataMapper entitlements in ‘src/test/resources’.


We'd love to hear your opinion on this post

2 Responses to “Building Enterprise Mule Apps with Gradle – Part 3”

  1. Are there issues synchronizing a Domain project within Studio? I run into an issue when synchronizing a domain project within Anypoint studio. I receive the following: An internal error occurred during: “Refreshing gradle project…”.
    Invalid thread access

    And then the console output:
    Defining custom ‘build’ task when using the standard Gradle lifecycle plugins has been deprecated and is scheduled to be removed in Gradle 3.0

    FAILURE: Build failed with an exception.

    * What went wrong:
    Task ‘studio’ not found in root project ‘ConnectedCommerceDomainHub’.

    * Try:
    Run gradle tasks to get a list of available tasks. Run with –info or –debug option to get more log output.

    * Exception is:
    org.gradle.execution.TaskSelectionException: Task ‘studio’ not found in root project ‘ConnectedCommerceDomainHub’.
    at org.gradle.execution.TaskSelector.getSelection(TaskSelector.java:100)
    at org.gradle.execution.TaskSelector.getSelection(TaskSelector.java:75)
    at org.gradle.execution.commandline.CommandLineTaskParser.parseTasks(CommandLineTaskParser.java:42)
    at org.gradle.execution.TaskNameResolvingBuildConfigurationAction.configure(TaskNameResolvingBuildConfigurationAction.java:44)
    at org.gradle.execution.DefaultBuildExecuter.configure(DefaultBuildExecuter.java:42)
    at org.gradle.execution.DefaultBuildExecuter.access$100(DefaultBuildExecuter.java:23)
    at org.gradle.execution.DefaultBuildExecuter$1.proceed(DefaultBuildExecuter.java:48)
    at org.gradle.execution.ExcludedTaskFilteringBuildConfigurationAction.configure(ExcludedTaskFilteringBuildConfigurationAction.java:47)
    at org.gradle.execution.DefaultBuildExecuter.configure(DefaultBuildExecuter.java:42)
    at org.gradle.execution.DefaultBuildExecuter.access$100(DefaultBuildExecuter.java:23)
    at org.gradle.execution.DefaultBuildExecuter$1.proceed(DefaultBuildExecuter.java:48)
    at org.gradle.execution.DefaultTasksBuildExecutionAction.configure(DefaultTasksBuildExecutionAction.java:44)
    at org.gradle.execution.DefaultBuildExecuter.configure(DefaultBuildExecuter.java:42)
    at org.gradle.execution.DefaultBuildExecuter.select(DefaultBuildExecuter.java:35)
    at org.gradle.initialization.DefaultGradleLauncher$5.run(DefaultGradleLauncher.java:162)
    at org.gradle.internal.Factories$1.create(Factories.java:22)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:62)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:47)
    at org.gradle.initialization.DefaultGradleLauncher.runBuildOperation(DefaultGradleLauncher.java:189)
    at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:159)
    at org.gradle.initialization.DefaultGradleLauncher.access$200(DefaultGradleLauncher.java:35)
    at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:104)
    at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:97)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:62)
    at org.gradle.initialization.DefaultGradleLauncher.runRootBuildOperation(DefaultGradleLauncher.java:184)
    at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:97)
    at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:86)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:93)
    at org.gradle.tooling.internal.provider.runner.BuildModelActionRunner.run(BuildModelActionRunner.java:50)
    at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:43)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:27)
    at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:72)
    at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:44)
    at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:49)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:37)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
    at org.gradle.util.Swapper.swap(Swapper.java:38)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.health.DaemonHealthTracker.execute(DaemonHealthTracker.java:47)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:66)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:71)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.health.HintGCAfterBuild.execute(HintGCAfterBuild.java:41)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
    at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:246)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
    at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)

    BUILD FAILED

    Total time: 0.117 secs

    Agree(0)Disagree(0)Comment
    • Hi Brad,

      Please use github issues on the project to receive support.

      Thanks!

      Agree(1)Disagree(0)Comment