0

i have a gradle build that retrieves properties file and such that are remote (to keep passwords out of github) but the remote retrieval doesn't complete by the time the JAR is built.

i figured i either had to get the JAR created in the execution phase instead of configuration phase or add the remote files in the execution phase but i couldn't get either working.

any suggestions?

task fatJar(type: Jar) {

  doFirst {
    exec {
      executable './scripts/getRemoteResources.sh'
    }
  }

  ...

  from {
    configurations.compile.collect { it.isDirectory() ? it : zipTree(it) 
  }

  //some resources are retrieved remotely & b/c of timing they don't get included here
  from ('src/main/java/resources') {
    include '*'
  }

  with jar

  //tried this but doesn't work
  //doLast {
  //  jar {
  //    from ('src/main/java/resources') {
  //      include '*'
  //    }
  //  }
  //}


}
bail it
  • 3
  • 2

2 Answers2

0

this seems to work so i'm going with it unless someone has a better solution...

gradle.taskGraph.beforeTask { Task task ->

  println "just before $task.name"

  // i just chose to kick this off with the first task sent through here
  if (task.name=="compileJava") {
    exec {
      executable './scripts/getRemoteResources.sh'
    }
  }
}
      


task fatJar(type: Jar) {

  ...

  from {
    configurations.compile.collect { it.isDirectory() ? it : zipTree(it) 
  }

  from ('src/main/java/resources') {
    include '*'
  }

  with jar

}
bail it
  • 3
  • 2
0

You shouldn't use the task graph for this. Also you shouldn't download the file to src/main/

Instead, you should

  1. Create a task to download the remote resources to a directory under $buildDir (so it's cleaned via the "clean" task)
  2. Configure the TaskOutputs so that the result can be cached and re-used.
  3. Wire the task into Gradle's DAG
  4. Add the directory to the "processResources" task so it ends up on the runtime classpath (ie in the jar)

Eg:

tasks.register('remoteResources', Exec) {
   inputs.property('environment', project.property('env')) // this assumes there's a project property named 'env'
   outputs.dir "$buildDir/remoteResources" // point 2 (above)
   commandLine = [
      './scripts/getRemoteResources.sh', 
      '--environment', project.property('env'),
      '--outputdir', "$buildDir/remoteResources"
   ]
   doFirst {
      delete "$buildDir/remoteResources"
      mkdir "$buildDir/remoteResources"
   }
}
processResources {
   from tasks.remoteResources // points 3 & 4 (above)
}

See The Java Plugin - Tasks

processResources — Copy

Copies production resources into the production resources directory.

lance-java
  • 25,497
  • 4
  • 59
  • 101
  • btw, i also pass to my shell script what environment to get the remote resources from/for. doing it your suggested way, even if i add the clean task to the gradle call, i see files from the previous build (diff environment) in the jar along with the right resources. i look and the build/resources/main has the right files along with extra files even though my build/remoteResources has the right files. – bail it Jun 24 '21 at 21:46
  • You'll need to include the "environment" as task input so it's considered as part of the up-to-date check. Perhaps you also want to delete the "$buildDir/remoteResources" in a `doFirst {...}` block for the `remoteResources` task. See https://stackoverflow.com/questions/15137271/what-does-up-to-date-in-gradle-indicate – lance-java Jun 25 '21 at 07:28
  • having trouble adding task input. i tried doing a custom task definition to allow the new input and it went downhill from there. your suggestion is good, i'm just not strong on gradle. – bail it Jun 25 '21 at 14:35
  • Thanks, much simpler than i thought to add the inputs but same problem. i have it exactly like you show but my build/resources/main has too many files (from last run) and my build/remoteResources is correct. one other strange thing, i pass one of dev/test/prod as a property to gradle and when i pass test it works fine but dev and prod have residuals. very strange! btw, here is how i call gradle... ./gradlew -Penv=dev fatJar no matter if i delete the whole build dir manually before running, the cached last resources end up in the build/resources/main (and jar) once i run the gradle build. – bail it Jun 25 '21 at 17:16
  • I believe that you were previously downloading remote resources to `src/main/resources` have you cleaned this up since? – lance-java Jun 25 '21 at 17:32
  • ah, yes! that was it. that's why it only worked for 'test' property as the test version of the resources was still in src/main/resources !!! thanks!! – bail it Jun 25 '21 at 17:38