117

How do I add config files or any other resources into my jar using gradle?

My project structure:

src/main/java/com/perseus/.. --- Java packages (source files)

src/main/java/config/*.xml --- Spring config files

Expected jar structure:

com/perseus/.. --- Java packages (class files)

config/*.xml --- Spring config files

Mahozad
  • 18,032
  • 13
  • 118
  • 133
Pritesh Mhatre
  • 3,847
  • 2
  • 23
  • 27

8 Answers8

114

I came across this post searching how to add an extra directory for resources. I found a solution that may be useful to someone. Here is my final configuration to get that:

sourceSets {
    main {
        resources {
            srcDirs "src/main/resources", "src/main/configs"
        }
    }
}
Wellington Souza
  • 2,200
  • 2
  • 22
  • 33
87

Move the config files from src/main/java to src/main/resources.

Peter Niederwieser
  • 121,412
  • 21
  • 324
  • 259
73

Thanks guys, I was migrating an existing project to Gradle and didn't like the idea of changing the project structure that much.

I have figured it out, thought this information could be useful to beginners.

Here is a sample task from my 'build.gradle':

version = '1.0.0'

jar {
   baseName = 'analytics'
   from('src/main/java') {
      include 'config/**/*.xml'
   }

   manifest {
       attributes 'Implementation-Title': 'Analytics Library', 'Implementation-Version': version
   }
}
Siddharth
  • 9,349
  • 16
  • 86
  • 148
Pritesh Mhatre
  • 3,847
  • 2
  • 23
  • 27
  • 39
    It's more accurate to reconfigure the source set. Something like `sourceSets.main.resources { srcDirs = ["src/main/java"]; exclude "**/*.java" }`. – Peter Niederwieser Jul 14 '14 at 05:19
  • 1
    Thanks @PeterNiederwieser!! Been trying to get my log4j.xml file to be included in my executable jar that I was building using shadow. I too was dealing with an older project and could not readily change the directory structure. Your suggestion was exactly what I needed!! :D – Piko May 15 '15 at 20:58
  • @PeterNiederwieser - I notice in Java plugin documentation that resources is already defined to exclude *.java. "Contains only resources, and excludes any .java files found in the resource source directories." – Joe Bowbeer Jun 08 '15 at 20:45
31

By default any files you add to src/main/resources will be included in the jar.

If you need to change that behavior for whatever reason, you can do so by configuring sourceSets.

This part of the documentation has all the details

geoand
  • 60,071
  • 24
  • 172
  • 190
  • 6
    Would you know why only the content of `.../resources/` are included instead of the _resources_ directory __with__ the content? – sargas Sep 29 '15 at 03:44
  • @sargas You should probably start a new question where you can easily include all the context. It's hard to get much information in the comment section :( – geoand Sep 29 '15 at 08:28
21

I ran into the same problem. I had a PNG file in a Java package and it wasn't exported in the final JAR along with the sources, which caused the app to crash upon start (file not found).

None of the answers above solved my problem but I found the solution on the Gradle forums. I added the following to my build.gradle file :

sourceSets.main.resources.srcDirs = [ "src/" ]
sourceSets.main.resources.includes = [ "**/*.png" ]

It tells Gradle to look for resources in the src folder, and ask it to include only PNG files.

EDIT: Beware that if you're using Eclipse, this will break your run configurations and you'll get a main class not found error when trying to run your program. To fix that, the only solution I've found is to move the image(s) to another directory, res/ for example, and to set it as srcDirs instead of src/.

Mickäel A.
  • 9,012
  • 5
  • 54
  • 71
  • 3
    I used the `+=` operator to add my dirs to the existing dirs: e.g. `sourceSets.main.resources.srcDirs += [ "src/main/java" ]` – TmTron Jan 12 '18 at 16:01
3

Be aware that the path under src/main/resources must match the package path of your .class files wishing to access the resource. See my answer here.

mike rodent
  • 14,126
  • 11
  • 103
  • 157
1

As I have answered here, for more granularity while configuring the resource directories it's also possible to use srcDir.

sourceSets {
    main {
        resources {
            srcDir "src/main/resources"

            srcDir "src/main"
            include "configs/**/*.xml"
        }
    }
}

So, if you have src/main/java/config/*.xml jar structure will have configs/*.xml as asked.

Maicon Mauricio
  • 2,052
  • 1
  • 13
  • 29
0

This is for Kotlin DSL (build.gradle.kts).

Add the following code to your subproject or app build.gradle.kts file:

sourceSets {
    main {
        resources {
            srcDirs("src/main/configs", "src/main/misc")
        }
    }
    // OR another notation
    // main.get().resources.srcDirs("src/main/configs", "src/main/misc")
}

As mentioned by other answers, files in src/main/resources/ are automatically added to JAR. The srcDirs() function in above code adds its given paths to that existing path so files in those directories will be included in the JAR as well. You can add as many entries as you want.

Note that after adding the above code and syncing your changes with the IDE, some IDEs like IntelliJ IDEA and Android Studio show a helpful icon for those directories to indicate they are resources root directories:

A directory added as resources root in Gradle shown in IntelliJ IDEA

Mahozad
  • 18,032
  • 13
  • 118
  • 133