I'm doing a project with Jetpack Compose Multiplatform Desktop.
I'm not very familiar with Gradle, and I would like to use Material 3 in my project.
So, I added this line in build.gradle.kts file:
implementation("androidx.compose.material3:material3:1.0.0-alpha14")
But when I try to import the lib in a Kotlin file with:
import androidx.compose.material3.*
I've got an unresolved reference issue.
This is my build.gradle.kts file:
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
plugins {
kotlin("multiplatform")
id("org.jetbrains.compose")
}
group = "com.example"
version = "1.0-SNAPSHOT"
repositories {
google()
mavenCentral()
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
}
kotlin {
jvm {
compilations.all {
kotlinOptions {
jvmTarget = "18"
freeCompilerArgs = listOf("-opt-in=kotlin.RequiresOptIn")
}
}
withJava()
}
sourceSets {
val jvmMain by getting {
dependencies {
implementation(compose.desktop.currentOs)
implementation("androidx.compose.material3:material3:1.0.0-alpha14")
}
}
val jvmTest by getting
}
}
compose.desktop {
application {
mainClass = "MainKt"
jvmArgs += listOf("-Djava.library.path=./lib")
nativeDistributions {
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
packageName = "FanControl"
packageVersion = "1.0.0"
}
}
}
I think I should be able to use this lib since the release note indicate it support it.
Edit1:
I have this message from Gradle when I try to sync:
Could not resolve: androidx.compose.material3:material3:1.0.0-alpha14
Finally found what was the problem, it was the wrong library,
change
implementation("androidx.compose.material3:material3:1.0.0-alpha14")
with
implementation("org.jetbrains.compose.material3:material3-desktop:1.2.1")
Related
I'm using gradle 7-4-1 and I'm trying to use a catalog to share dependencies between subprojects as documentation
https://docs.gradle.org/current/userguide/platforms.html#sec:sharing-catalogs
This is my settings.gradle.kts
dependencyResolutionManagement {
versionCatalogs {
create("libs") {
version("log4j", "2.17.1")
library("log4j-api", "org.apache.logging.log4j", "log4j-api").versionRef("log4j")
library("log4j-core", "org.apache.logging.log4j", "log4j-core").versionRef("log4j")
library("log4j-slf4j-impl", "org.apache.logging.log4j", "log4j-slf4j-impl").versionRef("log4j")
bundle("log4j", listOf("log4j-api", "log4j-core", "log4j-slf4j-impl"))
}
}
}
rootProject.name = "gawds-db"
include("db-server", "db-client", "db-common")
enableFeaturePreview("VERSION_CATALOGS")
And I'm trying to import into my build.gradle.kts (located in my subproject)
plugins {
`maven-publish`
application
`java-library`
}
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(11))
}
}
repositories {
mavenCentral()
}
configure<JavaApplication> {
mainClass.set("com.gawds.db.MainApp")
}
tasks.compileJava {
options.isIncremental = true
options.isFork = true
options.isFailOnError = false
}
tasks.named<Test>("test") {
useJUnitPlatform()
}
dependencies {
implementation(libs.log4j.api)
implementation(libs.log4j.core)
implementation(libs.log4j.log4j.slf4j.impl)
}
Note: also tried
implementation(libs.bundles.log4j)
But neither referencing libs.alias nor libs.bundles.alias-bundle work.
My project structure is:
/
| settings.gradle.kts
| db-server /
| build.gradle.kts
Just in case helps someone else. First, not sure why intellij marks as red, however from cmd line looks like it works.
From settings.gradle.kts get rid of
enableFeaturePreview("VERSION_CATALOGS")
This was required in previous versions but not in gradle 7.4.x
Also u need to add the repos in the catalog section, see below:
dependencyResolutionManagement {
repositories {
mavenCentral()
}
versionCatalogs {
create("libs") {
version("log4jVersion", "2.17.1")
library("log4j-api", "org.apache.logging.log4j", "log4j-api").versionRef("log4jVersion")
library("log4j-core", "org.apache.logging.log4j", "log4j-core").versionRef("log4jVersion")
library("log4j-slf4j-impl", "org.apache.logging.log4j", "log4j-slf4j-impl").versionRef("log4jVersion")
bundle("log4j", listOf("log4j-api", "log4j-core", "log4j-slf4j-impl"))
}
}
}
rootProject.name = "gawds-db"
include("db-server", "db-client", "db-common")
Another important point that I did wrong in my tests are:
Assuming this alias:
log4j-slf4j-impl
the typesafe equivalent is
log4j.slf4j.impl
so we need to call in the build.gradle.kts:
implementation(libs.log4j.slf4j.impl)
Also u can print the alias to check the name using:
val versionCatalog = extensions.getByType<VersionCatalogsExtension>().named("libs")
println("${versionCatalog.libraryAliases}")
To improve the previous code, we can create a task to print the catalog alias:
abstract class PrintCatalogAlias #Inject constructor(private val r : Project) : DefaultTask() {
#org.gradle.api.tasks.TaskAction
fun catalogAlias() {
val versionCatalog = r.rootProject.project.extensions.getByType<VersionCatalogsExtension>().named("libs")
println("${versionCatalog.libraryAliases}")
}
}
tasks.register<PrintCatalogAlias>("catalog")
I have the following build.gradle.kts
plugins {
id("com.mkobit.jenkins.pipelines.shared-library") version "0.10.1"
id("com.github.ben-manes.versions") version "0.21.0"
java
}
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
tasks.withType<Test> {
this.testLogging {
this.showStandardStreams = true
}
}
val log4jVersion = "2.11.2"
val slf4jVersion = "1.7.26"
val declarativePluginsVersion = "1.3.9"
dependencies {
// logging stuffs
testImplementation("org.slf4j:slf4j-api:$slf4jVersion")
testImplementation("org.apache.logging.log4j:log4j-api:$log4jVersion")
testImplementation("org.apache.logging.log4j:log4j-core:$log4jVersion")
testImplementation("org.apache.logging.log4j:log4j-slf4j-impl:$log4jVersion")
testImplementation("org.apache.logging.log4j:log4j-jul:$log4jVersion")
// general testing stuff
testImplementation("org.assertj:assertj-core:3.12.2")
testImplementation("com.lesfurets:jenkins-pipeline-unit:1.3")
testImplementation("junit:junit:4.12") // TODO: update to 5
// jenkins specific deps
testImplementation("org.jenkins-ci.plugins:pipeline-build-step:2.9")
testImplementation("org.jenkinsci.plugins:pipeline-model-api:$declarativePluginsVersion")
testImplementation("org.jenkinsci.plugins:pipeline-model-declarative-agent:1.1.1")
testImplementation("org.jenkinsci.plugins:pipeline-model-definition:$declarativePluginsVersion")
testImplementation("org.jenkinsci.plugins:pipeline-model-extensions:$declarativePluginsVersion")
testImplementation("org.jenkins-ci.plugins.workflow:workflow-cps-global-lib:2.8")
testImplementation("org.jenkins-ci.plugins.workflow:workflow-step-api:2.18")
}
jenkinsIntegration {
baseUrl.set(uri("http://localhost:5050").toURL())
authentication.set(providers.provider { com.mkobit.jenkins.pipelines.http.AnonymousAuthentication })
downloadDirectory.set(layout.projectDirectory.dir("jenkinsResources"))
}
sharedLibrary {
coreVersion.set(jenkinsIntegration.downloadDirectory.file("core-version.txt").map { it.asFile.readText().trim() })
pluginDependencies {
dependency("org.jenkins-ci.plugins", "pipeline-build-step", "2.9")
dependency("org.jenkinsci.plugins", "pipeline-model-api", declarativePluginsVersion)
dependency("org.jenkinsci.plugins", "pipeline-model-declarative-agent", "1.1.1")
dependency("org.jenkinsci.plugins", "pipeline-model-definition", declarativePluginsVersion)
dependency("org.jenkinsci.plugins", "pipeline-model-extensions", declarativePluginsVersion)
dependency("org.jenkins-ci.plugins.workflow", "workflow-step-api", "2.18")
}
}
when I do gradlew build
I got the following error on one of my groovy file:
unable to resolve class org.jenkinsci.plugins.workflow.support.steps.build.DownstreamFailureCause
To me the dependency should be solved in the pluginDependencies section.
I found a solution.
It seems that the class I was having a problem with was introduced in version 2.10
So you need to change
org.jenkins-ci.plugins:pipeline-build-step:2.9
to
org.jenkins-ci.plugins:pipeline-build-step:2.10
I have created a Kotlin MPP to share Json utilities between JVM and JS. All the code lies in the common source set and I have configured the necessary targets with their respective dependencies. Without further configuration I'm able to use the utilities from both JVM and JS but not from the common source set of another MPP, which has to do with the way Gradle handles metadata.
I already found the solution (taken from https://medium.com/xorum-io/crafting-and-publishing-kotlin-multiplatform-library-to-bintray-cbc00a4f770)
afterEvaluate {
project.publishing.publications.all {
groupId = group
if (it.name.contains('metadata')) {
artifactId = "$libraryName"
} else {
artifactId = "$libraryName-$name"
}
}
}
and I also got it to work with the Gradle Kotlin DSL:
afterEvaluate {
publishing.publications.all {
this as MavenPublication
artifactId = project.name + "-$name".takeUnless { "metadata" in name }.orEmpty()
}
}
However, this doesn't feel quite right yet.
There is no such code snippet in the official documentation.
The documentation advertises that a single dependency from the common source set should suffice to automatically resolve target specific dependencies: https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html#metadata-publishing. I had to add the dependency for each target, respectively, for it to work.
this as MavenPublication is necessary because Publication has no field artifactId.
I use project.name instead of libraryName.
Is this even remotely the right way to do things or am I missing some other option which would make the whole process trivial?
Right now I'm using Kotlin 1.3.72 and Gradle 5.2.1 with enableFeaturePreview("GRADLE_METADATA") in settings.gradle.kts. I also tried it with Gradle 6.5.1 (latest) but it behaves exactly the same.
For now I'm glad that it's working at all but I suspect there is a cleaner way to do this. I'd really appreciate if someone with a bit more Gradle expertise could clear things up for me or point me into the right direction.
Edit:
gradle.build.kts for completeness. Although there isn't much going on here.
group = "org.example"
version = "1.0-SNAPSHOT"
plugins {
kotlin("multiplatform") version "1.3.72"
`maven-publish`
}
repositories {
mavenCentral()
}
kotlin {
jvm()
sourceSets {
val commonMain by getting {
dependencies {
implementation(kotlin("stdlib-common"))
}
}
val jvmMain by getting {
dependencies {
implementation(kotlin("stdlib"))
}
}
}
}
There wasn't really a problem after all. The solution is to simply add enableFeaturePreview("GRADLE_METADATA") to the consuming project too.
According to https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html#metadata-publishing this shouldn't be necessary:
In earlier Gradle versions starting from 5.3, the module metadata is
used during dependency resolution, but publications don't include any
module metadata by default. To enable module metadata publishing, add
enableFeaturePreview("GRADLE_METADATA") to the root project's
settings.gradle file.
Weirdly it only works when both publishing project and consuming project have metadata enabled, even when both use the latest Gradle version.
enableFeaturePreview("GRADLE_METADATA") is enabled by default in latest gradle.
According to this you need to substitute "kotlinMultiplatform" by "" an empty string.
I finally managed to accomplish publishing to bintray with maven-publish plugin only, without outdated bintray library.
Here is my full maven.publish.gradle.kts:
import java.io.FileInputStream
import java.util.*
import org.gradle.api.publish.PublishingExtension
apply(plugin = "maven-publish")
val fis = FileInputStream("local.properties")
val properties = Properties().apply {
load(fis)
}
val bintrayUser = properties.getProperty("bintray.user")
val bintrayApiKey = properties.getProperty("bintray.apikey")
val bintrayPassword = properties.getProperty("bintray.gpg.password")
val libraryVersion: String by project
val publishedGroupId: String by project
val artifact: String by project
val bintrayRepo: String by project
val libraryName: String by project
val bintrayName: String by project
val libraryDescription: String by project
val siteUrl: String by project
val gitUrl: String by project
val licenseName: String by project
val licenseUrl: String by project
val developerOrg: String by project
val developerName: String by project
val developerEmail: String by project
val developerId: String by project
project.group = publishedGroupId
project.version = libraryVersion
afterEvaluate {
configure<PublishingExtension> {
publications.all {
val mavenPublication = this as? MavenPublication
mavenPublication?.artifactId =
"${project.name}${"-$name".takeUnless { "kotlinMultiplatform" in name }.orEmpty()}"
}
}
}
configure<PublishingExtension> {
publications {
withType<MavenPublication> {
groupId = publishedGroupId
artifactId = artifact
version = libraryVersion
pom {
name.set(libraryName)
description.set(libraryDescription)
url.set(siteUrl)
licenses {
license {
name.set(licenseName)
url.set(licenseUrl)
}
}
developers {
developer {
id.set(developerId)
name.set(developerName)
email.set(developerEmail)
}
}
organization {
name.set(developerOrg)
}
scm {
connection.set(gitUrl)
developerConnection.set(gitUrl)
url.set(siteUrl)
}
}
}
}
repositories {
maven("https://api.bintray.com/maven/${developerOrg}/${bintrayRepo}/${artifact}/;publish=1") {
credentials {
username = bintrayUser
password = bintrayApiKey
}
}
}
}
And build.gradle.kts:
plugins {
id("kotlin-multiplatform")
}
kotlin {
sourceSets {
jvm()
js() {
browser()
nodejs()
}
linuxX64()
linuxArm64()
mingwX64()
macosX64()
iosArm64()
iosX64()
val commonMain by getting {
dependencies {
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
val jsMain by getting {
dependencies {
}
}
val jsTest by getting {
dependencies {
implementation(kotlin("test-js"))
}
}
val jvmMain by getting {
dependencies {
}
}
val jvmTest by getting {
dependencies {
implementation(kotlin("test"))
implementation(kotlin("test-junit"))
}
}
val nativeMain by creating {
dependsOn(commonMain)
dependencies {
}
}
val linuxX64Main by getting {
dependsOn(nativeMain)
}
val linuxArm64Main by getting {
dependsOn(nativeMain)
}
val mingwX64Main by getting {
dependsOn(nativeMain)
}
val macosX64Main by getting {
dependsOn(nativeMain)
}
val iosArm64Main by getting {
dependsOn(nativeMain)
}
val iosX64Main by getting {
dependsOn(nativeMain)
}
}
}
apply(from = "maven.publish.gradle.kts")
Please note, there are bintray.user and bintray.apikey properties in local.properties file.
Also gradle.properties contains rest listed properties above:
libraryVersion = 0.5.22
libraryName = MultiplatformCommon
libraryDescription = Kotlin multiplatform extensions
publishedGroupId = com.olekdia
artifact = multiplatform-common
bintrayRepo = olekdia
bintrayName = multiplatform-common
siteUrl = https://gitlab.com/olekdia/common/libraries/multiplatform-common
gitUrl = https://gitlab.com/olekdia/common/libraries/multiplatform-common.git
.........
kotlin.mpp.enableGranularSourceSetsMetadata = true
systemProp.org.gradle.internal.publish.checksums.insecure = true
If you haven't created organisation in bintray you need to change in this url:
https://api.bintray.com/maven/${developerOrg}/${bintrayRepo}/${artifact}/;publish=1
developerOrg by bintrayUser, where the last one is your user name at bintray.com
I'm trying to publish my java library to JitPack using the maven-publish plugin in Gradle. I have done all that the docs have said, and JitPack says publishing was a success, but it seems like I cannot install my library, even if I just copy and paste straight from JitPack's repository.
I tried pushing straight to master on the github repo. I also changed the artifact id to sertain-core and the version to 1.0.0, as that is what is specified in the publish block. I even checked the repository url and downloaded the jar manually, and it worked fine. It seems that the only problem is downloading the jar using it's maven coordinates.
Here's my library's build file (the dependencies block is in another file and works fine):
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
val ktlint by configurations.creating
plugins {
kotlin("jvm") version "1.3.50"
`maven-publish`
}
dependencies {
implementation(kotlin("stdlib-jdk8"))
implementation(kotlin("reflect", "1.3.50"))
implementation("org.jetbrains.kotlinx", "kotlinx-coroutines-core", "1.3.1")
implementation("org.jetbrains.kotlin", "kotlin-reflect", "1.3.50")
implementation("edu.wpi.first.wpilibj", "wpilibj-java", "2019.4.1")
implementation("edu.wpi.first.hal", "hal-java", "2019.4.1")
implementation("edu.wpi.first.ntcore", "ntcore-java", "2019.4.1")
implementation("com.ctre.phoenix", "api-java", "5.14.1")
ktlint("com.pinterest:ktlint:0.34.2")
}
tasks {
val ktlint by creating(JavaExec::class) {
group = "verification"
description = "Check Kotlin code style."
classpath = configurations["ktlint"]
main = "com.pinterest.ktlint.Main"
args = listOf("src/**/*.kt")
}
"check" {
dependsOn(ktlint)
}
create("ktlintFormat", JavaExec::class) {
group = "formatting"
description = "Fix Kotlin code style deviations."
classpath = configurations["ktlint"]
main = "com.pinterest.ktlint.Main"
args = listOf("-F", "src/**/*.kt")
}
}
tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "1.8"
kotlinOptions.freeCompilerArgs += setOf("-Xuse-experimental=kotlin.Experimental")
}
publishing {
publications {
create<MavenPublication>("maven") {
groupId = "org.sert2521.sertain"
artifactId = "sertain-core"
version = "1.0.0"
from(components["java"])
artifact("$buildDir/libs/${project.name}.jar")
}
}
}
And here's the build file of the project that should install the library
plugins {
id "org.jetbrains.kotlin.jvm" version "1.3.50"
id "edu.wpi.first.GradleRIO" version "2019.4.1"
}
ext.kotlinVersion = "1.3.50"
tasks.whenTaskAdded { task ->
if (task.name == "deploy" || task.name == "deployMain" || task.name == "simulateJava") task.dependsOn "assemble"
}
repositories {
google()
jcenter()
mavenCentral()
maven { url "https://jitpack.io" }
maven { url "http://first.wpi.edu/FRC/roborio/maven/release" }
maven { url "http://devsite.ctr-electronics.com/maven/release" }
maven { url "https://www.kauailabs.com/maven2" }
maven { url "http://www.revrobotics.com/content/sw/max/sdk/maven/" }
maven { url 'https://jitpack.io' }
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion"
compile "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.1"
compile "com.kauailabs.navx.frc:navx-java:3.1.344"
compile "org.jetbrains.kotlin:kotlin-reflect:1.3.50"
compile wpi.deps.wpilib()
compile wpi.deps.vendor.java()
nativeZip wpi.deps.vendor.jni(wpi.platforms.roborio)
nativeDesktopZip wpi.deps.vendor.jni(wpi.platforms.desktop)
implementation 'com.github.SouthEugeneRoboticsTeam:sertain:publishing-f3bdecc967-1'
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
deploy {
targets {
roboRIO("roborio") {
team = frc.getTeamOrDefault(2521)
}
}
artifacts {
frcJavaArtifact("frcJava") {
targets << "roborio"
debug = frc.getDebugOrDefault(false)
}
fileTreeArtifact("frcStaticFileDeploy") {
files = fileTree(dir: "src/main/deploy")
targets << "roborio"
directory = "/home/lvuser/deploy"
}
}
}
jar {
from configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
manifest {
attributes(
"Main-Class": "org.sert2521.example.MainKt"
)
}
}
wrapper {
gradleVersion = "5.0"
}
There are no error messages when publishing the library. When installing the library, there is only the usual error from gradle not being able to find a dependency.
I've been writing Gradle plugins in several languages using their usual Groovy build script DSL for some time. As of recently I wanted to learn how to use their Kotlin build script DSL but I can't quite figured out some things.
I have an example below:
val kotlin_version = "1.2.41"
plugins {
application
kotlin("jvm").version(kotlin_version)
}
application {
mainClassName = "samples.HelloWorldKt"
}
dependencies {
compile(kotlin("stdlib"))
}
repositories {
jcenter()
}
However, when I run a simple task like 'clean', I get the following error:
* What went wrong:
Script compilation error:
Line 5: kotlin("jvm") version kotlin_version
^ Unresolved reference: kotlin_version
However, if I replace kotlin_version with a string literal, it works fine:
val kotlin_version = "1.2.41"
plugins {
application
// kotlin("jvm").version(kotlin_version)
kotlin("jvm").version("1.2.41")
}
application {
mainClassName = "samples.HelloWorldKt"
}
dependencies {
compile(kotlin("stdlib"))
}
repositories {
jcenter()
}
However, if I parameterize the dependencies block with my kotlin_version, it works perfectly fine:
dependencies {
compile(kotlin("stdlib", kotlin_version))
}
Why can't variables be referenced inside of the plugins block?
See documentation: https://docs.gradle.org/current/userguide/plugins.html#sec:constrained_syntax
Basically, it states that plugin version must be constant, literal, string.
It is achieved by DslMaker: https://kotlinlang.org/docs/reference/type-safe-builders.html#scope-control-dslmarker-since-11
If you want to reuse variable elsewhere, you could use this:
buildscript {
var kotlinVersion: String by extra { "1.2.41" }
repositories {
jcenter()
}
dependencies {
classpath(kotlin("gradle-plugin", kotlinVersion))
}
}
plugins {
application
}
application {
mainClassName = "samples.HelloWorldKt"
}
apply {
plugin("kotlin")
plugin("application")
}
val kotlinVersion: String by extra
repositories {
jcenter()
}
dependencies {
compile(kotlin("stdlib-jdk8", kotlinVersion))
}
tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "1.8"
}
If you don't need that, you can simply inline content of variable kotlin_version