Skip to content
rjrudin edited this page Aug 7, 2017 · 9 revisions

If you've used Roxy on a number of projects (as the author of ml-gradle has), this should be a useful FAQ for understanding how certain things work in ml-gradle as compared to Roxy.

First, read through the Getting Started guide to get an overview of Gradle and how ml-gradle works. Then, check out the items below.

Next, please see the Wiki page on migrating a Roxy project to ml-gradle. That page goes into more detail about how Roxy features are supported by ml-gradle.

What are Gradle and ml-gradle?

The first thing to understand about ml-gradle is that it's a Gradle plugin. Gradle is a build tool, like Roxy. Thus, there are certain things that ml-gradle isn't going to address because they're already covered by other Gradle plugins - support for environment properties being a prime example.

Why Gradle?

Gradle is essentially an automation tool. While it's commonly used for JVM-based projects, it can be used for any kind of automation. It also reflects the natural evolution based on Ant and Maven, but without the rigidity of those tools and with a much richer language - Groovy - for extending Gradle to do anything. You may find Groovy and Ruby to be somewhat similar too - though you won't typically be writing a lot of Groovy code when using ml-gradle. Most of your work typically is in adjusting properties and creating JSON/XML files to submit to the Management API.

What are the most common ml-gradle tasks to run?

On a Roxy project, you probably run "ml local bootstrap" and "ml local deploy modules" more than anything else. With ml-gradle, you'll run the following tasks a lot:

  • mlDeploy = does a full deployment; it's like bootstrap + deploy modules
  • mlWatch = watches for module changes/additions and loads them automatically
  • mlReloadModules = clears the modules database and loads all the modules back in; useful after syncing with a remote branch to ensure there are no leftover modules
  • mlDeployDatabases = useful for when you change e.g. a database range index, and you don't want to wait for a full mlDeploy

Running "gradle tasks" will reveal dozens of different tasks that ml-gradle adds to Gradle. Every resource in MarkLogic has at least one and usually more tasks associated with it. This is due to the Management API making it easy to support e.g. deploying only roles, or only privileges, or only CPF resources.

I'm used to the property files under the deploy directory. What's the equivalent of those?

Gradle by default reads properties in from gradle.properties. The aforementioned properties plugin is most commonly used for supporting multiple environments. And Configuring-ml-gradle details how ml-gradle is configured via gradle.properties and via scripting in build.gradle as well.

I'm used to ml-config.xml. What's the equivalent of that?

The way ml-gradle handles defining resources (databases, app servers, etc) to deploy is significantly different from how Roxy does it, with the significant difference being that there are many small XML or JSON files in directories as opposed to one large XML file. There are pros and cons to both approaches. But if you study the Management API a bit, you'll notice that the docs for the Management API suggest the many-small-files approach for the following reasons:

  1. The Management API table of contents is broken up into many resource types - this implies a directory structure
  2. Each Management API endpoint accepts an XML or JSON payload - this suggests a file per payload, particularly so that the user can choose the best fit (JSON is more concise, but XML is nice when inline comments are helpful)

Having a lot of small files is often helpful from a version control perspective too, though that's a more subjective topic. And being able to quickly scan a directory structure to understand an application's resource profile is also helpful - but again, that's a bit subjective.

It certainly would be possible to support one large XML or JSON file for ml-gradle. It would restrict the user to only using JSON or XML, which may not be desirable. And it would require a new schema in addition to the schemas used by the Management API. And it would need to be kept in sync as support for new resources are added. For those reasons, the priority of supporting this isn't high, but it's doable if anyone wants to pursue it.

Where do my modules go?

See How modules are loaded for information on where different modules go under src/main/ml-modules, which is the default path for all modules.

Will deploying and undeploying be as fast as Roxy?

No. This is a matter of using the Management API vs using the Admin API over XCC. The Management API is great at making it easy to automate any kind of configuration within MarkLogic, but it's currently very granular, and every operation is a separate HTTP request and transaction. Roxy uses the Admin API, which is for a typical MarkLogic user is a bit more complex to use than the Management API, but it can get a lot more done in one request to MarkLogic.

ml-gradle may soon have improvements for parallelizing certain requests to the Management API, but the real solution here is to file RFEs with MarkLogic for providing higher level operations that can get a lot done in one request - e.g. creating a database with N forests.

What about my data directory? What do I do now?

One of the benefits of using Gradle is that the jars for tools like mlcp and corb can be downloaded via Gradle's dependency management feature. So ml-gradle doesn't include any of these libraries by default, which means you're not bound to a specific version. Instead, you include them like you'd include any other jar.

And because tools like mlcp and corb are Java programs, it's easy to execute them via Gradle's JavaExec task. Which means you can create as many custom Gradle tasks as you want that use mlcp, or corb, or recordloader, or xqsync, or Spring Batch, or anything else you want.

That means there's not default support for a "data" directory. There is a ticket for this, but the demand hasn't really been there for it because it's usually easier/better to just setup your own MLCP Gradle task that does exactly what you want to do with MLCP.

To see examples of MLCP and corb in action, check out the mlcp sample project and the corb sample project.

What do I do with my Roxy tests?

Testing is a good example of something that's within the scope of Gradle, but not ml-gradle. There's an issue for integrating Roxy test results into the Gradle "test" task that's provided by Gradle's Java plugin - shouldn't be difficult to do, as Roxy can output test results in a JUnit-compliant format.

What's the equivalent of the Roxy capture command?

See Exporting resources for something similar to "capture". And see the guide for Migrating a Roxy project to ml gradle.

Clone this wiki locally