Use Case
I am trying to generate a dependency tree containing all plugins and dependencies for all configurations, but org.sonarqube is not included in the tree. I am working with a basic, single-module project and am using Gradle v7.5.1.
Examples
Running the following command outputs most (but not all) dependencies and plugins.
gradlew dependencies > dependency-tree.txt
Specify SonarQube plugin within build.gradle
plugins {
id 'org.sonarqube' version '3.2.0'
}
Specify SonarQube plugin within settings.gradle
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.2.0"
}
}
apply plugin: "org.sonarqube" // set in build.gradle, not in settings.gradle
Results
Neither approach includes the org.sonarqube plugin in the dependency graph. Is there a way to get this plugin to show up in the generated dependency tree? If yes, what changes need to be made?
The dependencies task provides the projet dependencies in each configuration, this does not include the projet script classpath (plugins).
You have another similar task available, buildEnvironment (see BuildEnvironmentReportTask) which will list the project build script dependencies.
you could combine both tasks outputs if you need a aggredated report of all project/plugin dependencies
> Task :buildEnvironment
------------------------------------------------------------
Root project 'demo'
------------------------------------------------------------
classpath
\--- org.sonarqube:org.sonarqube.gradle.plugin:3.2.0
\--- org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.2.0
\--- org.sonarsource.scanner.api:sonar-scanner-api:2.16.1.361
A web-based, searchable dependency report is available by adding the --scan option.
BUILD SUCCESSFUL in 452ms
Related
I have developed a Java library using the java-library Gradle plugin. This library has e dependency on protobuf-java which I need to expose as a transitive dependency to users of the library.
I have the following snippets in my library's build.gradle
plugins {
id 'java-library'
id "maven-publish"
id "com.google.protobuf" version "0.8.16"
}
...
dependencies {
api ("com.google.protobuf:protobuf-java:3.17.3")
testImplementation("com.google.protobuf:protobuf-java-util:3.17.3")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.2")
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.7.2")
}
Running gradlew dependencies gives me the following as expected
api - API dependencies for source set 'main'. (n)
\--- com.google.protobuf:protobuf-java:3.17.3 (n)
But when I add the library as a dependency to in my main app, I don't get any transitive dependencies. Doing a gradlew dependencies in my main app gives me:
compileClasspath - Compile classpath for source set 'main'.
+--- my-library:my-library:1.0.21
+--- javax.jms:javax.jms-api -> 2.0.1
....
What could be the cause for the dependency not showing up in the main app?
The problem was with the maven-publish plugin.
I had to add the following to my publishing section to get it to work.
publications {
mavenJava(MavenPublication) { from project.components.java }
}
I am using Gradle 6.1 in a multimodule project. I am also using two plugins: kotlin("jvm") and id("com.google.cloud.tools.jib"), and they are loaded in the following modules:
root/
build.gradle.kts loads kotlin("jvm")
services/
my-service/
rest/
build.gradle.kts loads id("com.google.cloud.tools.jib")
(There are more modules, files etc. but these are the relevant ones.)
The build fails:
$ ./gradlew clean jibDockerBuild
...
* What went wrong:
Execution failed for task ':services:driver:rest:jibDockerBuild'.
> com.google.cloud.tools.jib.plugins.common.BuildStepsExecutionException: 'org.apache.http.client.config.RequestConfig$Builder
org.apache.http.client.config.RequestConfig$Builder.setNormalizeUri(boolean)'
I identified the issue: both the Kotlin and JIB plugins have a transitive dependency on org.apache.httpcomponents:httpclient: Kotlin requires 4.5.3 and JIB 4.5.10. The problem is, in this project setup only 4.5.3 is loaded, and JIB fails as the new method is not available. This can be checked with ./gradlew buildEnv.
I've found a workaround, I need to load both plugins at the root level (which one is first seems to be irrelevant) in the main Gradle file; now ./gradlew buildEnv shows that the higher dependency version is used, also for Kotlin (output shortened and incomplete):
classpath
+--- org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin:1.3.61
| \--- org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.61
| +--- de.undercouch:gradle-download-task:3.4.3
| | \--- org.apache.httpcomponents:httpclient:4.5.3 -> 4.5.10
It works in this case, but it could be that the new library version breaks the Kotlin plugin. The problem is that the plugins and their dependencies are on the classpath without separation, something that was normal on Java before Jigsaw etc. Is there any way for Gradle to be able to separate the dependencies so that each plugin uses exactly the version it declares? I am building on Java 11, so the module system could be utilized, but does Gradle have an option to turn it on?
EDIT: updating to Kotlin 1.3.70 also fixes the issue as it doesn't depend on the library any longer. The general question is still valid, though.
Is there any way for Gradle to be able to separate the dependencies so that each plugin uses exactly the version it declares
No.
All plugins share the same build script configuration: classpath
It follows the same dependency resolution that application dependencies follow. So you can enforce that for this particular dependency only use a specific version always:
buildscript {
configurations {
classpath {
resolutionStrategy {
force("org.apache.httpcomponents:httpclient:4.5.10")
}
}
}
}
That's just one of many ways you can take control of dependency resolution for build script dependencies. You could also use a platform to advise on the dependency versions:
buildscript {
dependencies {
classpath(enforcedPlatform("org.springframework.boot:spring-boot-dependencies:2.2.5.RELEASE"))
}
}
Refer to the docs for more info:
https://docs.gradle.org/current/userguide/resolution_rules.html
https://docs.gradle.org/current/userguide/platforms.html
I have a multi module project with the following structure:
root_project
module1
module2
module3
I try to apply the java plug-in to all projects using the following code:
allprojects {
apply plugin: 'java'
group = 'com.mysoftware'
sourceCompatibility = 1.8
version = '1.3'
repositories {
mavenCentral()
}
}
Additionally I add the javafx plugin to module3. The java and javafx tasks are now shown in the intellij gradle view, but when trying to execute them, I get this error:
Task 'jfxJar' not found in root project 'module3'.
Furthermore, running the tasks task show me that neither the java tasks nor the javafx tasks are available, despite being shown in the gradle view in intellij.
I tried rebuilding and refreshing the whole project without success. I use the Use default gradle wrapper configuration.
The error message you got Task 'jfxJar' not found in root project 'module3' indicates that Gradle considers the subproject module3 as a Root project: this can happen if you created a settings.gradle file in the sub-project directory, which is not a valid setup (only one settings.gradle file can exist in a multiproject build, located in the root directory)
I have a library A that uses a library B. These two libraries are then used by application C.
Both library A and B can be found in a maven repository.
I have tried to add B as a dependency to A by adding it into A's POM file.
I'm not sure if this is the correct approach or there is a standard way to do this.
I am looking for either the standard way of doing this or a reference guide to point me into the right direction.
Please let me know if there is any other information I can provide.
The term for such relationship is called a transitive dependency. In your application, you define just the direct dependencies, the transitive ones are handled by a particular build system (Gradle, Maven, Ant + Ivy).
For example, considering following Gradle build script:
apply plugin: 'java'
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.0.2'
}
You can list this project dependencies with the command:
$ gradle dependencies
This should provide result similar to (depends on the Gradle version, this one is 4.4.1):
testCompileClasspath - Compile classpath for source set 'test'.
\--- org.junit.jupiter:junit-jupiter-api:5.0.2
+--- org.opentest4j:opentest4j:1.0.0
\--- org.junit.platform:junit-platform-commons:1.0.2
Therefore, opentest4j and junit-platform-commons are transitive dependencies of the junit-jupiter-api library, which is the only direct dependency of the project.
It's equivalent for Maven. E.g. you can list Maven dependencies with:
$ mvn dependency:tree
I am trying create an Gradle multi project similar to this structure
ouat-services
- ouat-contract
- ouat-servicesImpl (web project)
I followed the eclipse example and define my ouat-services settings.gradle as
include "ouat-contract", "ouat-servicesImpl"
In my ouat-servicesImpl build-gradle I define
dependencies {
compile project(':ouat-contract')
}
My problem starts when I try apply war plug-in in ouat-servicesImpl, I receive the following message in eclipse problem view:
Invalid classpath publish/ export dependency /ouat-contract. Project entries not supported
My ouat-services build.gradle
configure(subprojects) {
apply plugin: 'com.github.ben-manes.versions'
apply plugin: 'eclipse'
apply plugin: 'java'
version = '1.0'
sourceCompatibility = 1.8
targetCompatibility = 1.8
def defaultEncoding = 'UTF-8'
[compileJava, compileTestJava]*.options*.encoding = defaultEncoding
repositories {
jcenter()
mavenLocal()
mavenCentral()
}
jar {
manifest.attributes provider: 'Company'
}
}
configure(project(':ouat-servicesImpl')) {
apply plugin: 'checkstyle'
apply plugin: 'eclipse-wtp'
apply plugin: 'findbugs'
apply plugin: 'jacoco'
//apply plugin: 'jetty'
apply plugin: 'pmd'
apply plugin: 'war'
}
buildscript {
repositories {
jcenter()
mavenCentral()
mavenLocal()
}
dependencies {
classpath 'com.github.ben-manes:gradle-versions-plugin:0.10.1'
}
}
My ouat-servicesImpl build gradle was changed to:
dependencies {
compile project(':ouat-contract')
cxfArtifacts.each { artifact ->
compile "org.apache.cxf:$artifact:$cxfVersion"
}
springArtifacts.each { artifact ->
compile "org.springframework:$artifact:$springVersion"
}
testCompile "org.testng:testng:$testNGVersion"
testCompile "org.hamcrest:hamcrest-all:$hamcrestVersion"
testCompile "org.springframework:spring-test:$springVersion"
//WAR PLUGIN
providedCompile "javax.servlet:javax.servlet-api:$servletAPIVersion"
runtime "javax.servlet:jstl:$jstlVersion"
}
Is this an eclipse plug-in problem or I am doing something wrong?
Here's the magic steps I've discovered to make it work without messing with Project settings manually.
Run command: gradle cleanEclipse eclipse
as a result of this command Eclipse forgets that the project was supposed to have a gradle nature.
Add gradle nature back to the project by doing Configure -> Convert to Gradle Project.
as a result of this command the error reappears.
if incompatible plugin java version error appears then just delete .settings directory and refresh.
Run command: gradle cleanEclipseClasspath eclipseClasspath
this final step should get it fixed until the next time.
In my case, this was due to mixing "faceted" and non-faceted projects. The projects with the error had been converted to faceted form, and the project they referenced which it was complaining about had not been. You can configure the project to be faceted via use of the eclipse-wtp plugin, by adding this to your ouat-contract gradle file:
eclipse{
wtp{
facet{}
}
}
This will add facets for Java and a utility module when using the java and war plugins (see the EclipseWTPFacet documentation for more information on the defaults and manually adding facets if you aren't using the war plug-in). The utility module part is the key to avoid the error.
Note that within this block you can also access the facet file directly to perform manual XML manipulation if you need to do other things, like specify a particular Apache Tomcat Runtime or or similar
Once you make this change, you can use Eclipse to do Gradle -> Refresh All on ouat-contract within your workspace - once I did this, the error went away
I've also run into this problem long time ago. It really seems to be the problem related to the Eclipse plugin included in "Gradle IDE Pack" (as it works from the command line without problems).
My setup is probably way more complex than Yours (I'm including modules from one top-level gradle project into another top-level gradle project), but to overcome this specific error
Invalid classpath publish/ export dependency /my-project. Project entries not supported
... i excluded project dependency if some specific gradle property was missing:
if(project.hasProperty("myProjectRefAddedFromIDE")) {
println "NB! Build script started with property 'myProjectRefAddedFromIDE' - expecting that this project in IDE is configured to add the direct reference to my-project"
} else {
compile project(':my-project')
}
And to add the property "myProjectRefAddedFromIDE" only from IDE, i have configured eclipse plugin as follows:
Window -> Preferences -> Gradle -> Arguments -> Program arguments -> Use: ´-PmyProjectRefAddedFromIDE´
Just a warning: this will probably work for you, but there might be some other problem with Your setup, as for simple multi-module project (that doesn't include modules form another multi-module project) I don't have to use this workaround.
This works for me to remove the duplicate jar files from JRE System Library.
Steps Right click on Project and go to Build Path->configure build path->Libraries.
Remove the jars that are not in the classpath or duplicated in Maven dependency.