How perform OpenJPA Enhancement when using Gradle? - ant

I've tried this gradle plugin https://github.com/schmutterer/gradle-openjpa but it complains that it cannot find certain libraries and doesn't support providedCompile which makes this unusable for me anyway.
I've also tried calling ANT tasks, my latest attempt below is throwing:
Caused by: C:\Work_Java\workspace\PaxHoldRelease\jpa_enhance.xml:5: taskdef class org.apache.openjpa.ant.PCEnhancerTask cannot be found
build.gralde
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'ear'
// Java compilier compliance level
sourceCompatibility = 1.7
targetCompatibility = 1.7
repositories {
mavenLocal()
mavenCentral()
}
ant.importBuild 'jpa_enhance.xml'
war.dependsOn enhance
dependencies {
// Ensure ear plugin gets war file
deploy files(war)
providedCompile 'javax.servlet:javax.servlet-api:3.0.1'
compile 'javax.websocket:javax.websocket-api:1.1'
compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.16'
compile 'com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:2.5.1'
compile 'org.glassfish:javax.json:1.0.4'
providedCompile 'org.apache.openjpa:openjpa:2.2.2'
providedCompile 'com.sybase:jconn3:6.05'
providedCompile files('libs/sqljdbc4-3.0.jar')
}
jpa_enhance.xml
This is the latest version in a long list of attempts and probably complete rubbish as I just ripped everything out in a fit of desperation :-(
<project>
<target name="enhance">
<taskdef name="openjpac" classname="org.apache.openjpa.ant.PCEnhancerTask"/>
<!-- invoke enhancer on all .java files below the model directory -->
<openjpac>
</openjpac>
<echo message="Enhancing complete!"/>
</target>
</project>

Try this Andrew - I loosely based this gradle on the nice Enhancer script provided on S.O. by another member (for the DataNucleus enhancer).
Note that you will need to modify the entity-files (include/exclude) to point to your specific 'to be/to not be' enhanced Java source files. Further, this approach assumes that classpath derives from your parent build.gradle.
task openJPAEnhance {
description "Enhance JPA model classes using OpenJPA Enhancer"
dependsOn compileJava
doLast {
// define the entity classes
def entityFiles = fileTree(sourceSets.main.output.classesDir).matching {
include 'org/foo/mypkg/entity/*.class'
exclude 'org/foo/mypkg/entity/DoNotEnhance.class'
}
println "Enhancing with OpenJPA, the following files..."
entityFiles.getFiles().each {
println it
}
// define Ant task for Enhancer
ant.taskdef(
name : 'openjpac',
classpath : sourceSets.main.runtimeClasspath.asPath,
classname : 'org.apache.openjpa.ant.PCEnhancerTask'
)
// Run the OpenJPA Enhancer as an Ant task
// - see OpenJPA 'PCEnhancerTask' for supported arguments
// - this invocation of the enhancer adds support for a default-ctor
// - as well as ensuring JPA property use is valid.
ant.openjpac(
classpath: sourceSets.main.runtimeClasspath.asPath,
addDefaultConstructor: true,
enforcePropertyRestrictions: true) {
entityFiles.addToAntBuilder(ant, 'fileset', FileCollection.AntType.FileSet)
}
}
}
I hope this helps, and the individual who wrote that first gradle script did not mind that we re-purposed it (from DataNucleus) to OpenJPA.

Related

Gradle giving ClassNotFoundException while building Grails project

I am trying to use the gradle-grails-plugin to build an existing (small) Grails project. Should this work? What is the relationship between the dependencies in build.gradle and the ones specified in buildConfig.groovy?
In any event, I have two projects, so the topmost build.gradle file is in the parent directory and looks like:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "org.grails:grails-gradle-plugin:2.2.0.RC1"
}
}
task wrapper(type: Wrapper) {
gradleVersion = '2.3'
}
and then the build.gradle in the Grails project looks like:
apply plugin: "grails"
repositories {
grails.central() //creates a maven repo for the Grails Central repository (Core libraries and plugins)
}
grails {
grailsVersion = '2.4.4'
groovyVersion = '2.3.9'
springLoadedVersion '1.2.0.RELEASE'
}
dependencies {
bootstrap "org.grails.plugins:tomcat:7.0.55.3"
compile 'org.grails.plugins:asset-pipeline:3.0.1'
compile 'org.grails.plugins:scaffolding:2.1.2'
compile 'org.grails.plugins:cache:1.1.8'
runtime 'org.grails.plugins:hibernate4:4.3.1.1'
runtime 'org.grails.plugins:database-migration:1.3.8'
runtime 'org.grails.plugins:jquery:1.11.0'
}
However, when I run ./gradlew war, I get back:
Caused by: java.long.ClassNotFoundException: grails.artefact.Service
Can anyone shed some light on this? There are practically no references to that via Google, it seems to be a Grails 3.x class? Also, I am using Java 1.7.
Class grails.artefact.Service is indeed accessible from v3.0 of grails framework - as can be seen here.
With the following statement grailsVersion = '2.4.4' v2.4.4 is specified to be used and it all looks ok. What spoils the build is the following dependencies entry:
compile 'org.grails.plugins:asset-pipeline:3.0.1'
In this package there is a class asset/pipeline/grails/AssetProcessorService that imports the mentioned grails.artefact.Service which isn't loaded at runtime (probably because of v2.4.4 used).
Unfortunately I can't suggest any solution apart from the trivial like excluding this dependency. I am not a grails developer nor have I set the environment up.
Hopes that helps somehow.

Gradle project / task dependency & JavaScript lib in war

We have just started using Gradle and do have a few (noob) questions - hopefully someone can shed some light on those issues :)
We're using Angular and Grails to build our web-app. We want to be as modular as possible and hence put all the Angular-related artifacts (mainly *.js and *.html files) in a separate project in our Gradle multiproject build.
Our project structure is as follows:
- root
-- build.gradle
-- settings.gradle
|-- web-grails (grails project)
|----- build.gradle
|-- web-js-html (angular / js / html sources)
|----- build.gradle
As a start, we simply want to package web-js-html project accordingly. What we've come up so far (other suggestions very welcome) is to apply a webjars structure to it, i.e. have a .jar file with the required resources under /META-INF/resources. Online, we found the following config that seems to work just fine:
// file :web-js-grails/build.gradle
apply plugin: 'java'
ext {
webjarconfig = [
staticHTMLFilesDir : "${projectDir}/src/main/webfrontend",
baseDir: "META-INF/resources/",
subDir : "webjars/" + deployed_app_name
]
}
configurations {
webjar
}
task webjar(type: Jar, dependsOn: 'jar') {
from(fileTree(webjarconfig.staticHTMLFilesDir)) {
into webjarconfig.baseDir + webjarconfig.subDir
}
outputs.file archivePath
}
artifacts {
webjar(webjar.archivePath) {
type 'jar'
builtBy webjar
}
}
By invoking 'gradle webjar', the jar gets created with the files in the correct place.
Question 1:
What I would have expected is that this jar also gets properly created if I invoke 'gradle build'. As far as I understand, 'gradle build' is a task defined by the java plugin which, at some point, invokes the 'jar' task. Once that 'jar' task is done, I would expect the webjar task to be invoked. But it's not, so clearly I'm missing something. Does it follow that webjar only ever gets executed if explicitly invoked (either from command-line or from within the build.gradle file)?
Now, we would like the webjar to be included in the web-grails war-file. The config of :web-grails/build.gradle is as follows:
apply plugin: "grails"
repositories {
mavenLocal()
maven { url artifactory_url }
}
buildscript {
repositories {
mavenLocal()
maven { url artifactory_url }
}
dependencies {
classpath 'org.grails:grails-gradle-plugin:2.0.1-SNB1'
}
}
grails {
grailsVersion = '2.3.8'
groovyVersion = '2.3.0'
}
dependencies {
bootstrap 'org.grails.plugins:tomcat:7.0.50'
compile project(':web-js-html')
}
After try-and-error and quite a bit of reading, I arrived at this (possibly wrong) conclusion: when I invoke 'gradle build' on :web-grails, then (I assume) :build will also be invoked on the referenced :web-js-html project. I say this because the jar gets re-created in the build/lib folder, but obviously not using the webjar-task. Hence, the resulting jar only contains the MANIFEST.MF only.
Question 2:
Do I use Gradle correctly in that case and am I only overseeing a little thing or is this whole approach questionable? How can I get the :web-js-html jar into the war properly?
Thank you for your help in advance!
Your part where you define the new artifact doesn't make any sense for me. Change
artifacts {
webjar(webjar.archivePath) {
type 'jar'
builtBy webjar
}
}
to
artifacts {
webjar webjar
}
Maybe you should rename either your configuration or your task. However the first webjar is your configuration and the second one your task which creates the new jar.
Note that this will create a new artifact, so you have to give it a different name with
task webjar(type: Jar, dependsOn: 'jar') {
baseName = 'newJar'
from(fileTree(webjarconfig.staticHTMLFilesDir)) {
into webjarconfig.baseDir + webjarconfig.subDir
}
outputs.file archivePath
}
But I think you don't want to create a second jar, but change the original one. In that case your don't have to write a new task, but configure the default jar task like this:
jar {
from(fileTree(webjarconfig.staticHTMLFilesDir)) {
into webjarconfig.baseDir + webjarconfig.subDir
}
outputs.file archivePath
}

ANT Gradle - Axis WSDL 2 Java : No such property: axis for class: org.gradle.api.internal

I have the following code snap in ANT build.xml which is converting WSDL to Java. It works and uses axis-ant.jar 1.4.0
<!-- Build generated jars -->
<target name="axis-WSDL-2-Java" depends="init">
<taskdef resource="axis-tasks.properties" classpathref="axis.classpath" />
<axis-wsdl2java
output="${build.gen.src}"
testcase="true"
verbose="true"
url="${build.src.wsdl.v1}/${build.ws.wsdlfile}" >
</axis-wsdl2java>
<!-- Compile artifacts -->
<echo message="Compiling WS artifact source for Axis..." />
<javac destdir="${build.gen.classes}" debug="true" >
<src path="${build.gen.src}" />
<classpath>
<pathelement path="${build.lib.3rdParty}" />
<path refid="axis.classpath" />
</classpath>
</javac>
<jar .... some jar code here...
</jar>
</target>
Now, I converted the build script to Gradle and came up with the following Gradle code snap..
//wsdl to java
task axisWSDLTojava() << {
println "-- Inside axisWSDLToJava"
def flGen = new File( "$project.buildDir/thidsGen/src" )
flGen.mkdirs()
flGen = new File( "$project.buildDir/thidsGen/classes" )
flGen.mkdirs()
ant {
taskdef(
resource: 'axis-tasks.properties',
classpath: configurations.axisAnt.asPath )
axis-wsdl2java(
output: "$project.buildDir/thidsGen/src",
testcase: "true",
verbose: "true",
url: "$projectDir/src/ws/v1/wsdl/MDSSFileInfo.wsdl")
}
}
//compile generated src to classes
task compileJavaWsArtifacts (type: JavaCompile, dependsOn: axisWSDLTojava) << {
println "-- Inside compileGenSrc"
source = "$project.buildDir/thidsGen/src"
classpath = configurations.axisAnt.asPath
destinationDir = "$project.buildDir/thidsGen/classes"
}
// Build jar with web service artifacts
task jarWsArtifacts( type: Jar, dependsOn: compileJavaWsArtifacts ) << {
println "-- Inside jarWsArtifacts"
// some code here
// some code here to create the jar etc
}
Gradle logic for calling the respective task is all set i.e. I call the above task as dependsOn in CompileJava Gradle task..
// Compile java server components - must have artifacts first
compileJava {
dependsOn jarWsArtifacts
}
Configuration section in Gradle is defined as:
// Custom configurations
configurations {
axisAnt
}
Dependencies section in Gradle is defined as:
// Define dependencies
dependencies {
// Compilation
//compile 'groupid:artifactid:x.x.x'
//compile 'groupid:artifactid:x.x.x#yyy'
//other bunch of dependencies... come here which are required for compile task in Gradle
//axis-wsdl2java generates java files, which generates class files and jard into a -ws.jar file
compile fileTree( dir: 'build/resultantJar', include: "$ProjectName-ws-*.jar" )
// Unit Tests
testCompile 'xxx:yyy:x.x.x'
testCompile 'xxx:yyy:x.x.x'
//more artifacts for testCompile..
// Integration tests
// Everything from compile and testCompile targets
integrationTestCompile configurations.compile
integrationTestCompile configurations.testCompile
// Output of compiling "main" files
integrationTestCompile sourceSets.main.output
// Additional dependencies from war and others
integrationTestCompile 'xxx:yyy:x.x.x'
integrationTestCompile 'xxx:yyy:x.x.x'
//other enteries for IT test task
// All configuration files in conf folder in source control required for IT tests.
integrationTestRuntime files( 'conf' )
//Axis-ANT
axisAnt 'axis:axis-ant:1.4.0'
axisAnt 'othergroupid:otherartifactid:x.x.x'
axisAnt 'othergroupid:otherartifactid:x.x.x'
// comes here which are required for axis-wsdl2java to work
}
BUT, While running "gradle clean build", I'm getting the following error message:
:axisWSDLTojava FAILED
FAILURE: Build failed with an exception.
* Where:
Build file '/production/jenkinsAKS/workspace/DFDailyFeedSvc/build.gradle' line: 90
* What went wrong:
Execution failed for task ':axisWSDLTojava'.
> No such property: axis for class: org.gradle.api.internal.project.DefaultAntBuilder
Possible solutions: ant
Any idea, why it's not able to see axis-wsdl2java (which I see if defined in axis-tasks.properties file within axis-ant.jar version 1.4.0 as following:)
#properties file for taskdefing the public Axis taskdefs
axis-wsdl2java=org.apache.axis.tools.ant.wsdl.Wsdl2javaAntTask
axis-java2wsdl=org.apache.axis.tools.ant.wsdl.Java2WsdlAntTask
axis-admin=org.apache.axis.tools.ant.axis.AdminClientTask
OK, resolved.
Changing the following in the Gradle code did the trick. Don't know why Gradle didn't pick it without double quotes way. REASON: In Java/Groovy (Gradle uses Groovy), you can't have a function with a "-" in it's name (you can have giga_fifa but not giga-fifa). Glad, using "" resolved it.
axis-wsdl2java(
with
"axis-wsdl2java"(
Other thing, wherever I used "$project.buildDir .. I changed that to $buildDir as ANT was complaining about project.buildDir not found or buildDir not found when it was written in $project.buildDir format. Using $buildDir resolved those issues.
Also, compileJavaWsArtifacts was NOT seeing the generated src files!!! even though there were generated successfully after wsdl2java operation in Gradle build. So, did the shenzi using the following code:
//compile generated src to classes
//task compileJavaWsArtifacts (type: JavaCompile, dependsOn: axisWSDLToJava) << {
// source = "$buildDir/thidsGen/src"
// classpath = configurations.axisAnt.asPath
// destinationDir = "$buildDir/thidsGen/classes"
//}
//compile generated src to classes
task compileJavaWsArtifacts (dependsOn: axisWSDLToJava) << {
ant {
javac( destdir: "$buildDir/thidsGen/classes", debug: 'true', includeAntRuntime: 'no', classpath: configurations.axisAnt.asPath ) {
src( path: "$buildDir/thidsGen/src" )
}
}
}

Grails can't load maven-publisher

I am trying to add maven-publisher to a Grails (2.3.6) plugin like so:
dependencies {
compile 'org.mongodb.morphia:morphia:0.107'
compile ":maven-publisher:0.8.1"
}
When I run grails compile I get:
| Error There was an error loading the BuildConfig: Bad artifact coordinates
:maven-publisher:0.8.1, expected format is <groupId>:<artifactId>[:<extension>[
:<classifier>]]:<version> (Use --stacktrace to see the full trace)
What's going on here?
Do not use the maven-publisher plugin. It's old and deprecated. Use the release plugin - it should already be in your plugin's BuildConfig.groovy. If not, here's how it should look (after removing unnecessary cruft):
grails.project.work.dir = 'target'
grails.project.dependency.resolution = {
inherits 'global'
log 'warn'
repositories {
grailsCentral()
mavenLocal()
mavenCentral()
}
dependencies {
compile 'org.mongodb.morphia:morphia:0.107'
}
plugins {
build ':release:3.0.1', ':rest-client-builder:1.0.3', {
export = false
}
}
}
As #dmahapatro said in his comment, jar dependencies go in the dependencies block, and plugin dependencies go in the plugins block.
Note also that you should keep the export = false setting so the plugin is available locally for your use, but doesn't leak into the containing application as an unnecessary transitive dependency.

Classpath for ant plugins when using ANTBuilder from Gradle

I have a build.gradle file which loads PMD (downloading it from upstream Maven), and then loads an Ant build.xml file which requires PMD:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'pmd:pmd:4.2.5'
}
}
ant.importBuild 'shared-build.xml'
However, the Ant import fails:
taskdef class net.sourceforge.pmd.ant.PMDTask cannot be found
using the classloader AntClassLoader[]
at org.apache.tools.ant.ProjectHelper.addLocationToBuildException(ProjectHelper.java:551)
[...]
at org.gradle.api.internal.project.DefaultAntBuilder.importBuild(DefaultAntBuilder.groovy:76)
How can Gradle's ant integration be instructed to make this available?
There's no straighforward way to do it, as Gradle does not offer any API support for this. So you need to hack it some way.
For example, you can do something like this, right before calling ant.importBuild
org.apache.tools.ant.Project.class.classLoader.addURL( file('libs/somelib.jar').toURI().toURL() )
Alternatively you can call the addURL() method with the paths you get through the Gradle's dependency resolution (again, this should be executed before the call to ant.importBuild).
configurations { someconf }
dependencies { someconf "org.eclipse.jdt:ecj:3.6.1" }
def antClassLoader = org.apache.tools.ant.Project.class.classLoader
configurations.someconf.each { File f ->
antClassLoader.addURL(f.toURI().toURL())
}
Of course, another solution would be to have the classpath defined inside your build.xml file so you won't have to do anything from Gradle.
See some input here http://gradle.1045684.n5.nabble.com/How-to-add-to-classpath-for-ant-importBuild-td3268631.html

Resources