Include additional Sources for recompile in gwtSuperDev Task - java

I use the GWT Gradle Plugin. I have a second project which I included in my main project with:
dependencies {
compile(project(':core-project')) {
transitive = false
}
}
I have also created a settings.gradle which contains
includeFlat 'core-project'
The core-project is a library project. When I run gradle gwtSuperDev and change files in my main project recompile takes place but not if I change files in my core-project.
How can I make that the core-project sources are also recompiled in SuperDevMode when they have changed?

Depending on how your gradle dependencies are organized, you can simply add their source-files to the gwt section of your build.gradle file.
I have something like this in my build file:
gwt {
gwtVersion = '2.7.0'
if (System.getProperty('devmode') != null) {
modules = ['dk.logiva.invoice.autoaccount.gwt.AutoAccountAdminDev']
compiler {
style = 'PRETTY';
strict = true;
}
// include sources from inherited module
src += project(':invoice:gwt:gwt-common').files('src/main/java')
} else {
modules = ['dk.logiva.invoice.autoaccount.gwt.AutoAccountAdmin']
}
devWar = file("${buildDir}/war")
maxHeapSize = "3G"
}
...
dependencies {
compile project(':invoice:gwt:gwt-common')
...
}

Related

Delombok'ing source code with added jar dependencies

I am unable to delombok my Java source code, apparently due to jar dependencies that the project has, and I don't understand why. There are two jar files that have to be committed to the repo to tag along, and they are added to the project in the dependencies node of the build.gradle file by adding the line compile files('myproj1.jar'). So, the relevant part of the build.gradle file looks like this:
dependencies {
compile files('myproj1.jar')
compile files('myproj2.jar')
.....
}
When I run the delombok task I get the following error:
Execution failed for task ':delombok'.
> taskdef class lombok.delombok.ant.Tasks$Delombok cannot be found
using the classloader AntClassLoader[/path/to/repo/myproj1.jar:/path/to/repo/myproj2.jar]
Why would delombok task be using the AntClassLoader from the jar files?
I have tried the delombok'ing code from this post
Here is the task from my build.gradle file
def srcJava = 'src/main/java'
def srcDelomboked = 'build/src-delomboked'
task delombok {
// delombok task may depend on other projects already being compiled
dependsOn configurations.compile.getTaskDependencyFromProjectDependency(true, "compileJava")
// Set up incremental build, must be made in the configuration phase (not doLast)
inputs.files file(srcJava)
outputs.dir file(srcDelomboked)
doLast {
FileCollection collection = files(configurations.compile)
FileCollection sumTree = collection + fileTree(dir: 'bin')
ant.taskdef(name: 'delombok', classname: 'lombok.delombok.ant.Tasks$Delombok', classpath: configurations.compile.asPath)
ant.delombok(from:srcJava, to:srcDelomboked, classpath: sumTree.asPath)
}
}
I expect to be able to delombok my Java source code as part of the build process so that when the project is compiled there are no dependencies on Lombok.
So after continued trial an error, I have a working implementation. To answer my own question, the problem has nothing to do with the additional Jar files. Rather, when gradle runs the delombok task, the classes in the lombok jar are not in the classpath of the org.gradle.api.AntBuilder (ie, the ant task), and so it does not have a reference to lombok.delombok.ant.Tasks$Delombok anywhere (which seems obvious at this point, but not at the time).
The solution thus far has been to add those references in from configurations.compile
Combining code snippits from this post and this post you can do it with something like this:
def srcDelomboked = 'build/src-delomboked'
task delombok {
description 'Delomboks the entire source code tree'
def srcJava = 'src/main/java'
inputs.files files( srcJava )
outputs.dir file( srcDelomboked )
doFirst {
ClassLoader antClassLoader = org.apache.tools.ant.Project.class.classLoader
def collection = files( configurations.compile + configurations.testCompile )
def sumTree = collection + fileTree( dir: 'bin' )
sumTree.forEach { File file ->
antClassLoader.addURL(file.toURI().toURL())
}
ant.taskdef( name: 'delombok', classname: 'lombok.delombok.ant.Tasks$Delombok',
classpath: configurations.compile.asPath + configurations.testCompile.asPath )
ant.delombok( from: srcJava, to: srcDelomboked, classpath: sumTree.asPath )
}
}
sourceSets {
main {
java { srcDirs = [ srcDelomboked ] } //blow away the old source sets so that we only use the delomboked source sets
}
test {
java { srcDirs += [ srcDelomboked ] } //but add those new source sets to the tests so that their references are available at test time
}
}
compileJava.dependsOn(delombok)
bootJar {
mainClassName = 'com.myproj.MyMainClass' // you will need this if its a Spring Boot project
}
Hope this helps whomever else needs to delombok their code.

How to create JAR from specific classes and use it with Gradle?

I have few Java classes that I want to use on different projects.
I don't want to move these classes in a dedicated project for now.
So I want to build a JAR with these classes, and be able to use it in my other projects, all with Gradle.
So here my JAR task (sources) and I publish it as an artifact :
task utilitiesJar(type: Jar) {
baseName = 'utilities'
version = '0.0.1'
includeEmptyDirs = false
from sourceSets.main.allJava
include "**\\common\\exceptions\\**"
include "**\\common\\json\\**"
include "**\\common\\logging\\**"
}
publishing {
publications {
utilities(MavenPublication) {
artifact utilitiesJar
groupId group
artifactId utilitiesJar.baseName
version utilitiesJar.version
}
}
repositories {
maven {
url 'my_URL'
}
}
}
I get it back with an other project :
repositories {
mavenCentral()
maven {
url 'my_URL'
}
}
...
compile (...)
...
Seems like the JAR is correctly imported (I can see it in "External Libraries" of IntelliJ, with all its classes), but I can't use it.
Maybe because the .class files are missing ?
I'm beginner in Java, maybe I missed something.
How can I create a JAR with only some classes and then use it ?
Ok so as said in comments, I have to include the builded .class files, I can't use external .java classes like this.
So my solution :
def utilitiesName = '...'
def utilitiesVersion = '0.0.1'
task utilitiesJar(type: Jar, dependsOn: classes) {
baseName = utilitiesName
version = utilitiesVersion
includeEmptyDirs = false
from sourceSets.main.output
include ("**\\common\\exceptions\\**\\*", "**\\common\\json\\**\\*", "**\\common\\logging\\**\\*")
}
task utilitiesSourcesJar(type: Jar, dependsOn: classes) {
baseName = utilitiesName
version = utilitiesVersion
classifier = 'sources'
includeEmptyDirs = false
from sourceSets.main.allJava
include ("**\\common\\exceptions\\**\\*", "**\\common\\json\\**\\*", "**\\common\\logging\\**\\*")
}
publishing {
publications {
utilities(MavenPublication) {
artifact utilitiesJar
artifact utilitiesSourcesJar
groupId group
artifactId utilitiesName
version utilitiesVersion
}
}
repositories {
maven {
url 'myURL'
}
}
}
Now I can use it and see the classes in my IDE.
PS : doing in this way is pretty dirty. Create a sub-project / a module, it's just the way how to do it, that's finaly what I did.

Include specific classes in jar archive in gradle build

I have a newbie question on a gradle java project. I wish to configure the output artifact jar of this to only include certain classes from my project. I have the desired classes to be included in a file say classes.txt that is generated as a part of a separate task. How should one configure the jar task of the gradle build so that does this. This is what I have tried so far:
jar {
// reset actions
actions = []
copy {
def dependentClasses = file("classes.txt")
if (dependentClasses.exists()) {
dependentClasses.eachLine { include it }
}
from sourceSets.main.output
includeEmptyDirs = false
into "build/tmp/jar" //Some temporary location
}
// How to zip the contents?
}
I am sorry for the possibly naive question, but I haven't had luck with the other solutions seen.
Thanks!
It can be done in the following way:
apply plugin: 'java'
jar {
def excluded = project.file('classes.txt').readLines()
exclude { f ->
excluded.any { e -> f.path.replaceAll(File.separator, '.').contains(e) }
}
}
Demo can be found here, Lol1.class will be excluded.
Using Opal's answer, here is the answer for the include of files
apply plugin: 'java'
jar {
def included = project.file('classes.txt').readLines()
include { f ->
included.any { i -> f.isDirectory() ? true : f.path.replaceAll(File.separator, '.').contains(i) }
}
}
The slight trick was that the FileTreeElement f being passed to the closure also has the package directory passed and if that happens to return false, the subtree below is not traversed and hence the check on it being a directory to return true to enable processing of the subtree.
Demo for solution is here and Lol1.class will be included. Thanks for the help, Opal!

Gradle - how to specify javadoc location jar file for maven dependency?

I want to add local javadoc jar to maven dependency. Is it possible? If yes, how can I do it? The problem is that I've got maven dependency which contains transitive jars
dependencies {
compile 'org.eclipse.persistence:eclipselink:2.5.0'
}
gradle dependencies command returned this:
compile - Compile classpath for source set 'main'.
+--- org.eclipse.persistence:eclipselink:2.5.0
+--- org.eclipse.persistence:javax.persistence:2.1.0
\--- org.eclipse.persistence:commonj.sdo:2.1.1
Main dependency eclipselink contains javadoc for javax.persistence so I can't see javadoc hints in eclipse editor. What I want to do is to connect eclipselink javadoc to javax.persistence.
This is what I expect:
dependencies {
compile 'org.eclipse.persistence:javax.persistence:2.1.0' {
javadoc = <path to javadoc>
}
}
Problem solved. I've edited eclipse .classpath file using gradle eclipse plugin and it do what it should. This is the code:
eclipse {
classpath {
downloadSources=true
downloadJavadoc=true
file {
withXml {
def node = it.asNode()
// find eclipselink javadoc path
def eclipselinkPath = configurations.compile.find { it.absolutePath.contains('eclipselink') }
def javaxPersistenceJavadocPath = ""
node.each {
def filePath = it.attribute('path')
if (file(filePath) == file(eclipselinkPath)) {
javaxPersistenceJavadocPath = it.attributes.attribute.#value[0]
}
}
// add eclipselink javadoc path as attribute to javax.persistence
def javaxPersistencePath = configurations.compile.find { it.absolutePath.contains('javax.persistence') }
node.each {
def filePath = it.attribute('path')
if (file(filePath) == file(javaxPersistencePath)) {
it.appendNode('attributes').appendNode('attribute', [name:'javadoc_location', value:javaxPersistenceJavadocPath])
}
}
}
}
}
}
I know that it looks ugly but I didn't have more time to fight with that problem. BTW it wasn't the source of my problem (I've got problem with dependencies or gradle cache, I don't know yet).

Gradle scala class already defined with combined Java compilation

I have the following scala compilation issue
scala -> depends upon java source
java source -> depends upon scala source
My scala code is in src/main/scala
My java code is in src/main/java
I cant change this code so I need to compile this with gradle and it currently compiles with JRuby just fine.
I have read the following posts on how to solve this issue:
http://forums.gradle.org/gradle/topics/how_to_compile_a_java_class_that_depends_on_a_scala_class_in_gradle
http://forums.gradle.org/gradle/topics/how_to_compile_a_java_class_that_depends_on_a_scala_class_in_gradle
I added this to my build:
ext {
baseName = 'd2'
description = 'Divisional IVR.'
combinedSources = "$buildDir/combined-sources"
}
apply plugin: 'scala'
compileScala.taskDependencies.values = compileScala.taskDependencies.values - 'compileJava'
compileJava.dependsOn compileScala
sourceSets.main.scala.srcDir "$combinedSources"
sourceSets.main.java.srcDirs = []
I tried to copy all the scala and java files to one location:
compileScala.dependsOn{
copyAllSourceFiles
}
task copyAllSourceFiles(type:Copy) {
description = 'Copy All Source Files.'
from('src/main/java') {}
from('/src/main/scala') {}
into combinedSources
includeEmptyDirs = false
}
But now I get an error:
[ant:scalac] Compiling 18 source files to C:\usr\git_workspaces\xivr\d2\target\classes\main
[ant:scalac] Compiling 18 scala and 196 java source files to C:\usr\git_workspaces\xivr\d2\target\classes\main
[ant:scalac] C:\usr\git_workspaces\xivr\d2\target\combined-sources\com\comcast\ivr\d2\actors\AlternateAniWithAccountActor.scala:9: error: AlternateAniWithAccountActor is already defined as class AlternateAniWithAccountActor
It almsot seems like scalaCompile sees $combinedSources and 'src/main/scala'
It almsot seems like scalaCompile sees $combinedSources and 'src/main/scala'
That's how you configured it: src/main/scala is the default, and you added "$combinedSources". To override the default, use sourceSets.main.scala.srcDirs = [combinedSources].
In any case, you don't have to (and shouldn't) copy sources around. Here is one solution that neither requires copying nor reconfiguring of task dependencies:
sourceSets.main.scala.srcDir "src/main/java"
sourceSets.main.java.srcDirs = []
Now, your Java and Scala code will get joint-compiled, and can depend on each other arbitrarily.
PS: Instead of "$combinedSources", use combinedSources.
gradle.properties
theVersion=2.1
theSourceCompatibility=1.7
theScalaVersion=2.10.3
build.gradle
apply {
plugin 'scala'
plugin 'java'
plugin 'idea'
}
ext {
scalaVersion = theScalaVersion
}
sourceCompatibility = theSourceCompatibility
tasks.withType(ScalaCompile) {
scalaCompileOptions.useAnt = false
}
dependencies {
compile "org.scala-lang:scala-library:$theScalaVersion"
compile "org.scala-lang:scala-compiler:$theScalaVersion"
}
sourceSets {
main.scala.srcDirs = ["src/main/scala", "src/main/java"]
main.java.srcDirs = []
}

Categories

Resources