My introduction to Gradle is a legacy project that has been converted fairly directly from Ant to Gradle. It constructs a jar of common classes, an ejb-jar containing a large number of EJBs, a war and an ear containing everything.
The libraries that get packaged are not directly based upon the compiled dependencies, and as I make changes to the dependencies I’m concerned about the fragility of the build - each dependency is declared in multiple places for compilation and ant jar tasks.
The java packages have a lot of inter-dependencies, so it uses a lot of Ant patterns to determine what classes go into the jar/ejb-jar/war. This makes it difficult to modularize the existing code into separate projects.
Does it make sense to try and do all of this in a single build file? I’m struggling to figure out how I would build a jar of common classes and include it into the EAR (as an earlib) because I’m still new to gradle and it hasn’t clicked yet - and it’s just going to get more complicated.
Is all of the source in one directory and the ant patterns are used to select pieces for the jar/war/ear? Does all of the source build in one step right now? Can you give us some idea of what your structure looks like and what your build file looks like?
It probably could be done in one build file, but it sounds like it may more naturally fit a multi-project build (with separate jar, war, ear projects and dependencies across them).
If you’re stuck with the current directory structure, I’d look at trying to reuse the common ant patterns across the separate tasks. You can build portable CopySpecs. It’s not ideal, but you could create a “common jar” copyspec and reuse that in multiple places.
You may also be able to create a multi-project build with the existing layout with clever use of include/exclude patterns on sourceSets.java, but if your project is too entangled, that may make things worse.
Hi, there’s a single java source directory (src/java) for all the code, but a more complicated structure for property files and configuration files.
I guess what I’m struggling with is trying to work out how to configure a highly customized gradle build when I’ve never done the basics yet - I’m finding it hard to understand a lot of the examples I see online.
For example, in my first attempt to do all of this in a single build I have the java, war and ear plugins and I’ve customized the jar task to only include certain classes, and I’m calling this core.jar. I’ve no idea how I would go about adding that as an earlib to the ear task.
This is the sort of thing I’ve got so far:
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'ear'
sourceSets {
main {
java.srcDirs = ["src/java"]
// not sure if this is a good idea
compileClasspath += configurations.earlib
}
test {
java.srcDirs = ["src/test"]
}
}
dependencies {
// Application dependencies
// Java EE libraries
providedCompile 'javax.activation:activation:1.1.1'
providedCompile 'javax.mail:mail:1.4.5'
...
earlib 'joda-time:joda-time:2.5'
...
}
jar {
archiveName = 'core.jar'
include = [
'com/foo/bar/model/**/*'
'com/foo/bar/util/**'
...
]
exclude = [
'com/foo/bar/model/**/*DAO*.class'
...
]
}
ear {
// include core.jar somehow?
}
As you can see I haven’t got very far - I more looking to know whether this is a bad thing to even attempt because the resulting build is going to be very complex, and if that’s the case I’ll push for more modularization of the codebase (which sadly doesn’t appear to be going away any time soon).
Yes, that’s a bit of a headache. If it’s too hard to separate the single source tree, you could try something like this (models everything as separate projects in Gradle):
allprojects {
// common configuration (e.g., repositories {})
group = "my.company"
version = "1.0"
}
project(":core") {
apply plugin: 'java'
sourceSets {
main {
java {
srcDir rootProject.file("src/java")
includes = [ "**/com/foo/bar/model/**/*" ]
excludes = [ "**/com/foo/bar/model/**/*DAO*/*" ]
}
}
test {
// probably need to exclude some tests too?
}
}
}
project(":earproject") {
apply plugin: 'ear'
dependencies {
deploy project(":warproject")
earlib project(":core")
}
}
project(":warproject") {
apply plugin: 'war'
dependencies {
compile project(":core")
// other JavaEE dependencies...
}
sourceSets {
main {
java {
srcDir rootProject.file("src/java")
includes = [ "**/com/foo/bar/model/**/*DAO*/*" ]
}
}
test {
// probably need to exclude some tests too?
}
}
}
You could eventually move source to their project structure (from root/src/java to core/src/main/java, e.g.). You’ll have to configure some extra things this way for now because you’ll want everything to be relative to the root (vs subproject).