datanucleus-gradle-plugin

Unofficial Gradle Plugin for DataNucleus JPA / JDO Provider

View on GitHub

Travis branch Code Coverage License

GitHub watchers GitHub stars GitHub forks

Unofficial Gradle Plugin for DataNucleus JPA and JDO Provider.

This is a follow-up to a blog post talking about performing build-time enhancement with both DataNucleus and Gradle Ant Tasks.

Heavily inspired by the official DataNucleus Maven Plugin, this one defines a Gradle plugin for introducing DataNucleus specific tasks and capabilities into an end-user Gradle Project build.

Currently the only capability added is for bytecode enhancement of the user domain model, although other capabilities are planned.

Getting Started

This plugin is published to the Gradle Plugin Portal.

Grab via Gradle, by applying the plugin (and configure it) in your build.gradle:

plugins {
  id "org.rm3l.datanucleus-gradle-plugin" version "1.0.181124-SNAPSHOT"
}
buildscript {
  repositories {
    maven {
      url "https://plugins.gradle.org/m2/"
    }
  }
  dependencies {
    classpath "org.rm3l:datanucleus-gradle-plugin:1.0.181124-SNAPSHOT"
  }
}

apply plugin: "org.rm3l.datanucleus-gradle-plugin"

Note that this plugin automatically applies the Gradle JavaPlugin, as this is a prerequisite here.

Tasks

This plugin aims at supporting the same set of operations provided by the official DataNucleus Maven Plugin:

Applying this plugin automatically applies the Java Plugin (if not already the case) and adds the following tasks to your project:

Bytecode Enhancement

A noteworthy behavior of most JPA providers is to “enhance” the domain JPA classes. This technique, also known as weaving, allows to modify the resulting bytecode of your domain classes, in order to essentially add the following capabilities:

Some providers such as DataNucleus have chosen to require all domain classes to be enhanced before any use. This means that enhancement has to be done beforehand at build time, or at any time between compile time and packaging time. It is still possible to do it at run-time, but this requires using an appropriate ClassLoader to make sure the enhanced classes are effectively being used.

On the other hand, other JPA providers do not make enhancement a mandatory prerequisite, and can do it on-the-fly at run-time. They still allow to perform enhancement at build time, but this may not be the default behavior.

Performing bytecode enhancement at build time clearly has a performance benefit over the use of slow proxies or reflection that might be done at run-time.

This plugin supports build-time enhancement. The benefit is that the enhanced classes are what gets added to the final built Jar artifact.

To use the plugin in your Gradle project, after applying it as depicted above, you need to configure it, e.g.:

datanucleus {
  enhance {
    api 'JPA'
    persistenceUnitName 'myPersistenceUnit'
    //... other options are possible
  }

  //
  testEnhance { //'testEnhance' task has exactly the same options as the 'enhance' one above
    api 'JPA'
    persistenceUnitName 'myTestPersistenceUnit'
    //...
  }
}

All those tasks support the same set of enhancement options as in the official datanucleus-maven-plugin, i.e.:

Property Default value Description
persistenceUnitName - Name of the persistence-unit to enhance. Mandatory
log4jConfiguration - Config file location for Log4J (if using it)
jdkLogConfiguration - Config file location for JDK1.4 logging (if using it)
api JDO API to enhance to (JDO or JPA). Mandatory
verbose false Verbose output?
quiet false No output?
targetDirectory - Where the enhanced classes are written (default is to overwrite them)
fork true Whether to fork the enhancer process
generatePK true Generate a PK class (of name {MyClass}_PK) for cases where there are multiple PK fields yet no IdClass is defined.
generateConstructor true Generate a default constructor if not defined for the class being enhanced.
detachListener false Whether to enhance classes to make use of a detach listener for attempts to access an un-detached field.
ignoreMetaDataForMissingClasses false Whether to ignore when we have metadata specified for classes that are not found (e.g in orm.xml)
skip false Whether to skip execution

Note that by default, the classes task is automatically marked as depending on the enhance task, so that the latter is automatically run when you run a build.

Similarly, the testClasses task is automatically marked as depending on the testEnhance task.

This way, your resulting artifacts will contain the enhanced classes.

Credits

Developed by

License

The MIT License (MIT)

Copyright (c) 2018 Armel Soro

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.