I recently started work on a 7+ year old project which uses Ant/Ivy for dependency & build management. I'm tasked with converting this to Gradle but the structure is a bit unconventional:
|- projectRoot
|- folderA
|- folderB
|- projectX
|- conf
| |- file1.txt
|
|- core
| |- src
| | |- App.java
| |
| |- test
| |- AppTest.java
|
|- res
| |- file2.txt
|
|- ivybuild.xml
|- ivysettings.xml
The Ivy build process is fairly straight forward, the resulting dist folder looks like this:
|- dist
|- proj.jar
|- lib
| |- dep1.jar
| |- dep2.jar
|
|- conf
| |- file1.txt
|- res
|- file2.txt
No resources are build in to the resulting JAR as some configurations are applied from a separate repository during deployment, thus the resources must stay external to the JAR.
I'm struggling to find a way to achieve this while also letting the IDE (Intellij IDEA) successfully locate the resources during debugging and running tests.
sourceSets {
main {
java {
srcDir 'core/src'
}
resources {
srcDir 'conf'
srcDir 'res'
}
}
test {
java {
srcDir 'core/test'
}
}
}
processResources {
from 'conf' into 'lib/conf'
from 'res' into 'lib/res'
}
startScripts {
classpath += files('conf')
classpath += files('res')
}
With the above I'm able to run/test the project successfully as all files from 'conf' and 'res' are copied into 'build/resources/main' which allows both debugging and tests to locate them. It copies both resource directories to the output lib folder and these are added to the classpath in the run script.
The above works except that the resources are still being copied into the built JAR. These override the external folder configurations so it will not do.
jar {
processResources {
exclude("*")
}
}
If I now run just assemble
then the built project is exactly how I want it, however the IDE now cannot run the debugger or tests successfully as it cannot locate the files missing under build/resources/main
I have also tried the idea
plugin to set the resource paths but to no avail.
Is there a way?
Example build.gradle
plugins {
id 'java'
id 'application'
}
// Project specifics
version '1.0-SNAPSHOT'
group 'com.example'
sourceCompatibility = 1.8
project.mainClassName = "core.ExampleApp"
dependencies {
testCompile 'junit:junit:4.12'
}
// Define the project source paths
sourceSets {
main.java {
srcDir 'core/src'
}
test.java {
srcDir 'core/test'
}
}
// Exclude all resources from the jar
jar {
processResources.exclude('*')
}
// Allows the 'test' task to see the directories on the classpath
test {
classpath += files('conf')
classpath += files('res')
}
// Allows the 'run' task to see the directories on the classpath
run {
classpath += files('conf')
classpath += files('res')
}
// Adds the directories to classpath in the start scripts
// They will have '$APP_DIR/lib/' prepended so they need to be copied into 'dist/lib/'
startScripts {
run {
classpath += files('conf')
classpath += files('res')
}
}
// Copy 'conf' and 'res' into the 'dist/lib' directory
distributions {
main {
contents {
from('conf').into("lib/conf")
from('res').into("lib/res")
}
}
}
gradle run
gradle test
example.zip/lib/conf
& .../lib/res
right click -> run tests
e.g.)BUT:
right click -> run main()
e.g.)Resolution:
right click -> run
and right click -> debug
FYI: As a gradle newbie, I have recently been caught by this when trying just exclude a few src/main/resources files from the jar
// Exclude all resources from the jar
jar {
processResources.exclude('*')
}
Actually does more than exclude from the jar - it excludes from the build entirely, in that they do not exist in build/resources/; so may impact your testing etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With