I'm following the sample code in Gradle's Transform dependency artifacts on resolution page.
def artifactType = Attribute.of('artifactType', String)
def minified = Attribute.of('minified', Boolean)
dependencies {
attributesSchema {
attribute(minified)
}
artifactTypes.getByName("jar") {
attributes.attribute(minified, false)
}
}
configurations.all {
afterEvaluate {
if (canBeResolved) {
attributes.attribute(minified, true)
}
}
}
dependencies {
registerTransform(Minify) {
from.attribute(minified, false).attribute(artifactType, "jar")
to.attribute(minified, true).attribute(artifactType, "jar")
}
}
dependencies {
implementation('com.google.guava:guava:27.1-jre')
implementation(project(':my-sub-project'))
}
When I run gradlew :my-app:test I get:
FAILURE: Build failed with an exception.
* What went wrong:
Could not determine the dependencies of task ':my-app:test'.
> Could not resolve all task dependencies for configuration ':my-app:testRuntimeClasspath'.
> Could not resolve project :my-sub-project.
Required by:
project :my-app
> The consumer was configured to find a runtime of a library compatible with Java 17,
packaged as a jar, preferably optimized for standard JVMs, and its dependencies
declared externally, as well as attribute 'minimized' with value 'true'.
However we cannot choose between the following variants of project :my-sub-project:
- archives
- checkstyle
- default
- jacocoAgent
- jacocoAnt
- runtimeElements
All of them match the consumer attributes:
...
- Variant 'runtimeElements' capability my_project:my-sub-project:unspecified declares a runtime of a library compatible with Java 17, packaged as a jar, and its dependencies declared externally:
- Unmatched attributes:
- Doesn't say anything about its target Java environment (preferred optimized for standard JVMs)
- Doesn't say anything about minimized (required 'true')
How can I exclude our internal projects (and maybe even libraries within our group) from the requirement of being minimized?
I've managed to fix the problem with allprojects:
configurations.all {
// Skip internal projects
allprojects {
attributes.attribute(minimized, true)
}
// Request minimized=true on all resolvable configurations
afterEvaluate {
if (canBeResolved) {
attributes.attribute(minimized, true)
}
}
}
Related
springboot gradle plugin version: org.springframework.boot:spring-boot-gradle-plugin:2.7.2
I have defined different versions of Java for compilation and test as mentioned here but thats just for compile and test.
tasks.withType(JavaCompile).configureEach {
javaCompiler = javaToolchains.compilerFor {
languageVersion = JavaLanguageVersion.of(8)
}
}
task('testsOn14', type: Test) {
javaLauncher = javaToolchains.launcherFor {
languageVersion = JavaLanguageVersion.of(14)
}
}
Ref: https://docs.gradle.org/current/samples/sample_jvm_multi_project_with_toolchains.html
The jar task is defined simply as jar.dependsOn(bootJar)
I want this task to create 2 jars: myproject-j8.jar and myproject-j14.jar meaning one build with Java-8 and other with Java-14. No idea how to do that. Thanks for taking a look.
The straight question is: why is Gradle not resolving this dependency I added
dependencies {
//kafka-protobuf-serializer
implementation("io.confluent:kafka-protobuf-serializer:6.0.0")
}
?
Accoring to mvn this is how I add such dependency in my build.gradle
compile group: 'io.confluent', name: 'kafka-protobuf-serializer', version: '6.0.0'
All my other dependencies are added with "implementation ...". So far so good. But for this speficic I got
Execution failed for task ':extractIncludeProto'.
> Could not resolve all files for configuration ':compileProtoPath'.
> Could not find io.confluent:kafka-protobuf-serializer:6.0.0.
Searched in the following locations:
- file:/C:/Users/Cast/.m2/repository/io/confluent/kafka-protobuf-serializer/6.0.0/kafka-protobuf-serializer-6.0.0.pom
- https://jcenter.bintray.com/io/confluent/kafka-protobuf-serializer/6.0.0/kafka-protobuf-serializer-6.0.0.pom
Required by:
project :
Possible solution:
- Declare repository providing the artifact, see the documentation at https://docs.gradle.org/current/userguide/declaring_repositories.html
What I am missing or messing here?
Here is the whole build.gradle
plugins {
id "org.jetbrains.kotlin.jvm" version "1.3.72"
id "org.jetbrains.kotlin.kapt" version "1.3.72"
id "org.jetbrains.kotlin.plugin.allopen" version "1.3.72"
id "application"
id 'com.google.protobuf' version '0.8.13'
}
version "0.2"
group "account-control"
repositories {
mavenLocal()
jcenter()
}
configurations {
// for dependencies that are needed for development only
developmentOnly
}
dependencies {
kapt(enforcedPlatform("io.micronaut:micronaut-bom:$micronautVersion"))
kapt("io.micronaut:micronaut-inject-java")
kapt("io.micronaut:micronaut-validation")
implementation(enforcedPlatform("io.micronaut:micronaut-bom:$micronautVersion"))
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlinVersion}")
implementation("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinxCoroutinesVersion")
implementation("io.micronaut:micronaut-runtime")
// implementation("io.micronaut.grpc:micronaut-grpc-runtime")
implementation("io.micronaut.grpc:micronaut-grpc-server-runtime:$micronautGrpcVersion")
implementation("io.micronaut.grpc:micronaut-grpc-client-runtime:$micronautGrpcVersion")
implementation("io.grpc:grpc-kotlin-stub:${grpcKotlinVersion}")
//Kafka
implementation("io.micronaut.kafka:micronaut-kafka")
//vertx
implementation("io.micronaut.sql:micronaut-vertx-mysql-client")
//implementation("io.micronaut.configuration:micronaut-vertx-mysql-client")
compile 'io.vertx:vertx-lang-kotlin:3.9.4'
//mongodb
implementation("org.mongodb:mongodb-driver-reactivestreams:4.1.1")
//kafka-protobuf-serializer
implementation("io.confluent:kafka-protobuf-serializer:6.0.0")
runtimeOnly("ch.qos.logback:logback-classic:1.2.3")
runtimeOnly("com.fasterxml.jackson.module:jackson-module-kotlin:2.9.8")
kaptTest("io.micronaut:micronaut-inject-java")
testImplementation enforcedPlatform("io.micronaut:micronaut-bom:$micronautVersion")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.3.0")
testImplementation("io.micronaut.test:micronaut-test-junit5")
testImplementation("org.mockito:mockito-junit-jupiter:2.22.0")
testRuntime("org.junit.jupiter:junit-jupiter-engine:5.3.0")
testRuntime("org.jetbrains.spek:spek-junit-platform-engine:1.1.5")
}
test.classpath += configurations.developmentOnly
mainClassName = "account-control.Application"
test {
useJUnitPlatform()
}
allOpen {
annotation("io.micronaut.aop.Around")
}
compileKotlin {
kotlinOptions {
jvmTarget = '11'
//Will retain parameter names for Java reflection
javaParameters = true
}
}
//compileKotlin.dependsOn(generateProto)
compileTestKotlin {
kotlinOptions {
jvmTarget = '11'
javaParameters = true
}
}
tasks.withType(JavaExec) {
classpath += configurations.developmentOnly
jvmArgs('-XX:TieredStopAtLevel=1', '-Dcom.sun.management.jmxremote')
}
sourceSets {
main {
java {
srcDirs 'build/generated/source/proto/main/grpc'
srcDirs 'build/generated/source/proto/main/grpckt'
srcDirs 'build/generated/source/proto/main/java'
}
}
}
protobuf {
protoc { artifact = "com.google.protobuf:protoc:${protocVersion}" }
plugins {
grpc { artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}" }
grpckt { artifact = "io.grpc:protoc-gen-grpc-kotlin:${grpcKotlinVersion}" }
}
generateProtoTasks {
all()*.plugins {
grpc {}
grpckt {}
}
}
}
*** first edition
Execution failed for task ':extractIncludeProto'.
> Could not resolve all files for configuration ':compileProtoPath'.
> Could not resolve com.squareup.wire:wire-schema:3.2.2.
Required by:
project : > io.confluent:kafka-protobuf-serializer:6.0.0 > io.confluent:kafka-protobuf-provider:6.0.0
> The consumer was configured to find a component, preferably only the resources files. However we cannot choose between the following variants of com.squareup.wire:wire-schema:3.2.2:
- jvm-api
- jvm-runtime
- metadata-api
All of them match the consumer attributes:
- Variant 'jvm-api' capability com.squareup.wire:wire-schema:3.2.2 declares a component, packaged as a jar:
- Unmatched attributes:
- Provides release status but the consumer didn't ask for it
- Provides an API but the consumer didn't ask for it
- Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm' but the consumer didn't ask for it
- Variant 'jvm-runtime' capability com.squareup.wire:wire-schema:3.2.2 declares a component, packaged as a jar:
- Unmatched attributes:
- Provides release status but the consumer didn't ask for it
- Provides a runtime but the consumer didn't ask for it
- Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm' but the consumer didn't ask for it
- Variant 'metadata-api' capability com.squareup.wire:wire-schema:3.2.2:
- Unmatched attributes:
- Doesn't say anything about its elements (required them preferably only the resources files)
- Provides release status but the consumer didn't ask for it
- Provides a usage of 'kotlin-api' but the consumer didn't ask for it
- Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'common' but the consumer didn't ask for it
* Try:
Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':extractIncludeProto'.
at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:38)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
at
...
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
Caused by: org.gradle.internal.resolve.ModuleVersionResolveException: Could not resolve com.squareup.wire:wire-schema:3.2.2.
Required by:
project : > io.confluent:kafka-protobuf-serializer:6.0.0 > io.confluent:kafka-protobuf-provider:6.0.0
Caused by: org.gradle.internal.component.AmbiguousConfigurationSelectionException: The consumer was configured to find a component, preferably only the resources files. However we cannot choose between the following variants of com.squareup.wire:wire-schema:3.2.2:
- jvm-api
- jvm-runtime
- metadata-api
All of them match the consumer attributes:
- Variant 'jvm-api' capability com.squareup.wire:wire-schema:3.2.2 declares a component, packaged as a jar:
- Unmatched attributes:
- Provides release status but the consumer didn't ask for it
- Provides an API but the consumer didn't ask for it
- Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm' but the consumer didn't ask for it
- Variant 'jvm-runtime' capability com.squareup.wire:wire-schema:3.2.2 declares a component, packaged as a jar:
- Unmatched attributes:
- Provides release status but the consumer didn't ask for it
- Provides a runtime but the consumer didn't ask for it
- Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm' but the consumer didn't ask for it
- Variant 'metadata-api' capability com.squareup.wire:wire-schema:3.2.2:
- Unmatched attributes:
- Doesn't say anything about its elements (required them preferably only the resources files)
- Provides release status but the consumer didn't ask for it
- Provides a usage of 'kotlin-api' but the consumer didn't ask for it
- Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'common' but the consumer didn't ask for it
at org.gradle.internal.component.model.AttributeConfigurationSelector.selectConfigurationUsingAttributeMatching(AttributeConfigurationSelector.java:105)
at org.gradle.internal.component.model.AttributeConfigurationSelector.selectConfigurationUsingAttributeMatching(AttributeConfigurationSelector.java:108)
at org.gradle.internal.component.model.AttributeConfigurationSelector.selectConfigurationUsingAttributeMatching(AttributeConfigurationSelector.java:51)
at org.gradle.internal.component.external.model.ConfigurationBoundExternalDependencyMetadata.selectConfigurations(ConfigurationBoundExternalDependencyMetadata.java:98)
at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.builder.EdgeState.calculateTargetConfigurations(EdgeState.java:253)
at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.builder.EdgeState.attachToTargetConfigurations(EdgeState.java:153)
at ...org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
When using mvnrepository.com, take note of which repository the module is available in as you only have JCenter configured for your build (which is usually fine, just not in this case). Here the dependency is in the Confluent repository:
So you will need to add this repository to your build:
repositories {
mavenLocal()
jcenter()
maven { url "https://packages.confluent.io/maven/" }
}
I'm want to obtain other plugin version from my own plugin. I can't find a way to do that via PluginContainer nor PluginManager.
For example for build.gradle.kts:
plugins {
id("some.plugin") version "1.2.3"
id("my.plugin") version "3.4.5"
}
From the code of "my.plugin" I would like to read that "some.plugin" is in version "1.2.3".
If you want to access other plugins versions you could do something like:
plugins {
id("base")
id("org.hidetake.ssh") version "2.10.1"
id("com.jfrog.artifactory") version "4.29.2"
}
apply plugin: MyPlugin
class MyPlugin implements Plugin<Project> {
#Override
void apply(Project target) {
// retrieve plugins dependencies from buildscript classpath
DependencySet pluginDependencies = target.buildscript.configurations.getByName("classpath").allDependencies
// use the found plugins dependencies
pluginDependencies.forEach { Dependency classpathDep ->
println(" Plugin dependency found: $classpathDep.name, version=$classpathDep.version")
}
}
}
This will prompt:
> Configure project :
Plugin dependency found: org.hidetake.ssh.gradle.plugin, version=2.10.1
Plugin dependency found: com.jfrog.artifactory.gradle.plugin, version=4.29.2
> Task :prepareKotlinBuildScriptModel UP-TO-DATE
BUILD SUCCESSFUL in 434ms
nop ... still 2022 this is a 🚧
even google ships tons of lines on it
even your api() declaration (with version range)
nor can I see that dependency constraints will help us
in combination
like
class YourPlugin : Plugin<Project> {
override fun apply(project: Project) {
project
.buildscript.dependencies.constraints
.add("classpath", "com.example:other-plugin") {
it.version {
it.require("[1.0, 2.0)")
}
}
}
}
because you can't add constraints in this gradle phase
ending with
> Cannot change dependencies of dependency configuration ':app:classpath' after it has been resolved.
tldr;
so I don't see anything else than
iterate all project build dependencies checking for version
await depending plugin provides a version
https://docs.gradle.org/current/userguide/toolchains.html is JVM specific and even not addresses this aspect
btw, I was not successful when trying to use the version constraints for comparison
if (project.pluginManager.hasPlugin("com.example.other") == false) {
throw DependencyVerificationException("This plugin needs com.example.other")
}
project
.buildscript
.configurations
.getByName("classpath")
.withDependencies {
it.find {
it.group == "com.example" &&
it.name == "other-plugin"
}
?.version
?.let {
if (DefaultImmutableVersionConstraint.of("1.0") /*no clue how to compare with*/ == it)
else throw DependencyVerificationException("This plugin needs com.example.other at least with version 1.0")
} ?: throw DependencyVerificationException("This plugin needs com.example.other")
}
btw. because it is related: for testing different versions there are indeed some things out there like https://github.com/ajoberstar/gradle-stutter
I'm using the new Play Framework support in Gradle 2.7.
Ironically, Play 2.3.x explicitly depends on org.scala-sbt:io:0.13.8.
Gradle is able to resolve the JAR (not the sources, just the classes) from typesafe's repository if I add
model {
components {
play {
platform play: "2.3.7", scala: "2.10", java: "1.7"
}
}
}
repositories {
maven {
name "typesafe-maven-release"
url "https://repo.typesafe.com/typesafe/maven-releases"
}
ivy {
name "typesafe-ivy-release"
url "https://repo.typesafe.com/typesafe/ivy-releases"
layout "ivy"
}
}
dependencies {
play group: "org.scala-sbt", name: "io", version: "0.13.8", classifier: "jar", configuration: "compile"
}
however it seems that it cannot resolve the io-sources.jar. I get this:
FAILURE: Build failed with an exception.
What went wrong:
Execution failed for task ':runPlayBinary'.
Could not find io-sources.jar (org.scala-sbt:io:0.13.8).
Searched in the following locations:
https://repo.typesafe.com/typesafe/ivy-releases/org.scala-sbt/io/0.13.8/srcs/io.jar
I actually don't care about these sources, I just want to avoid this runtime exception when running gradlew runPlay
Execution exception
[RuntimeException: java.lang.NoClassDefFoundError: sbt/Path$]
Any advice? I can't seem to figure out how to exclude or resolve the sources dependency.
I ran into the same RuntimeException (NoClassDefFound sbt/Path$) with Play 2.4 and Gradle 2.7. In my case the root problem was to not define all repositories correctly (didn't include typesafe-ivy -> sbt-io was not resolved -> thought i need to state sbt-io-dependency -> wrong sbt-io led to mentioned Exception...).
I would advise you to add jcenter() as repository, remove the explicit dependency on sbt and state the play version in your build.gradle. As an example my working gradle.build:
plugins {
id 'play'
}
dependencies {
repositories {
jcenter()
maven {
name "typesafe-maven-release"
url "https://repo.typesafe.com/typesafe/maven-releases"
}
ivy {
name "typesafe-ivy-release"
url "https://repo.typesafe.com/typesafe/ivy-releases"
layout "ivy"
}
}
play 'com.typesafe.play:play-jdbc_2.11:2.4.3'
[...other dependencies - but not "org.scala-sbt"!]
}
model {
components {
play {
platform play: '2.4.3', scala: '2.11'
injectedRoutesGenerator = true
}
}
}
In your case the last part should be:
model {
components {
play {
platform play: '2.3.7', scala: '2.10'
}
}
}
A kind Gradle dev answered my question on the Gradle forums
TL;DR - Gradle/Play bug specific to 2.3.7 that can be resolved by using
repositories {
ivy {
url "https://repo.typesafe.com/typesafe/ivy-releases/"
layout "pattern", {
ivy "[organisation]/[module]/[revision]/ivys/ivy.xml"
artifact "[organisation]/[module]/[revision]/jars/[artifact].[ext]"
}
}
}
In my case, upgrading to Play 2.3.9 fixed my problem.
Set Up
I'm using Gradle and have a multi-project build using Java EE with IBM WebSphere Application Server. The project directory structure looks like this:
--/build.gradle
--/defaults.gradle
--/settings.gradle
--/common-ejb
--/common-ejb/build.gradle
--/logging
--/logging/build.gradle
--/project1
--/project1/build.gradle
--/project1-ejb
--/project1-ejb/build.gradle
--/project2
--/project2/build.gradle
--/project2-ejb
--/project2-ejb/build.gradle
project1 and project2 are individual ears that get deployed. They both reuse a number of EJBs from common-ejb and share some other library dependencies that aren't relevant for this question.
After performing the build: project1.ear looks like:
--/lib/log4j.jar
--/lib/logging.jar
--/META-INF/application.xml
--/META-INF/MANIFEST.MF
--/common-ejb.jar
--/project1-ejb.jar
Gradle properly creates the application.xml to load EJBs from both projects. Unfortunately, project1-ejb.jar will fail to load due to dependencies on common-ejb.jar. The project1-ejb.jar/META-INF/MANIFEST.MF needs to have the Class-Path set with common-ejb.jar since it's not in the lib/ directory.
I was able to set it by explicitly defining it as done below. Gradle knows the dependencies for the Class-Path, so it should be able do this automatically. Is there a way to set this up?
Gradle Files
Not including project2, but you can guess what it looks like.
--/build.gradle
apply from: 'defaults.gradle'
defaultTasks 'clean', 'build'
--/defaults.gradle
defaultTasks 'build'
repositories {
mavenCentral()
}
--/settings.gradle
include 'common-ejb'
include 'project1'
include 'project1-ejb'
include 'logging'
--/logging/build.gradle
apply from: '../defaults.gradle'
apply plugin: 'java'
dependencies {
compile 'log4j:log4j:1.2.+'
}
--/common-ejb/build.gradle
apply from: '../defaults.gradle'
apply plugin: 'java'
dependencies {
compile 'javax:javaee-api:6.0'
compile project(':logging')
}
--/project1-ejb/build.gradle
apply from: '../defaults.gradle'
apply plugin: 'java'
dependencies {
compile 'javax:javaee-api:6.0'
compile project(':common-ejb')
compile project(':logging')
}
// THIS IS THE WORKAROUND, I don't want to explicitly modify the Class-Path for each EJB based on the EAR the EJB is going to be included in.
jar {
manifest {
attributes("Class-Path": project(':common-ejb').jar.archiveName)
}
}
--/project1/build.gradle
apply from: '../defaults.gradle'
apply plugin: 'ear'
apply plugin: 'java'
dependencies {
deploy project(':project1-ejb')
deploy project(':common-ejb')
earlib project(':logging')
}
Using some information from and modifying code from a question about getting all dependencies of a project from the Gradle forums.
Essentially, you want to take the EAR's deploy dependencies and see if any deploy dependencies depend on each other. If they do, you set the Class-Path to include the referenced jars.
Remove the manifest lines from project1-ejb and project2-ejb. Add the following to your defaults.gradle:
def getAllDependentProjects(project) {
if ( !project.configurations.hasProperty("runtime") ) {
return []
}
def projectDependencies = project.configurations.runtime.getAllDependencies().withType(ProjectDependency)
def dependentProjects = projectDependencies*.dependencyProject
if (dependentProjects.size > 0) {
dependentProjects.each { dependentProjects += getAllDependentProjects(it) }
}
return dependentProjects.unique()
}
gradle.projectsEvaluated {
if (plugins.hasPlugin('ear')) {
def deployProjectDependencies = configurations.deploy.getAllDependencies().withType(ProjectDependency)*.dependencyProject
deployProjectDependencies.each {
def cur = it
def cur_deps = getAllDependentProjects(cur)
def depJars = []
deployProjectDependencies.each {
def search = it
if ( cur_deps.contains(search)) {
depJars += search.jar.archiveName
}
}
depJars = depJars.unique()
if ( depJars.size() > 0 ) {
logger.info("META-INF Dependencies for deploy dependency " + cur.name + ": " + depJars)
cur.jar.manifest.attributes(
'Class-Path': depJars.join(' ')
)
}
}
}
}
This will have the desired affect. Directly after the configuration step and before build, the EAR projects will reevaluate their dependencies to see if any are cross-referenced. There may be a more efficient way, but this gets the job done.