Difference between runtime and compile group - gradle

In a gradle build script I've the following piece of code:
dependencies {
runtime group: 'org.springframework', name: 'spring-core', version: '4.1.1'
}
and it works fine, but if I change it to
dependencies {
compile group: 'org.springframework', name: 'spring-core', version: '4.1.1'
}
an exception will be thrown during gradle build
Could not resolve all dependencies for configuration ':compile'.
> Could not find org.springframework:spring-core:4.1.1.
Searched in the following locations:
https://repo1.maven.org/maven2/org/springframework/spring-core/4.1.1/sprin
g-core-4.1.1.pom
https://repo1.maven.org/maven2/org/springframework/spring-core/4.1.1/sprin
g-core-4.1.1.jar
I thought the artifact searching for in the same place for both compile and runtime. What are differences between them?

Gradle resolves compile dependencies before it performs compilation, expecting that the source code will reference the artifact directly. However, it does not resolve runtime dependencies until later in the build process. (See #Dónal 's answer for usage guidelines in choosing between compile and runtime)
Thus, it is most likely that the difference between the two cases is that your build task required compilation, but not runtime prep. With your original configuration, any task requiring runtime prep would have failed with the same error.
To fix the failure in this specific case, I recommend changing your version value from 4.1.1 (which is not in the Maven repository you reference) to 4.1.1.RELEASE (which is).

Related

spring boot plugin and gradle dependency implementation

We have been using gradle spring boot plugin version 1.5.14 and gradle 4.10.3 for our builds. After an upgrade of gradle to 6.2.2, we've also changed dependency-definition from compile group to implementation group i.e.:
compile group: 'org.springframework.boot', name: 'spring-boot-starter-integration'
to
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-integration'.
The fat jar created via gradle assemble does to my surprise not contain the required libs under BOOT-INF/lib anymore? If I replace "implementation" with "compile" it works again as expected.
Is there something which needs to be configured so that spring-boot-plugin adds them? Or do I need to upgrade the project to spring boot 2 beforehand?
Implementation will bring in the dependency only for that module it is declared in.
Compile will allow a module that depends on the module to use the dependency as well.
Say you have Module A depending on Module B.
Module A and B both need the dependency:
com.font:font1:1.1.1
If B uses:
implementation 'com.font:font1:1.1.1'
A will not see font1, and will need to bring it into its own build.gradle file as well.
compile 'com.font:font1:1.1.1'
will make it available to the entire classpath (which should be avoided anyway, and the new equivalent is for libraries which uses 'api' instead of 'compile').
Without seeing your project directory, I'm assuming that some dependency is not being pulled into a place where it used to be grabbed from a lower dependency in the hierarchy. You should be able to find the missing dependencies easily by changing compile to implementation one at a time, unless you have a huge multi-module project.

gradle dependency with classifier

I am using gradle version 4.6:
in dependencies I add this:
testCompile "com.kuku:kuku:1.0:tests"
also tried this and same:
testCompile group: "com.kuku", name: "kuku", version: "1.0", classifier: "tests"
then gradle throw error:
Could not resolve all files for configuration ':testCompileClasspath'.
Could not find kuku-tests.jar (project :serializer_v9).
what I am doing wrong? needless to say I see the kuku tests jar in the build directory
So I found that the problem is Gradle includeBuild does not support yet publication that does not default: here
So the only way is to create separate jar with the test classes

How does Gradle's configurations hierarchy work?

I know there are four basic configurations, compile, runtime, testCompile, and testRuntime. If I put in a dependency like this:
runtime group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.3'
This means this dependency is available under runtime and compile, correct? But what about testCompile and testRuntime? Is it available for these configurations as well? If I add my own configuration, do I have to specify where it exists in the hierarchy? What happens if I don't? The documentation didn't really make this clear.
The definition for those 4 configuration are as follow for the java plugin :
compile
The dependencies required to compile the production source of the project.
runtime
The dependencies required by the production classes at runtime. By default, also includes the compile time dependencies.
testCompile
The dependencies required to compile the test source of the project. By default, also includes the compiled production classes and the compile time dependencies.
testRuntime
The dependencies required to run the tests. By default, also includes the compile, runtime and test compile dependencies.
you can also check https://docs.gradle.org/current/userguide/java_plugin.html#tab:configurations, it has pretty graph and table:
When you declare a new configuration you can define what other configuration it extends, for example Gradle In Action takes the example with Geb, you would define new configuration as
configurations {
functTestCompile.extendsFrom testCompile
functTestRuntime.extendsFrom testRuntime
}
If you dont, you assume those configuration do not need to benefit from another one and its standalone, you will need to define all dependencies this configuration requires.

could not resolve all dependencies for configuration ':compile'

To study Gradle I am using the book Gradle in action.
There was an example of dependency definition.
dependencies {
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.1'
}
But when I do in console gradle build I've got an error
What is the problem? My whole .gradle file looks like this
apply plugin: 'java'
dependencies {
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.1'
}
You did not tell Gradle where to find commons-lang3 library. Easy fix is to add the following to your build script:
repositories {
mavenCentral()
}
Of course you can find this piece of information in documentation - http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html#N10608
I was facing this same issue. I fixed it by using local gradle distribution instead of the default gradle wrapper. This is how it goes, make sure that you have Gradle installed and setup(PATH variable).
Open IntelliJ. Goto File->setting->Build, Exec, Deployment->Build tools->Gradle and use local gradle distribution and add your Gradle Home. Apply changes and try to run it now.

Process a subset of my dependencies in Gradle

I have a simple project where I'd like to unjar a subset of my dependencies and pack them into the output jar.
I have the two configurations:
configurations {
embed
all
}
dependencies {
embed group: 'commons-collections', name: 'commons-collections', version: '3.2'
...
all embed
all group: 'something-not-embeddable', name: 'dontembed'
compile all
}
According to http://www.gradle.org/docs/current/userguide/dependency_management.html 50.5 Working with Dependencies section's example it should work.
In a later section of my build, I want to unjar the embed jars and use them as source for jar.
My problem is that the gradle output says:
> Could not find method all() for arguments [configuration ':embed'] on root project 'myproject'.
Can you tell me why my approach is not working and how could I fix it?
Lol, looks like I chose a bad configuration name, works with alldeps instead of all

Resources