Is there a way to convince Gradle to accept resource files (like XML files) as well in the src/main/java folder?
This would be great since I need to put my JavaFX XML files there ...
You could define where gradle looks for resource files by doing something like this:
sourceSets {
main {
resources {
srcDirs = ["src/main/java"]
includes = ["**/*.fxml"]
}
}
}
The equivalent Kotlin DSL would be:
sourceSets {
main {
resources {
srcDirs("src/main/java")
include("**/*.fxml")
}
}
}
As the name suggests src/main/java is for JAVA files. Whilst it's possible to tweak gradle's defaults to allow resources in this folder, you shouldn't (in my opinionated view).
I suggest you stick to the sensible conventions and put your xml etc in src/main/resources. This convention is followed by both Maven and Gradle.
Related
how to regenerate missing source paths in in a Gradle project? I need to generate all those missing folders like src/java, src/clojure and so on. depends on project plugins. So if I add say Java plugin then src/java/ will be generated.
I just saw that some IDE has an option to create al source paths of the plugins when it imports the project - so I assume it is possible to do from the command line.
You can do that in build.gradle by changing the sourceSets.
sourceSets {
main {
java { srcDirs 'src/java' }
clojure { srcDirs 'src/clojure' }
}
}
If you also need to do the same for the test folders, this should work too:
sourceSets {
test {
java { srcDirs 'test/java' }
clojure { srcDirs 'test/clojure' }
}
}
Java plugin will not create folders for you, it instead assumes a project layout, and you are free to change this structure by doing something similar to what I have above. I have not used the clojure plugin, but I assume it behaves in a similar way.
If you want to list all the folders that the java plugin is making use of, you can do this:
println sourceSets.main.allJava.asPath
Displays all the files being watched by the java plugin.
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
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"
}
}
}
Move the config files from src/main/java to src/main/resources.
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
}
}
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
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/.
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.
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.
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:
I have query files in same location as my classes. But gradle is not copying query files into classes directory after compiling. I added following below, but it did not work. Can you help how to resolve this issue?
I can't refactor to move query files.
processResources {
from('src/main/java') {
include '**/*.properties'
}
}
The follow structure
src
service
service1
Service.java
Service.properties
I want that the output generated by gradle would be
classes
service
service1
Service.class
Service.properties
If your structure is src/service/service1/Service.properties it is quite obvious why nothing is copied if you copy from src/main/java, isn't it?
Besides that, it might be better to configure sourceSets { main { resources { ... } } } instead of configuring the processResources task.
Gradle and Maven both use the same sensible convention
src/main/java is for java files ONLY
src/main/resources is for resources (eg properties, xml, images etc)
I suggest you stick to these very sensible conventions. Both Gradle and Maven can be configured to allow resources in src/main/java but this should be avoided if at all possible.
Don't mess with a default!
If you really want resources in src/main/java then I suggest you do
processResources {
from('src/main/java') {
exclude '**/*.java'
}
}
I'm trying to include the compiled .class files from Project1 into the jar for Project2 since my project structure requires it to be done. For that, in the build.gradle for Project2, I write :
jar {
from project(':Project1').sourceSets.main.output.classesDir
}
Which successfully does what I had to do. But, I now want to filter some of the classes that are added based on path and/or some pattern. For example, to include only delegate files, I tried this :
jar {
from project(':Project1').sourceSets.main.output.classesDir {
include '**/*Delegate*.class'
}
}
But unfortunately it doesn't work. Is there a way to achieve this in Gradle/Groovy?
Using Gradle 2.12, the following works for me (this is build.gradle for Project 2):
task myBuild(type: Jar) {
baseName "myjar"
from project(':Project1').sourceSets.main.output.classesDir,
{ include "**/*Delegate*.*" }
}
From the doc for Jar.from, note that it takes 2 arguments (hence, the comma is used).
Thanks Michael
Although I got my answer as well, I was just missing a parantheses. The correct and working code goes something like this :
jar {
from (project(':Project1').sourceSets.main.output.classesDir) {
include '**/*Delegate*.class'
}
}
So I have setup a way to just run integration tests using this configuration:
test {
exclude "**/*IntegrationTest*.class"
}
task integrationTest(type: Test, dependsOn: testClasses) {
include "**/*IntegrationTest*.class"
}
check.dependsOn integrationTest
Works great. But then for logging in my integration tests, I want to use a log4j.properties file from a specific directory instead of the one that is located in the src/main/resoures which is used for production.
I've tried this but didn't work:
integrationTest.classpath = files("$rootDir/test/src/main/resources/log4j.properties") + integrationTest.classpath
I also tried to just see if I could exclude the file, but could not find a way. Tried this:
processTestResources.exclude "**/*log4j.properties"
Any suggestions for including one properties file in production and another one for tests?
If you put the 'test' log4j.properties in the src/test/resources directory, it will actually come before anything in src/main/resources on the classpath of your tests/integration tests.
An alternative solution is to setup your bundling so that the log4j.properties for production is not in src/main/resources, but is added to the jar from a different directory...
jar {
from('production') {
include('log4j.properties')
}
}
If you want to keep the log4j.properties files in their current locations, you were almost there with what you tried. On the classpath you can have either jar files, or directories containing resources. So try doing this:
integrationTest.classpath = files("$rootDir/test/src/main/resources") + integrationTest.classpath
Seems like you could do something like this also so that the .jar task will include it later:
sourceSets {
main {
java {
srcDir 'src/main/java'
output.classesDir = 'build/classes/main'
}
resources {
srcDir 'src/main/resources'
include 'logback.xml'
output.resourcesDir = 'build/resources/main'
}
}
}