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

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).

Related

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

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")
}

import dependencies from another module

I think I am missing some point in how dependencies management works in gradle.
Let's say I have the following project structure:
project
---api
------api-commons
------api-v1
------api-v2
------api-v3
where all api* directories are modules. All api-v* need a particular dependency (let's say common-dependency).
My aim would be to import it in api-commons build.gradle file:
dependencies {
implementation 'common-dependency'
}
while in the build.gradle files of the other modules api-v* put:
dependencies{
implementation project(':api:api-commons')
}
I would expect this to work but it doesn't. The code in the api-v* modules simply acts like the dependency is not declared. Indeed, if I import the dependency in the single modules, the code works as expected.
Am I doing a wrong assumption? Doesn't the dependency inheritance work like that?
Declaring a dependency in the implementation configuration conceptually means it is internal to the module (it is used in the implementation but not part of the public API). Such a dependency will not be exposed to the compile classpath of consumers, though it will still be on the runtime classpath.
An advantage of this way of modelling dependencies is that you do not need to recompile consuming projects if an implementation dependency changes. Another is that by encapsulating them, it is less likely that a consumer will start depending on them directly and then breaking if you change them.
If you want to expose the dependency to consumers, you have to declare it as part of the API for the module. You do that by applying the java-library plugin and using the api configuration.
Example:
// api-commons/build.gradle
plugins {
id 'java-library'
}
dependencies {
api 'common-dependency'
}
Read more about it in the Gradle user guide
Let say, I have to moved below common code(*.java files) from below 2 service/modules to sharedprocessing-data which is present inside shared-libraries service/modules :
abc-service
xyz-servcie
Address.java
Employee.java
Department.java
Vaccation.java
Name.java
City.java
Order.java
Steps0:
In shared- service/modules folder create additional module inside existing shared-libraries module
Name it as sharedprocessing-data
Steps1:
Move(refactor) common code inside this module
Steps2:
In parent folder (root) update settings.gradle file
rootProject.name = "root"
include 'abc-service'
include 'xyz-service'
include 'shared-libraries:sharedprocessing-data'
Step3:
In each of abc-service and xyz-flow service modules, update build.gradle file
dependencies
{
implementation project(':shared-libraries:sharedprocessing-data')
}

Gradle test library in multi module project

I want to create a library that other modules in my project can depend on, but only for tests. I've read the Gradle documentation extensively and couldn't find how to do it. This is my project structure:
gradle-example:
app:
src/main/kotlin ...
src/test/kotlin <- this is supposed to use 'com.example.SomeTestUtil'
testlib:
src/test/kotlin/com.example.SomeTestUtil
settings.gradle.kts:
rootProject.name = "gradle-example"
include("app")
include("testlib")
In the app module I tried adding
dependencies {
testImplementation(project(:testlib"))
}
But I get compilation error trying to import the SomeTestUtil in the app module test classes.
What is the correct way to declare dependency on a module in the same project that allows to use test sources in test code?
To clarify, we want to create a library that can only be used by other modules under src/test and not src/main.
Apparently this can be done by using the https://docs.gradle.org/current/userguide/java_testing.html#sec:java_test_fixtures
they can see the main source set classes
test sources can see the test fixtures classes
So changes to the example in the question are:
changing the src/test to src/testFixtures
declaring the dependency as testImplementation(testFixtures(project(":testlib")))
Adding java-test-fixtures plugin to the build.gradle.kts for the testlib module

how do you set up log4j for a gradle project with modules?

how do you set up log4j for a gradle project with modules?
I have a project set up like the following:
project root
build.gradle
gradle.properties
settings.gradle
// this root project does:
// include CommonModule
// includeBuild <all composite modules within module folder>
---CommonModule
------build.gradle
------gradle.properties
------settings.gradle
------src/main/groovy/...<common-code>
------src/main/resources/log4j2.xml
Modules
---OtherModule-1
// this is a gradle composite module
// it also includes the common module
------build.gradle
------gradle.properties
------settings.gradle
------src/main/groovy/...module1-code
------src/main/resources/log4j2.xml
---OtherModule-2
// this is a gradle composite module
// it also includes the common module
------build.gradle
------gradle.properties
------settings.gradle
------src/main/groovy/...module2-code
------src/main/resources/log4j2.xml
As shown above, we have a common gradle module and a module folder that contains module related composite module, each which depends on the included CommonModule
(core common code goes in common, the composite modules each contain code that extends common stuff
My question is hopefully simple:
where do I configure my log4j module?
e.g. can I put it in the common include module ?
or does each composite module need to have their own log4j xml?
I went and asked this same question on the gradle forums https://discuss.gradle.org/t/how-do-you-set-up-log4j-for-a-gradle-project-with-modules/28262 and got an answer -
Common module doesn’t include a log4j config Individual library
modules don’t include a log4j config either Top-level application
module does include a log4j config, but doesn’t put it on the
classpath (I set aside a src/[configuration]/config directory just
for that)
Launcher for the application itself (whether from a release
build or from a JavaExec in the Gradle build) specifies where the
log4j config is loaded from, so that you can’t get accidentally
poisoned by other configs on the classpath
you can define the xml location by providing a -D flag in the gradle properties file e.g. -Dlog4j.configurationFile=
also -Dlog4j.debug might help to track down issues

Gradle: how does one modify a dynamically created task?

I am building an Android Library project using the Android Gradle plugin (version 0.9.2) and it appears to have a bug (reported) in that while a "provided" dependency is correctly handled (not included) in the generated aar artifact, that dependency is incorrectly included in the generated debug test apk file.
It strikes me that a reasonable workaround is to remove the dependency jar file that is added by the :preDexDebugTest task as the last step for that task. But this task is dynamically generated so getting a handle to it is eluding me at the moment, hence the question.
In your app's build.gradle file, add
afterEvaluate {
def preDexDebugTest = tasks['preDexDebugTest']
// Do something with preDexDebugTest ...
}
That way it should be possible to operate on the preDexDebugTest task.

Resources