Andromda Plugin for Gradle


(Chibuzo Ilechukwu) #1

My Maven project uses andromda plugin to generate code. I’m stuck migrating to Gradle, cant execute the andromda plugin. Is there an andromda plugin for gradle please?


(uklance) #2

Looks like there’s an ant task here

See the ant integration guide

eg:

configurations {
   andromda
}
dependencies {
   andromda 'org.andromda.ant:andromda-ant-task:3.4'
}
task andromda {
   doLast {
      ant.taskdef(
         name: 'andromda',
         classname: 'org.andromda.ant.task.AndroMDAGenTask',
         classpath: configurations.andromda.asPath)
      ant.andromda(configurationUri:"src/main/mda/andromda.xml")
   }
}

(Chibuzo Ilechukwu) #3

Thanks very much indeed, Lance! For quick replies. I pasted your example above into my build.gradle file. And ran the build, but nothing happened. I’m pretty sure I’m missing something fundamental. What could it be please? Please see my full build.gradle file below:

configurations {
   andromda
}
dependencies {
   andromda 'org.andromda.ant:andromda-ant-task:3.4'
}
task andromda {
   doLast {
      ant.taskdef(
         name: 'andromda',
         classname: 'org.andromda.ant.task.AndroMDAGenTask',
         classpath: configurations.andromda.asPath)
      ant.andromda(configurationUri:"src/main/mda/andromda.xml")
   }
}

apply plugin: "com.liferay.portal.tools.service.builder"
dependencies {
	compileOnly group: "biz.aQute.bnd", name: "biz.aQute.bndlib", version: "3.1.0"
	compileOnly group: "com.liferay", name: "com.liferay.osgi.util", version: "3.0.0"
        compileOnly group: "javax.portlet", name: "portlet-api", version: "2.0"
        compileOnly group: "javax.servlet", name: "javax.servlet-api", version: "3.0.1"
	compileOnly group: "com.liferay", name: "com.liferay.portal.spring.extender", version: "2.0.0"
	compileOnly group: "com.liferay.portal", name: "com.liferay.portal.kernel", version: "2.6.0"
        compileOnly group: "com.liferay", name: "com.liferay.portal.dao.orm.custom.sql", version: "1.0.3"
	compileOnly project(":medications-api")     
}

buildService {
	apiDir = "../medications-api/src/main/java"
}

group = "com.tpl.pmedics.medication"

(uklance) #4

I’m guessing you’ll need to wire the task into Gradle’s DAG

Eg:

someTask.dependsOn andromda

Possibly you could get some inspiration from here


(Chibuzo Ilechukwu) #5

Thanks again Lance and God bless you for your quick replies. What I would like to achieve is have this andromda task (which generates source code from a graphic model) run only when I invoke it, not necessarly in sequence before any other gradle. Pls isn’t it possible to have this as just a task on its own directly invocable by something like “grade build:andromda”? There are times I may want to build without running the code generation each time.

Again thank you sir for your assistance.


(uklance) #6

I’d advise against this, if you set the task input and output directories correctly then gradle will skip if the task is up to date (eg task ran before and inputs/outputs haven’t changed since)

All tasks can be run directly from the command line

Eg

gradle andromda

(Chibuzo Ilechukwu) #7

Ok, Lance. I understand your advice now. Thanks. I’ve modified by build.gradle file to look like this:

configurations {
   andromda
}
dependencies {
   andromda 'org.andromda.ant:andromda-ant-task:3.4'
}
task generateCode {
   doLast {
      ant.taskdef(
         name: 'andromda',
         classname: 'org.andromda.ant.task.AndroMDAGenTask',
         classpath: configurations.andromda.asPath)
      ant.andromda(configurationUri:"src/main/mda/andromda.xml")
   }
}
compileJava.dependsOn generateCode

apply plugin: "com.liferay.portal.tools.service.builder"
dependencies {
	compileOnly group: "biz.aQute.bnd", name: "biz.aQute.bndlib", version: "3.1.0"
	compileOnly group: "com.liferay", name: "com.liferay.osgi.util", version: "3.0.0"
        compileOnly group: "javax.portlet", name: "portlet-api", version: "2.0"
        compileOnly group: "javax.servlet", name: "javax.servlet-api", version: "3.0.1"
	compileOnly group: "com.liferay", name: "com.liferay.portal.spring.extender", version: "2.0.0"
	compileOnly group: "com.liferay.portal", name: "com.liferay.portal.kernel", version: "2.6.0"
        compileOnly group: "com.liferay", name: "com.liferay.portal.dao.orm.custom.sql", version: "1.0.3"
	compileOnly project(":medications-api")     
}

buildService {
	apiDir = "../medications-api/src/main/java"
}

group = "com.tpl.pmedics.medication"

Right now gradle is downloading the dependency jars. Will keep you posted on how this works. Thanks for making my day less difficult, Lance!!


(uklance) #8

For the up to date checking you’ll want something like

task generateCode {
   inputs.dir 'src/main/mda' 
   outputs.dir "$buildDir/andromda" 
   doLast { ... } 
} 

And maybe this so the generated sources are also compiled

sourceSets.main.java.srcDir "$buildDir/andromda"

(Chibuzo Ilechukwu) #9
FAILURE: Build failed with an exception.

* Where:
Build file 'C:\Software\Devel\Src\Web\Component\MedicationMgmt\medications\medications-service\build.gradle' line: 13

* What went wrong:
Execution failed for task ':medications-service:generateCode'.
> java.net.MalformedURLException: no protocol: src/main/mda/andromda.xml

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

I placed my andromda.xml file (same one working in my maven build) under the src/main/mda/ directory. I’m using Windows 10


(uklance) #10

Perhaps

ant.andromda(configurationUri: file("src/main/mda/andromda.xml").absolutePath)

(Chibuzo Ilechukwu) #11

Funny how little things like file URLs can become problematic. I tried this:
ant.andromda(configurationUri: file("src/main/mda/andromda.xml").absolutePath)

It still gives me the exception

FAILURE: Build failed with an exception.

* Where:
Build file 'C:\Software\Devel\Src\Web\Component\MedicationMgmt\medications\medications-service\build.gradle' line: 13

* What went wrong:
Execution failed for task ':medications-service:generateCode'.
> java.net.MalformedURLException: unknown protocol: c

Here’s the full path to the file I want to access
C:\Software\Devel\Src\Web\Component\MedicationMgmt\medications\medications-service\src\main\mda\andromda.xml

Isnt there a gradle variable like $rootFolder so I can do something like configurationUri: $rootFolder/src/main/mda/andromda.xml?


(uklance) #12
ant.andromda(configurationUri: "file:${file('src/main/mda/andromda.xml')}") 

(Chibuzo Ilechukwu) #13

Great work, Lance. Now it does see my andromda.xml file. But it cant reach the the uml file (understandably so). Here’s a copy of my andromda.xml file

<andromda>
<properties>
    <property name="modelValidation">false</property>
    <property name="cartridgeFilter">${andromda.cartridge.filter}</property>
</properties>
<repositories>
    <repository name="netBeansMDR">
        <models>
            <model>
                <uri>${andromda.model.uri}</uri>
                <moduleSearchLocations>
                    <!--location>${maven.repo.local}/andromda/xml.zips</location-->
		<location>${maven.repo.local}/andromda/xmi</location>
                    <!--location patterns="**/*.xml.zip">${settings.localRepository}/org/andromda/profiles/uml14</location-->
		<location patterns="**/*.xml.zip, **/*.xmi">${settings.localRepository}/org/andromda/profiles/uml2</location>
                </moduleSearchLocations>
            </model>
        </models>            
    </repository>
</repositories>
<namespaces>
    <namespace name="default">
        <properties>
            <property name="languageMappingsUri">Java</property>
            <property name="wrapperMappingsUri">JavaWrapper</property>
            <property name="sqlMappingsUri">${sql.mappings}</property>
            <property name="jdbcMappingsUri">JDBC</property>
            <property name="maxSqlNameLength">30</property>
            <property name="foreignKeySuffix">_FK</property>
            <property name="ejbJndiNamePrefix">${application.id}</property>
            <!-- used in both hibernate and spring cartridges -->
            <property name="hibernateVersion">3</property>
        </properties>
    </namespace>
    <namespace name="liferay">
        <properties>
            <property name="service-xml">${service.xml.dir}</property>
        </properties>
    </namespace>
    <!--namespace name="hibernate">
        <properties>
            <property name="hibernateHbm2DDLAuto">update</property>
            <property name="hibernateEnableCache">false</property>
            <property name="hibernateEnableAssociationsCache">false</property>
            <property name="hibernateTypeMappingsUri">Hibernate</property>
            <property name="hibernateInheritanceStrategy">${hibernate.inheritance.strategy}</property>
            <property name="defaultHibernateGeneratorClass">${hibernate.generatorClass}</property>
            <property name="hibernateDefaultCascade">none</property>
            <property name="entities">${common.generated.dir}</property>
            <property name="entity-impls">${core.manual.dir}</property>
            <property name="entity-mappings">${common.generated.dir}</property>
            <property name="user-types">${common.generated.dir}</property>
            <property name="customTypesPackage">${application.package}</property>
            <property name="compositionDefinesEagerLoading">true</property>
            <property name="cache">${hibernate.configuration.dir}</property>
            <property name="configuration">${hibernate.configuration.dir}</property>
        </properties>
    </namespace-->
    <!--namespace name="java">
        <properties>
            <property name="enumerations">${common.generated.dir}</property>
            <property name="exceptions">${common.generated.dir}</property>
            <property name="value-objects">${common.generated.dir}</property>
        </properties>
    </namespace-->
</namespaces>

How do I specify these properties referenced in this file, on gradle. For instance it cant see
${andromda.model.uri}
because it was defined in a properties file in my maven build.
Pls is there any such properties file for Gradle too?


(uklance) #14

See the ant properties section in the Gradle docs


(Chibuzo Ilechukwu) #15

Thanks again, Lance. I’ve read your reference and made necessary modifications. Now my andromda.xml looks like this

<andromda>
<properties>
    <property name="modelValidation">false</property>
    <property name="cartridgeFilter">$ant.properties['andromdaCartridgeFilter']</property>
</properties>
<repositories>
    <repository name="netBeansMDR">
        <models>
            <model>
                <uri>$ant.properties['andromdaModelUri']</uri>
                <moduleSearchLocations>
                    <!--location>${maven.repo.local}/andromda/xml.zips</location-->
		<location>${maven.repo.local}/andromda/xmi</location>
                    <!--location patterns="**/*.xml.zip">${settings.localRepository}/org/andromda/profiles/uml14</location-->
		<location patterns="**/*.xml.zip, **/*.xmi">${settings.localRepository}/org/andromda/profiles/uml2</location>
                </moduleSearchLocations>
            </model>
        </models>            
    </repository>
</repositories>
<namespaces>
    <namespace name="default">
        <properties>
            <property name="languageMappingsUri">Java</property>
            <property name="wrapperMappingsUri">JavaWrapper</property>
            <property name="sqlMappingsUri">${sql.mappings}</property>
            <property name="jdbcMappingsUri">JDBC</property>
            <property name="maxSqlNameLength">30</property>
            <property name="foreignKeySuffix">_FK</property>
            <property name="ejbJndiNamePrefix">${application.id}</property>
            <!-- used in both hibernate and spring cartridges -->
            <property name="hibernateVersion">3</property>
        </properties>
    </namespace>
    <namespace name="liferay">
        <properties>
            <property name="service-xml">$ant.properties['serviceXmlDir']</property>
        </properties>
    </namespace>
    <!--namespace name="hibernate">
        <properties>
            <property name="hibernateHbm2DDLAuto">update</property>
            <property name="hibernateEnableCache">false</property>
            <property name="hibernateEnableAssociationsCache">false</property>
            <property name="hibernateTypeMappingsUri">Hibernate</property>
            <property name="hibernateInheritanceStrategy">${hibernate.inheritance.strategy}</property>
            <property name="defaultHibernateGeneratorClass">${hibernate.generatorClass}</property>
            <property name="hibernateDefaultCascade">none</property>
            <property name="entities">${common.generated.dir}</property>
            <property name="entity-impls">${core.manual.dir}</property>
            <property name="entity-mappings">${common.generated.dir}</property>
            <property name="user-types">${common.generated.dir}</property>
            <property name="customTypesPackage">${application.package}</property>
            <property name="compositionDefinesEagerLoading">true</property>
            <property name="cache">${hibernate.configuration.dir}</property>
            <property name="configuration">${hibernate.configuration.dir}</property>
        </properties>
    </namespace-->
    <!--namespace name="java">
        <properties>
            <property name="enumerations">${common.generated.dir}</property>
            <property name="exceptions">${common.generated.dir}</property>
            <property name="value-objects">${common.generated.dir}</property>
        </properties>
    </namespace-->
</namespaces>

and I’ve created a build.xml file inside same directory where build.gradle exists. Here are the contents

<?xml version="1.0" encoding="UTF-8"?>

<property name="andromdaModelUri" value="jar:file:C:/Software/Devel/Src/Web/Component/MedicationMgmt/medications/medications-service/src/main/mda/medication-mgmt-component-model.xmi.zip!/medication-mgmt-component-model.xmi"/>
<property name="andromdaCartridgeFilter" value=""/>
<property name="serviceXmlDir" value="C:/Software/Devel/Src/Web/Component/MedicationMgmt/medications/medications-service"/>

But now build fails with this error?
FAILURE: Build failed with an exception.

* Where:
Build file 'C:\Software\Devel\Src\Web\Component\MedicationMgmt\medications\build.gradle' line: 14

* What went wrong:
A problem occurred evaluating root project 'medications'.
> Failed to apply plugin [class 'com.liferay.gradle.plugins.LiferayAntPlugin']
   > Could not import Ant build file 'C:\Software\Devel\Src\Web\Component\MedicationMgmt\medications\medications-service\build.xml'.

(uklance) #16

Huh? All you need to do is configure the ant properties in Gradle. Don’t change andromda.xml, and don’t create a build.xml either. You can run any ant task in build.gradle including <property ... />

Eg:

task generateCode {
   inputs.dir 'src/main/mda' 
   outputs.dir "$buildDir/generated" 
   doLast {
      ant.property(name: 'andromda.model.uri', value: 'xxx')
      ant.property(name: 'andromda.outputDir', value: file("$buildDir/generated").absolutePath)
      ant.property(location: file('src/main/andromda/andromda.properties').absolutePath)
      ant.taskdef(...)
      ant.andromda(...) 
   } 
} 
sourceSets.main.java.srcDir "$buildDir/generated"
compileJava.dependsOn generateCode

(Chibuzo Ilechukwu) #17

Greetings Friend Lance.
Been tinkering things up quite a bit. Didn’t want to bother you with every single bit of my problems, and I’ve made some good success.

First, ant couldn’t see my netBeansMDR andromda repository (which I referred to in my andromda.xml). But after adding the 2 lines:

andromda 'org.andromda.repositories:andromda-repository-mdr- 
uml14:3.4
andromda 'org.andromda.repositories:andromda-repository-emf- 
uml22:3.4'

to my dependencies, now it reports discovering my repository. Below is the info from andromda engine log

2018-06-13 09:05:26,101 INFO  [AndroMDA] - discovering namespaces -
2018-06-13 09:05:26,245 INFO  [AndroMDA] found namespace --> 'emf-uml22'
2018-06-13 09:05:26,245 INFO  [AndroMDA]   +  registering component 'metafacades'
2018-06-13 09:05:26,429 INFO  [AndroMDA]   +  registering component 'profile'
2018-06-13 09:05:26,437 INFO  [AndroMDA]   +  registering component 'repository'
2018-06-13 09:05:26,461 INFO  [AndroMDA] found namespace --> 'hibernate'
2018-06-13 09:05:26,461 INFO  [AndroMDA]   +  registering component 'cartridge'
2018-06-13 09:05:26,557 INFO  [AndroMDA]   +  registering component 'metafacades'
2018-06-13 09:05:26,591 INFO  [AndroMDA]   +  registering component 'profile'
2018-06-13 09:05:26,595 INFO  [AndroMDA] found namespace --> 'java'
2018-06-13 09:05:26,595 INFO  [AndroMDA]   +  registering component 'cartridge'
2018-06-13 09:05:26,603 INFO  [AndroMDA]   +  registering component 'profile'
2018-06-13 09:05:26,603 INFO  [AndroMDA]   +  registering component 'metafacades'
2018-06-13 09:05:26,611 INFO  [AndroMDA] found namespace --> 'liferay'
2018-06-13 09:05:26,611 INFO  [AndroMDA]   +  registering component 'cartridge'
2018-06-13 09:05:26,619 INFO  [AndroMDA]   +  registering component 'metafacades'
2018-06-13 09:05:26,643 INFO  [AndroMDA]   +  registering component 'profile'
2018-06-13 09:05:26,643 INFO  [AndroMDA] found namespace --> 'netBeansMDR'
2018-06-13 09:05:26,643 INFO  [AndroMDA]   +  registering component 'repository'
2018-06-13 09:05:26,771 INFO  [AndroMDA] found namespace --> 'validation'
2018-06-13 09:05:26,771 INFO  [AndroMDA]   +  registering component 'translation-library'

However, now I’m getting a new error
* What went wrong:
Execution failed for task ‘:medications-service:generateCode’.

java.lang.reflect.InvocationTargetException

  • Try:
    Run with --stacktrace option to get the stack trace. Run with --debug option to get more log output.

BUILD FAILED

Not sure what to do about this anymore. It doesn’t say anything more apart from what’s in the log. A source I read online talks about possible classpath issues (invoking a class present on 2 different instances or something).

Pls is there anywhere I’m supposed to include something about classpath in my andromda ant invocation task

task generateCode {
}.

Below is my present build.gradle file

configurations {
   andromda
}
dependencies {
   andromda 'org.andromda.ant:andromda-ant-task:3.4'
   andromda 'org.andromda.profiles.uml2:andromda-profile:3.4'
   andromda 'org.andromda.repositories:andromda-repository-mdr:3.4'
   andromda 'org.andromda.repositories:andromda-repository-mdr-uml14:3.4'
   andromda 'org.andromda.repositories:andromda-repository-emf-uml22:3.4'
   andromda 'org.andromda.cartridges:andromda-cartridges:3.4'
   andromda 'org.andromda.cartridges:andromda-java-cartridge:3.4'
   andromda 'org.andromda.cartridges:andromda-ejb-cartridge:3.4'
   andromda 'org.andromda.cartridges:andromda-hibernate-cartridge:3.4'
   andromda 'org.andromda.templateengines:andromda-templateengine-velocity:3.4'
   andromda 'org.andromda.thirdparty.netbeans.mdr:jmiutils:20050711'
}
task generateCode {
   doLast {
      ant.property(name: 'andromda.model.uri', value: 'C:/Software/Devel/Src/Web/Component/MedicationMgmt/medications/medications-service/src/main/mda/medication-mgmt-component-model.xmi')
      ant.property(name: 'andromda.cartridge.filter', value: 'liferay')
      ant.property(name: 'service.xml.dir', value: 'C:/Software/Devel/Src/Web/Component/MedicationMgmt/medications')
      ant.property(name: 'settings.localRepository', value: 'C:/Software/Devel/Lib/Maven304/repository')
      ant.taskdef(
         name: 'andromda',
         classname: 'org.andromda.ant.task.AndroMDAGenTask',
         classpath: configurations.andromda.asPath)
      ant.andromda(configurationUri: "file:${file('src/main/mda/andromda.xml')}")
   }
}
compileJava.dependsOn generateCode

apply plugin: "com.liferay.portal.tools.service.builder"
dependencies {
	compileOnly group: "biz.aQute.bnd", name: "biz.aQute.bndlib", version: "3.1.0"
	compileOnly group: "com.liferay", name: "com.liferay.osgi.util", version: "3.0.0"
        compileOnly group: "javax.portlet", name: "portlet-api", version: "2.0"
        compileOnly group: "javax.servlet", name: "javax.servlet-api", version: "3.0.1"
	compileOnly group: "com.liferay", name: "com.liferay.portal.spring.extender", version: "2.0.0"
	compileOnly group: "com.liferay.portal", name: "com.liferay.portal.kernel", version: "2.6.0"
        compileOnly group: "com.liferay", name: "com.liferay.portal.dao.orm.custom.sql", version: "1.0.3"
	compileOnly project(":medications-api")     
}

buildService {
	apiDir = "../medications-api/src/main/java"
}

group = "com.tpl.pmedics.medication"

and here is my andromda.xml file

<andromda>
<properties>
    <property name="modelValidation">false</property>
    <property name="cartridgeFilter">${andromda.cartridge.filter}</property>
</properties>
<repositories>
    <repository name="netBeansMDR">
        <models>
            <model>
                <uri>${andromda.model.uri}</uri>

            </model>
        </models>            
    </repository>
</repositories>
<namespaces>
    <namespace name="default">
        <properties>
            <property name="languageMappingsUri">Java</property>
            <property name="wrapperMappingsUri">JavaWrapper</property>
            <property name="sqlMappingsUri">${sql.mappings}</property>
            <property name="jdbcMappingsUri">JDBC</property>
            <property name="maxSqlNameLength">30</property>
            <property name="foreignKeySuffix">_FK</property>
            <property name="ejbJndiNamePrefix">${application.id}</property>
            <!-- used in both hibernate and spring cartridges -->
            <property name="hibernateVersion">3</property>
        </properties>
    </namespace>
    <namespace name="liferay">
        <properties>
            <property name="service-xml">${service.xml.dir}</property>
        </properties>
    </namespace>
    <!--namespace name="hibernate">
        <properties>
            <property name="hibernateHbm2DDLAuto">update</property>
            <property name="hibernateEnableCache">false</property>
            <property name="hibernateEnableAssociationsCache">false</property>
            <property name="hibernateTypeMappingsUri">Hibernate</property>
            <property name="hibernateInheritanceStrategy">${hibernate.inheritance.strategy}</property>
            <property name="defaultHibernateGeneratorClass">${hibernate.generatorClass}</property>
            <property name="hibernateDefaultCascade">none</property>
            <property name="entities">${common.generated.dir}</property>
            <property name="entity-impls">${core.manual.dir}</property>
            <property name="entity-mappings">${common.generated.dir}</property>
            <property name="user-types">${common.generated.dir}</property>
            <property name="customTypesPackage">${application.package}</property>
            <property name="compositionDefinesEagerLoading">true</property>
            <property name="cache">${hibernate.configuration.dir}</property>
            <property name="configuration">${hibernate.configuration.dir}</property>
        </properties>
    </namespace-->
    <!--namespace name="java">
        <properties>
            <property name="enumerations">${common.generated.dir}</property>
            <property name="exceptions">${common.generated.dir}</property>
            <property name="value-objects">${common.generated.dir}</property>
        </properties>
    </namespace-->
</namespaces>

.

Thanks Lance!!


(uklance) #18

Disclaimer: I’d never heard of androidmda before this thread

As the error message states, try adding --stacktrace to gradle command line to get more details

is there anywhere I’m supposed to include something about classpath in my andromda ant invocation

Yes, in the ant.taskdef you are passing the classpath from gradle to ant

      ant.taskdef(
         name: 'andromda',
         classname: 'org.andromda.ant.task.AndroMDAGenTask',
         classpath: configurations.andromda.asPath)

ant.property(name: ‘andromda.model.uri’, value: ‘C:/Software/Devel/Src/Web/Component/MedicationMgmt/medications/medications-service/src/main/mda/medication-mgmt-component-model.xmi’)

Don’t hard code absolute paths like this, do this instead

ant.property(name: 'andromda.model.uri', value: file('src/main/mda/medication-mgmt-component-model.xmi').absolutePath)