Can't configure properties-file in gradle - gradle

So I'm trying to access a token key in my Kotlin code, but it won't let me import BuildConfig.
In my main() I have:
val client: DiscordClient = DiscordClientBuilder(BuildConfig.TOKEN_KEY).build()
BuildConfig is red in IntelliJ.
My build.gradle is as follows:
defaultConfig {
buildConfigField("String", "TOKEN_KEY", apikeyProperties['TOKEN_KEY'])
}
Everywhere I look I see stackoverflow posts where they want defaultConfig to be in android {}, but I'm not making an Android app.
My token key is in a file called apikey.properties in root which has been added to .gitignore.
Content of the file:
TOKEN_KEY="token_value"

BuildConfig is a class generated by the Android Gradle plugin, hence it's not part of the Gradle's standard featrue set.
At build time, Gradle generates the BuildConfig class so your app code can inspect information about the current build.
(From: Share custom fields and resource values with your app's code)
Since you're not using Android plugin the class doesn't get generated and is red in IJ.
You have the following options:
Deploy the properties file with your source code and read it accordingly during runtime
Have a look at this answer to the question Generate a Java class using Gradle for Java plugin. It mentions the alternative gradle-buildconfig-plugin for non-Android projects.

Related

How can I access the dependencies of an application from within the build file of a dependency embedded in the application?

I have a Gradle-based library that is imported as a dependency into consuming applications. In other words, an application that consumes my library will have a build.gradle file with a list of dependencies that includes both my library as well as any other dependencies they wish to import.
From within my library's build.gradle file, I need to write a Gradle task that can access the full set of dependencies declared by the consuming application. In theory, this should be pretty straightforward, but hours of searching has not yielded a working solution yet.
The closest I've come is to follow this example and define an additional task in the library's build.gradle file that runs after the library is built:
build {
doLast {
project.getConfigurations().getByName('runtime')
.resolvedConfiguration
.firstLevelModuleDependencies
.each { println(it.name) }
}
}
I keep getting an error message that the 'runtime' configuration (passed into getByName and referenced in the Gradle forum post I linked) cannot be found. I have tried other common Gradle configurations that I can think of, but I never get any dependencies back from this code.
So: what is the best way to access the full set of dependencies declared by a consuming application from within the build file of one of those dependencies?
Okay, I mostly figured it out. The code snippet is essentially correct, but the configuration I should have been accessing was 'compileClasspath' or 'runtimeClasspath', not 'runtime'. This page helped me understand the configuration I was looking for.
The final build task in the library looks roughly like this:
build {
doLast {
// ...
def deps = project.getConfigurations().getByName('compileClasspath')
.resolvedConfiguration
.firstLevelModuleDependencies
.each {
// it.name will give you the dependency in the standard Gradle format (e.g."org.springframework.boot:spring-boot:1.5.22.RELEASE")
}
}
}

Adding gradle dependencies

I have a simple gradle 7.2 project, with a simple kotlin file, running java 11, on ubuntu 20.04 in vs code
For my project, I need to add some simple dependencies to java.security such that I'll be able to encrypt and hash some things.
So I need to add it as a dependency.
The project is created by running gradle init and picking all the default options.
I then want to be able to do an import like: import java.security.MessageDigest and use the java.security package.
I guess I'll have to add the dependency in the build file, which currently looks like this:
plugins {
// Apply the org.jetbrains.kotlin.jvm Plugin to add support for Kotlin.
id("org.jetbrains.kotlin.jvm") version "1.5.0"
// Apply the application plugin to add support for building a CLI application in Java.
application
}
repositories {
// Use Maven Central for resolving dependencies.
mavenCentral()
}
dependencies {
// Align versions of all Kotlin components
implementation(platform("org.jetbrains.kotlin:kotlin-bom"))
// Use the Kotlin JDK 8 standard library.
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
// This dependency is used by the application.
implementation("com.google.guava:guava:30.1.1-jre")
// Use the Kotlin test library.
testImplementation("org.jetbrains.kotlin:kotlin-test")
// Use the Kotlin JUnit integration.
testImplementation("org.jetbrains.kotlin:kotlin-test-junit")
}
application {
// Define the main class for the application.
mainClass.set("com.what.isthis.AppKt")
}
I now search google high and low for how a reference to the java.security package can be added in gradle, but find absolutely nothing anywhere.
Following a guide like this it looks like I could just add a in this manner:
implementation 'org.springframework.boot:spring-boot-starter-validation:2.4.0'
If what I wanted was a reference to this validation library. But I can never get to test it, because I can't find any info on how I would target java.security anywhere.
Looking at the docsI tried to just grab the names I could find here, but this did not compile:
implementation 'java.security Package'
So yes, how do I get thjis dependency. And in general how do find the names that I need for getting dependencies in general?
java.security package is part of the Java language itself as you can see from the documentation, for this reason you don't need to include it explicitly it should already be available to you.
Please make sure you have proper Java SDK set up in IDE. Try to configure different distribution/type than you use currently.
Even if you have logic in Kotlin class it should properly resolve an import and compile.
import java.security.MessageDigest
fun main() {
val test = MessageDigest.getInstance("SHA-256")
println("Test Succeeded")
}
You're not finding examples of declaring java.security packages in Gradle because you don't need to declare them; they're included in the JDK so you can import them natively in any class without declaring them in gradle. Try creating this class in any given package within your project and running it. It should succeed.
import java.security.MessageDigest;
public class Test {
public static void main(String[] args) throws Exception {
MessageDigest test = MessageDigest.getInstance("SHA-256");
System.out.println("Test Succeeded");
}
}

Adding a `.klib` library to kotlin multiplatform

I'm wondering how I'd be able to import my cinterop-ted library to gradle build of the kotlin multiplatform build.
I've already created the library.def file and filled it, I also generated the library.klib and the folder that goes with it.
I just don't understand how to import it into gradle.
I've looked all over internet and I found a reference to Konan and I'm wondering if that's something I have to use, or if that's something being used for something similar to 'cinterop'.
I've looked over the following links, and I haven't found anything remotely connected to the .klib import part of my question.
Link #1 (kotlinlang.org)
Link #2 (github.com)
Link #3 (plugins.gradle.org)
In general, you'll want to use the multiplatform plugin. If you're building a klib separately, you're creating some extra steps (probably). In Link #2 it says that platform plugin is deprecated. Konan is the name of the native platform/compiler. There was a separate plugin for that last year, but you definitely don't want to be using that.
I just created an example but it's not public yet, so this is the best one I have off hand:
https://github.com/JetBrains/kotlin-native/blob/3329f74c27b683574ac181bc40e3836ceccce6c1/samples/tensorflow/build.gradle.kts#L12
I'm working on a Firestore library. The native and interop config live in the multiplatform config.
kotlin {
android {
publishAllLibraryVariants()
}
// iosArm64()
iosX64("ios"){
compilations["main"].cinterops {
firebasecore {
packageName 'cocoapods.FirebaseCore'
defFile = file("$projectDir/src/iosMain/c_interop/FirebaseCore.def")
includeDirs ("$projectDir/../iosApp/Pods/FirebaseCore/Firebase/Core/Public")
compilerOpts ("-F$projectDir/src/iosMain/c_interop/modules/FirebaseCore-${versions.firebaseCoreIos}")
}
firestore {
packageName 'cocoapods.FirebaseFirestore'
defFile = file("$projectDir/src/iosMain/c_interop/FirebaseFirestore.def")
includeDirs ("$projectDir/../iosApp/Pods/FirebaseFirestore/Firestore/Source/Public", "$projectDir/../iosApp/Pods/FirebaseCore/Firebase/Core/Public")
compilerOpts ("-F$projectDir/src/iosMain/c_interop/modules/FirebaseFirestore-${versions.firebaseFirestoreIos}")
}
}
}
}
The cinterops sets up where the def files are and params. I then publish that whole thing as a multiplatform library. The actual native artifact is a klib ultimately, but it's all managed with gradle and dependency metadata.

Using Gradle 5.1 "implementation platform" instead of Spring Dependency Management Plugin

I have written a Gradle Plugin that contains a bunch of common setup configuration so that all of our projects just need to apply that plugin and a set of dependencies. It uses the Spring Dependency Management Plugin to setup the BOM imports for Spring as shown in the code snippet below:
trait ConfigureDependencyManagement {
void configureDependencyManagement(final Project project) {
assert project != null
project.apply(plugin: "io.spring.dependency-management")
final DependencyManagementExtension dependencyManagementExtension = project.extensions.findByType(DependencyManagementExtension)
dependencyManagementExtension.imports {
mavenBom "org.springframework.boot:spring-boot-dependencies:2.1.0.RELEASE"
}
}
}
Whilst that still works in Gradle 5.1 I wanted to replace the Spring Dependency Management Plugin with the new dependency mechanism for BOM Imports so I updated the above to now be this:
trait ConfigureDependencyManagement {
void configureDependencyManagement(final Project project) {
assert project != null
project.dependencies.platform("org.springframework.boot:spring-boot-dependencies:2.1.0.RELEASE")
}
}
Unfortunately that change means none of the dependencies defined by these BOMs are being imported and I get errors like these when building projects?
Could not find org.springframework.boot:spring-boot-starter-web:.
Required by:
project :
Could not find org.springframework.boot:spring-boot-starter-data-jpa:.
Required by:
project :
Could not find org.springframework.boot:spring-boot-starter-security:.
Required by:
project :
Am I correct in thinking the Spring Dependency Management Plugin is no longer needed with Gradle 5.1 and if so then am I missing something for this to work?
The platform support in Gradle 5 can replace the Spring dependency management plugins for BOM consumption. However the Spring plugin offers features that are not covered by the Gradle support.
Regarding your issue, the problem comes from the following line:
project.dependencies.platform("org.springframework.boot:spring-boot-dependencies:2.1.0.RELEASE")
This will simply create a Dependency, it still needs to be added to a configuration. by doing something like:
def platform = project.dependencies.platform("org.springframework.boot:spring-boot-dependencies:2.1.0.RELEASE")
project.dependencies.add("configurationName", platform)
where configurationName is the name of the configuration that requires the BOM. Note that you may have to add this BOM to multiple configurations, depending on your project.

Gradle Kotlin DSL: get sourceSet of another project

Currently, we're trying to migrate our existing build.gradle scripts to the new Kotlin DSL. Right now, we are struggling with the jar task configuration.
Our project is a simple multi-project. Let's say we've Core and Plugin and Plugin uses classes from Core. Now, when building Plugin, the target jar should include any used classes from Core.
This is how it looked like before:
jar {
from sourceSets.main.output
from project(':Core').sourceSets.main.output
}
And this is the current solution we've with Kotlin DSL:
val jar: Jar by tasks
jar.apply {
from(java.sourceSets["main"].allSource)
from(project(":Core").the<SourceSetContainer>()["main"].allSource)
}
However, the above example just gives me an Extension of type 'SourceSetContainer' does not exist. Currently registered extension types: [ExtraPropertiesExtension] error. I've also tried other code snippets I've found, but none of them have been working so far.
I have also tried this (like suggested in the first answer):
val jar: Jar by tasks
jar.apply {
from(java.sourceSets["main"].allSource)
from(project(":Core").sourceSets.getByName("main").allSource)
}
But then the IDE (and also the jar task) argues that sourceSets is not available: Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: public val KotlinJvmProjectExtension.sourceSets: NamedDomainObjectContainer<DefaultKotlinSourceSet> defined in org.gradle.kotlin.dsl.
I hope that someone can help us, because it is very frustrating to spend hours in configuration instead of writing any usefull code.
Thank you very much in advance.
You can access the SourceSetContainer by
project(":Core").extensions.getByType(SourceSetContainer::class)
it seems <T : Any> Project.the(extensionType: KClass<T>): T looks in the convention of the project, while val Project.sourceSets: SourceSetContainer get() looks in the extensions ExtensionContaier instead. This is somewhat odd, as the documentation for the says "Returns the plugin convention or extension of the specified type."
Note that you may need to do your sourceSet manipulation in gradle.projectsEvaluated, because otherwise the sourceSet in question may not be configured yet if the corresponding project is not yet evaluated.
If you get access to the project, then everything should looks like your actual groovy gradle script:
project(":Core").sourceSets.getByName("main").allSource
So regarding your actual code:
val jar: Jar by tasks
jar.apply {
from(java.sourceSets["main"].allSource)
from(project(":Core").sourceSets.getByName("main").allSource)
}

Resources