Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I run DataNucleus Enhancer from Gradle?

Is there a gradle plugin for running DataNucleus Enhancer? As I can see from documentation you can run it only from Maven or Ant: http://www.datanucleus.org/products/datanucleus/jpa/enhancer.html

like image 604
Adrian Ber Avatar asked Mar 26 '15 13:03

Adrian Ber


2 Answers

I searched and found no plugin for running the DataNucleus Enhancer from Gradle. But there is a way of doing this by using the DataNucleus Enhancer Ant task.

I added the following in my build.gradle.

task datanucleusEnhance {
    description "Enhance JPA model classes using DataNucleus Enhancer"
    dependsOn compileJava

    doLast {    
        // define the entity classes
        def entityFiles = fileTree(sourceSets.main.output.classesDir).matching {
            include 'com/mycom/*.class', 'org/myorg/*.class'
        }

        println "Enhancing with DataNucleus the following files"
        entityFiles.getFiles().each {
            println it
        }

        // define Ant task for DataNucleus Enhancer
        ant.taskdef(
            name : 'datanucleusenhancer',
            classpath : sourceSets.main.runtimeClasspath.asPath,
            classname : 'org.datanucleus.enhancer.EnhancerTask'
            // the below is for DataNucleus Enhancer 3.1.1
            //classname : 'org.datanucleus.enhancer.tools.EnhancerTask'
        )

        // run the DataNucleus Enhancer as an Ant task
        ant.datanucleusenhancer(
            classpath: sourceSets.main.runtimeClasspath.asPath,
            verbose: true,
            api: "JPA") {
            entityFiles.addToAntBuilder(ant, 'fileset', FileCollection.AntType.FileSet)
        }
    }
}

classes.dependsOn(datanucleusEnhance)

In the entityFiles is where you configure your JPA entity annotated classes.

Unfortunately you cannot see the enhancer output, as this task is using Ant logging. Unless you're running gradle with -i or -d option.

Using: Java 8, org.eclipse.persistence:javax.persistence:2.1.0, org.datanucleus:datanucleus-accessplatform-jpa-rdbms:4.1.1.

like image 153
Adrian Ber Avatar answered Oct 23 '22 02:10

Adrian Ber


Here is slightly different approach. First of all I've created EntityEnhancer class in my project. This class calls DataNucleus enhancer via its main method. Then I called this class from Gradle's JavaExec task.

This prints out all enhancer's log messages on Gradle console and also can be called from IDE.

EntityEnhancer class uses Spring Boot 1.3.5 library.

public class EntityEnhancer {

    private static final ClassPathScanningCandidateComponentProvider ENTITY_SCANNER;
    static {
        ENTITY_SCANNER = new ClassPathScanningCandidateComponentProvider(false);
        ENTITY_SCANNER.addIncludeFilter(new AnnotationTypeFilter(Entity.class));
    }

    public static void main(String[] args) throws IOException {
        Validate.isTrue(args.length == 1, "Expected single argument <package_to_scan>!");
        String pathToScan = args[0];
        String[] classesToEnhance = findEntityClasses(pathToScan);
        Validate.isTrue(classesToEnhance.length > 0, "No classes to enhance has been found!");

        DataNucleusEnhancer enhancer = new DataNucleusEnhancer("JPA", null);
        enhancer.addClasses(classesToEnhance);
        enhancer.enhance();
    }

    private static String[] findEntityClasses(String packageToScan) throws IOException {
        Set<BeanDefinition> entityBeanDefinitions = ENTITY_SCANNER.findCandidateComponents(packageToScan);
        List<String> entityClasses = entityBeanDefinitions.stream().map(BeanDefinition::getBeanClassName).collect(Collectors.toList());
       return entityClasses.toArray(new String[]{});
    }
}

Task definition for your build.gradle file. This actually puts your just-compiled classes on the classpath and runs EntityEnhancer class.

// Call this task from your IDE after project compilation.
task enhanceJpaEntities(type: JavaExec) {
    classpath = sourceSets.main.runtimeClasspath
    main = 'com.your.project.package.EntityEnhancer'
    args 'com.your.entities.package'
}

classes.doLast {
    enhanceJpaEntities.execute()
}
like image 1
Václav Kužel Avatar answered Oct 23 '22 03:10

Václav Kužel