6

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.

Community
  • 1
  • 1
lospejos
  • 1,976
  • 3
  • 19
  • 35
  • 1
    Possible duplicate of http://stackoverflow.com/questions/32028947/gradle-distzip-config-files – wakjah Jul 16 '16 at 23:32
  • @wakjah I didn't found the question/anser you mentioned before I created my question, thanks for pointing. I'll check it. – lospejos Jul 16 '16 at 23:58
  • Probably most robust way is: when performing distZip task (or related, f.e. distTar etc), do the following: 1) copy files by mask (or all) to a specified folder inside zip (tar.gz) file; 2). patch start script to add this folder to classpath. But I cannot get how it may be done, so gradle gurus help is very appreciated. – lospejos Jul 17 '16 at 01:18
  • @lospejos: did you find a solution to the problem mentioned in addition #4? So can you have resources in `src/dist/config` which are on the classpath of IntelliJ, but not in the final jar file? – Pieter Aug 24 '17 at 13:42

1 Answers1

2

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')
}
Community
  • 1
  • 1
wakjah
  • 4,541
  • 1
  • 18
  • 23
  • Well I have an error: `"A problem occurred evaluating root project 'report-rest-server-sparkjava'. > Could not find method runtime() for arguments [file collection] on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler."`. I put `dependencies` block you mentioned into the root of my gradle script as well as inside `buildcript` block in my gradle script, but no luck. Gradle 2.14.1-rc-2 – lospejos Jul 17 '16 at 14:23
  • As I said before, I'm not an advanced Gradle user (that is sad), so please could you specify where exactly should I put your lines? Putting `startScripts` block in script "root" chain (not under some of closures) leads to: `Could not find method startScripts() for arguments [build_6f9g84j5bx1rq0giscgo9symy$_run_closure2@3419e23b] on root project '' of type org.gradle.api.Project` – lospejos Jul 18 '16 at 14:14
  • 1
    @lospejos You need to apply the `application` plugin in order to use `startScripts` -- see https://docs.gradle.org/current/userguide/application_plugin.html – wakjah Jul 18 '16 at 20:51
  • See my addition #2 in the question, we're almost done (notice the extra folder in start script classpath). – lospejos Jul 19 '16 at 23:02
  • See additions #2 and #3 – lospejos Jul 19 '16 at 23:29
  • See addition #4. It's almost done, but there is one more issue. Anyway I believe you're completely answered my question (thanks again! :-) ) but if you're familiar with Idea, it could be nice to resolve the last issue (mentioned in addition #4). – lospejos Jul 20 '16 at 06:54
  • @lospejos add this to your build.gradle will resolve your last issue: `sourceSets.main.resources.srcDir "src/dist/config"` – Budzu Jun 26 '17 at 22:06
  • @Budzu: your solution doesn't seem to work. I just end up with the resources back in the JAR where I don't want them. – Pieter Aug 24 '17 at 13:42
  • @Pieter Did you try this? It looks like my previous command was missing the equals: `sourceSets.main.resources.srcDir="src/dist/config"` – Budzu Aug 25 '17 at 15:10