How to get the Gradle build directory in a Java annotation processor - gradle

I am writing a custom annotation processor in Java which needs to create a file.
It seems to me the best location for that file would be in a new folder inside the Gradle's $buildDir.
For a project without modules, the environment property "user.dir" seems to hold a value I could use.
However, that environment property changes if the project has modules and the gradlew build command is executed either from inside or outside a module.
What is the best approach to actually get in Java the Gradle build directory of the module in which the annotation processor is declared ?
P.S.
I do not want to create that file in the "build/generated" folder (this is what processingEnv.getFiler().createSourceFile(..) does).

You should do it the other way around : choose a location and set it up in your build.gradle
tasks.withType(JavaCompile) {
options.annotationProcessorGeneratedSourcesDirectory = file("your/custom/path")
}

Related

Add a file to a specific folder with gradle build

I am currently working with a project (using gradle) that needs a properties file in the same package to the class that consumes it (I can't change this config). I have added the file in my package, but when I execute the gradle build command omits the file, and only adds the .class file. The app is deployed as a war file.
I have tried editing the war task, but I can't find the way to make the properties file to be added:
war {
from('src/main/com/foo/bar') {
include 'b.properties'
into 'WEB-INF/classes/com/foo/bar'
}
}
The war task does execute (I have added a prinln and it executes). Also, I have tried changing the paths, but no results. Also replacing from('path') to from (file('path')), but still doesn't seem to add the file anywhere.
How should I achieve this? Thanks!
Is there anything stopping you from following Gradle's convention for resources?
Eg put your property file at src/main/resources/com/foo/bar/b.properties
If you do this you won't need any task customisations

Is there a simple way to access project resource files from a gradle task?

I am working on a Gradle task for a java project. The task needs to read files from a subfolder of the project’s resources directory. I was expecting to find a standard way for Gradle to access project resources but have been unable to find one. Does Gradle provide simple way to find and import resource files? Maybe through a plugin?
If you mean the src/main/resources folder, then no. That is by convention used by the Java plugin to hold resources for the actual module and not the build classpath. But if you just want to read a file in it from a task, just use normal Java, Groovy or Kotlin APIs. You don't need a plugin for that.
Here is one for Groovy:
task printMyResource {
doLast {
logger.quiet(file("src/main/resources/subfolder/my_file.txt").text)
}
}
(The file method resolves a path to a File object relative to the project folder.)

Add local Gradle source module by absolute path

I want to add a subproject to my Gradle project. The project is located somewhere on my hard disk drive, for example:
/A/Path/to/a/ProjectA
/Another/Path/to/another/ProjectB
What I want to achieve is to use ProjectB as a source module within Project A. However, all my attempts to do this so far - either by adding include /Another/Path/to/another/ProjectB or by adding include ':ProjectB'; project(':ProjectB').projectDir = ... in settings.gradle - just failed. Apparently, Gradle is not able to find the project.
How can I add ProjectB as a dependency without moving it from it's location?
Using Gradle 3.4.1, the following works for me (full example here):
include 'app', 'common'
def MY_PATH = '/Users/johndoe/foo'
assert new File("$MY_PATH/random/path/common").exists()
project(':common').projectDir = new File("$MY_PATH/random/path/common")
Thanks for your responses.
Turns out I've made several mistakes:
Adding the project to the built was dependent on the value of an environment variable. I replaced that with a property within gradle.properties.
I tested this by running the settings.gradle usind IntelliJ. I mistakingly expected this to work, but it didn't
I did not add the project as a dependency to the build.gradle file of the parent project.
It works now. Thank you all again!

Gradle equivalent for maven properties

How can I add properties in Gradle which are similar to Maven's properties?
The use case is this: I want to have a file which declares all versions for repo dependencies so they are unified in a single place for a multi module project
compile group: 'javax.servlet.jsp.jstl', name: 'jstl', version: '1.2'
In Maven you can have properties like this:
<properties>
<jstlVersion>1.2</jstlVersion>
</properties>
Is it ok to use Gradle's external properties? Or just add them to the gradle.properties file?
Project properties defined in the root build file are available to subprojects. So if you have this in your root build.gradle file:
ext.commonsLangVersion = "2.4"
then you can use that in the dependencies {} block of a subproject like so:
dependencies {
implementation "commons-lang:commons-lang:${commonsLangVersion}"
}
You can also define such properties in the root gradle.properties file instead of the root build file. You use them in the same way.
If you really feel the need to put the versions in a separate file, you can do so. Simply add the following line to the root build file:
apply from: "dependencies.gradle"
Within the dependencies.gradle file, you can define the extra project properties as if they were in the root build file directly:
ext.commonsLangVersion = "2.4"
Note Normally, the values set in the build script take precedence over the values in gradle.properties. But if you set a value in the root build script as above, then any matching value in gradle.properties will override it in subprojects.
This behaviour is somewhat confusing and unique. For behaviour that is consistent with Gradle single-project builds you would need to use the following in the root build script:
allprojects {
apply from: "dependencies.gradle"
}
As a general rule of thumb, any given property should be declared/defined in either the build script or gradle.properties. If users want to override a particular property value, they can do so in $USER_HOME/.gradle/gradle.properties.
[EDIT I have updated the above note to clarify the actual behaviour]
One final thing: Gradle also allows you to control the versions of transitive dependencies via dependency constraints. You can also import Maven BOMs if you're using Gradle 4.6 or newer.
Found this as a possible solution, though I don't really like that uses relative path to the properties file.
Point 7 from here:
https://proandroiddev.com/make-your-build-gradle-great-again-c84cc172a654#8029

Setting dependency of a component to mantle-usl - custom Groovy class

I have a custom groovy class inside mantle-usl component. I would like to use the class in other component. Hence, I need to add a dependency so that the new component (or project) has the jar of mantle-usl ready for use.
Is there anyone who can help with this? I attempted to modify the build.gradle file of the project. And add a project dependency, but it returned an error.
project(':runtime/component/warehouse-items-masterenumerator') {
dependencies {
compile project(':runtime/component/mantle-usl')
}
}
As you would expect, this does not work. It seems that I do not have the project references set correctly.
The mantle-usl component doesn't have any compiled code in it so the build.gradle file does not build a jar file, it is only used for running the Spock tests.
I wouldn't recommend adding your own code to mantle-usl, it is easier and cleaner to put it in a separate component. For an example of a build.gradle file that does build a jar file look at the moqui/example component or most of the moqui tool components (such as moqui-elasticsearch).
You also don't need to modify the main build.gradle file from the moqui-framework repository, dependencies should be declared in the build.gradle file in each component (which are picked up automatically in the main build).

Resources