Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gradle build file with conf folder with properties not in jar but on classpath

Tags:

java

gradle

Could you please share a build.gradle script example with configured folder "conf":

  1. This folder including all containing files is packaged into zip file during "gradle distZip";
  2. Files in this folder are on classpath (e.g. accessible to ClassLoader) in startscripts files (in bin folder);
  3. These files also are on classpath when running gradle run, gradle build etc.

Addition #1:

I've done actions mentioned in answer pointed by @wakjah, files was copied to a zip file and was not put into jar during gradle distZip, this covers my requirement #1. But this folder is not on classpath in start scripts from bin folder (requirement #2 is not covered). Files are not on classpath when running gradle clean run (requirement #3 is not covered).

Addition #2:

I started sample project from scratch and with the help of @wakjah now I have:

  1. Req #1: ok (directory config contains resource file), but this resource is also in lib folder.
  2. Req #2: ok (directory config is on classpath in start script), but classpath additionally contains invalid folder %APP_HOME%\lib\config
  3. Req #3: ok

Additionally, I tested 3 approaches of loading file contents (as mentioned here), method Thread.currentThread().getContextClassLoader().getResource(name) succeeded.

Added my sample project zip file here: http://rgho.st/8r2dJjSz7

Addition #3:

When I comment / remove in gradle script:

dependencies { runtime files('src/dist/config') }

lib/config folder is not on CLASSPATH (it's ok), and resource file gets not copied to lib folder (it's ok). But resource file is failed to load both starting class main() method from Idea and running gradle clean run from command prompt. After gradle clean distZip and deploying (unpacking) application, resource gets loaded.

Addition #4:

After replacing

dependencies { runtime files('src/dist/config') }

to tasks.withType(JavaExec) { classpath += files('src/dist/config') } everything went fine, thanks, @wakjah! There is one more issue, not mentioned in initial requirements: when I start this project inside Idea (not executing gradle run, but starting main() in class directly from Idea), file in config directory could not be loaded using any of approaches mentioned earlier.

like image 566
lospejos Avatar asked Oct 29 '22 23:10

lospejos


1 Answers

As mentioned here Gradle distZip config files you can just add the folder dist/config to your src folder and it will be included by the distZip task automatically.

As for adding it to the runtime classpath, just add the folder as a dependency (see below).

Requirement #2 is a little harder, due to limitations with startScripts. This question has an answer that proposes a workaround, however: Adding classpath entries using Gradle's Application plugin

The following code collects all of the above:

// put config files in src/dist/config

dependencies {
  runtime files('src/dist/config')
}

startScripts {
  classpath += files('src/dist/XxxAPlaceHolderForAConfigxxX')
  doLast {
    def windowsScriptFile = file getWindowsScript()
    def unixScriptFile    = file getUnixScript()
    windowsScriptFile.text = windowsScriptFile.text.replace('%APP_HOME%\\lib\\XxxAPlaceHolderForAConfigxxX', '%APP_HOME%\\config')
    unixScriptFile.text  = unixScriptFile.text.replace('$APP_HOME/lib/XxxAPlaceHolderForAConfigxxX', '$APP_HOME/config')
  }
}

I have tested this and it appears to work. The correct classpath entries appear in both the run scripts and the command line used by gradle during the run task.

EDIT: In your comment you implied that you also want this to be available in the classpath of your build script. If that is the case, you need to add a buildscript dependency like this:

buildscript {
  dependencies {
    classpath files('src/dist/config')
  }
}

EDIT #2: In another comment you mention that adding the runtime dependency has the unintended consequence of producing an extra, invalid, entry in the start script classpath. You could fix this by just adding to the classpath of any JavaExec tasks, rather than using a dependency. So replace the dependencies { runtime { ... } } block with

tasks.withType(JavaExec) {
  classpath += files('src/dist/config')
}
like image 156
wakjah Avatar answered Nov 15 '22 07:11

wakjah