What is the exact purpose of Gradle configurations "all"? - java

I'm trying to get rid of all the errors and warnings suggested by the IDE (Intellij).
Among them, a warning occurs in the log4j2 dependency removal code, as shown below.
'exclude' cannot be applied to '(['group':java.lang.String, 'module':java.lang.String])'
I searched for a way to get rid of the error, and I succeeded in removing it.
But I don't know why it disappeared.
(the above alert. However, there is no problem in actual operation)
configurations {
all {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
}
configurations {
implementation {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
}
configurations {
all {
implementation {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
}
}
The first method is to display an error message.
The second and third methods do not have any error messages and work normally.
Could you point me to the difference between these three methods?

As far as the IntelliJ warning goes - it seems like this is a caching issue that can resolve itself.
Configurations
configurations is a ConfigurationContainer - it contains many instances of configurations, with the type Configuration. Each configuration has a name.
(Aside: yes, the name 'configuration' is confusing. It doesn't mean "properties or settings used to configure the Gradle project", it means "a collection of files that might be outgoing artifacts, or incoming dependencies")
configurations.all {} will retrieve all configurations, and attempt to configure each one using the contents of the lambda.
Unless we're inside a task, resolving all configurations is usually (but not always!) bad practice, because it might trigger work that could have been avoided, which will make the build slower. Instead, try and use configurations.configureEach {}.
configurations.implementation {} will retrieve a single configuration that is named implementation. The implementation configuration is created by the Java plugin. Again, the lambda will configure the configuration.
In both cases - the contents of the lambda will have a receiver type of Configuration.
configurations {
all {
// configure *all* configurations
// this is a Configuration
Configuration currentReceiver = this
}
implementation {
// configure the 'implementation' configurations
// this is also a Configuration
Configuration currentReceiver = this
}
}
Nested configurations
Your third example is unusual.
configurations {
all {
implementation {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
}
}
What this does is that any time a Configuration is added to the project's ConfigurationContainer, the lambda is triggered. The lambda that you've defined will configure the implementation configuration, and add an exclusion.
This is equivalent to this:
configurations {
ConfigurationContainer confContainer = this
all {
confContainer.implementation {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
}
}
Which is weird... try to avoid nesting configurations like this! In this simple example, it probably works out okay, but it will cause problems if the inner lambda is dependent on the other lambda, because implementation is part of all - so it might cause some weird recursions.

Related

How to add lombak (annotationProcessor type) dependency in test suites plugin in gradle?

I have created a new test suite using jvm-test-suite plugin.
I have added few implementation type dependencies and it was working fine, no error was coming. But I also want to add lombak dependency in that test suite, I tried it with implementation keyword, after that I checked the project is getting compiled but at the runtime those annotations (Eg: SneakyThrows) of lombak are getting ignored and I was getting error.
After that I tried adding lombak dependency with annotationProcessor keyword which resulting is below given error at gradle sync. So basically it looks like annotationProcessor keyword and testAnnotationProcessor are not getting recognised and thus this error is coming.
Exception is:
org.gradle.api.GradleScriptException: A problem occurred evaluating root project 'serverlessserver'.
at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:93)
Caused by: groovy.lang.MissingMethodException: No signature of method: build_aiuizpn3ddvrwt4slowy7mi4q.testing() is applicable for argument types: (build_aiuizpn3ddvrwt4slowy7mi4q$_run_closure4) values: [build_aiuizpn3ddvrwt4slowy7mi4q$_run_closure4#74ada7e2]
Gradle file snippet:-
testing {
suites {
test {
useJUnitJupiter()
}
customTest(JvmTestSuite) {
dependencies {
implementation project
... // other dependencies
annotationProcessor 'org.projectlombok:lombok:1.18.22' // adding this line is resulting in error message
}
}
....
}
}
I communicated with gradle development team on their slack support channel. I got the answer to this question which solved my problem and hence I am posting it here for other people.
plugin donot provide direct annotation processor support inside testing/suites block by default as of now, the team is implementing it and probably they will support it in future releases.
You can still mention this annotation processor in outer most dependencies block of build.gradle file along with test suite name.
Example - build.gradle sample file
dependencies {
.....
// dependencies you already have in your project
// add this line. "customTest" here is the name of test suite you defined.
customTestAnnotationProcessor('org.projectlombok:lombok:1.18.22')
}
One more thing you have to make sure is that you have defined your test suites before this dependencies block in build.gradle file. otherwise, the annotationProcessor statement in dependencies do not recognise the test suite and will give error.
This is what I used to not rewrite the same dependencies twice for test and customTest tasks (I also use lombok for my test):
configurations {
customTestImplementation {
extendsFrom testImplementation
}
customTestCompileOnly {
extendsFrom testCompileOnly
}
customTestAnnotationProcessor {
extendsFrom annotationProcessor
}
}
Directly from the official lombok website.
repositories {
mavenCentral()
}
dependencies {
compileOnly 'org.projectlombok:lombok:1.18.22'
annotationProcessor 'org.projectlombok:lombok:1.18.22'
testCompileOnly 'org.projectlombok:lombok:1.18.22'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.22'
}
Lombok annotations are applied during compilation, so it should be added in compileOnly stage, not in runtimeOnly.

Do an exclusion in build.gradle?

I want to add an exclusion to my build.gradle because my jar doesnt run after I compile it. The problem can be fixed if some modules are excluded.
How do I do that correctly? The following code should fix the problem:
compile ("com.badlogicgames.gdx:gdx-tools:$gdxVersion") {
exclude group: 'com.badlogicgames.gdx', module: 'gdx-backend-lwjgl'
}
For the most recent gradle versions (7+), you need to use the new syntax implementation or compileOnly. This should also be in a dependencies block as shown below:
dependencies {
implementation("com.badlogicgames.gdx:gdx-tools:$gdxVersion") {
exclude group: 'com.badlogicgames.gdx', module: 'gdx-backend-lwjgl'
}
}
See for more info
However for gradle 6 and below, your compile block should work fine inside a dependencies block.

Excluding dependency from implementation files

I have a jar that I am including in my Android project using the following syntax
implementation files('lib/fm.liveswitch.jar')
fm.liveswitch has a dependency of org.bouncycastle that I am already including as a dependency of my project. How do I exclude bouncycastle from being included as part of the jar?
I have already tried each of the following:
implementation (files('lib/fm.liveswitch.jar')) {
exclude group: 'org.bouncycastle'
}
implementation (files('lib/fm.liveswitch.jar')) {
exclude module: 'org.bouncycastle'
}
implementation (files('lib/fm.liveswitch.jar'), {
exclude group: 'org.bouncycastle'
})
implementation files('lib/fm.liveswitch.jar') {
exclude group: 'org.bouncycastle'
}
But each time I get an error similar to the below:
Could not find method exclude() for arguments [{group=org.bouncycastle}] on object of type org.gradle.api.internal.artifacts.dependencies.DefaultSelfResolvingDependency
When you add file based dependencies, they have no dependency metadata and thus no transitive dependency information.
Given this, there is no point in trying to add an exclude.
Adding implementation files('lib/fm.liveswitch.jar') will only add fm.liveswitch.jar on the classpath, nothing else.
Now if that JAR contains some bouncycastle classes inside, it is a different story. Gradle has no direct way of letting you control the visibility of the contents of a JAR.
You would then have two options:
Since it is a local JAR, you can yourself remove the offending classes from it.
You could attempt to leverage artifact transforms

Gradle - Exclude spring.xml from a dependency

Is there a way to exclude spring.xml from a gradle dependency? I have enabled autoscanning for all spring.xmls but do not want spring.xml from a specific jar to considered.
compile('com.savnet.ofm:ofm-client:16.08') {
exclude group: "net.sf.saxon", module: "saxon-xpath"
exclude group: 'hibernate'
}
You mean excluding a file from a JAR you depend on?
If so, then as far as I know there is no per-se supported way.
But you can make it manually.
Something like the following which is totally made up right now and not tested, so take this as a starting point that might work or might need some polishing to work.
configurations { foo }
dependencies { foo 'com.savnet.ofm:ofm-client:16.08'}
sourceSets { main.compileClasspath += configurations.foo }
task fooJar(type: Jar) {
archiveName = 'foo.jar'
from zipTree(configurations.foo.singleFile)
exclude 'spring.xml'
}
And then use fooJar output as runtime library.

UNEXPECTED TOP-LEVEL EXCEPTION while building android app

I have checked multiple times for duplicate dependencies but cannot find anything. Here are the screenshots.
Here is my build.gradle file
Here is my file structure.
Here is the error
Please help. It was running perfect since this morning.
try this and let me know
configurations.all {
exclude group: 'com.google.android', module: 'support-v4'
// other configurations
}
When I have same issue, I replaced compile with provided.
And recommendation - use concrete library that need your app like described here - http://android-developers.blogspot.com/2014/12/google-play-services-and-dex-method.html

Categories