Unable to add duplicate strategy in gradle - kotlin

Disclaimer: I am new to gradle, so it's likely I'm missing something simple.
Background: I am splitting a service into two services that will live in the same repo. The second service (tester) uses code from the first service (engine), which I have managed to tell gradle. But I have an issue.
Building the tester fails, giving the following error:
Execution failed for task ':engine:processResources'.
Entry application.properties is a duplicate but no duplicate handling strategy has been set
It seems this is a common issue in gradle that someone has already posted about. Unfortunately, pasting each of the responses in my build file has yielded nothing.
I've also tried the kotlin solutions in this thread with similar results: I keep getting the duplicate strategy not set error.
Surely I'm missing something but I can't for the life of me figure out what.
Tester build.gradle.kts Code
plugins {
kotlin("jvm") version "1.5.10"
kotlin("plugin.serialization") version "1.5.30"
id("net.linguica.maven-settings") version "0.5"
}
group = "my.group"
version = "1.0"
repositories {
mavenCentral()
maven(url = "my/url") {
name = "maven-snapshots"
authentication {
create<BasicAuthentication>("basic")
}
}
maven(url = "my/other/url") {
name = "maven-releases"
authentication {
create<BasicAuthentication>("basic")
}
}
}
//just trying all the things
rootProject.tasks.named("processResources", Copy::class.java) {
duplicatesStrategy = DuplicatesStrategy.WARN
}
tasks.withType<ProcessResources>() {
duplicatesStrategy = DuplicatesStrategy.WARN
}
tasks.withType<Copy>() {
duplicatesStrategy = DuplicatesStrategy.WARN
}
tasks.withType<Jar>() {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
dependencies {
implementation(project(":engine"))
}

Related

Why do I need to reference a custom gradle config with square brackets?

I created a gradle build config just to download some dependencies. The documentation has been sparse, so I've piece together this working snippet based on random snippets and guesses.
configurations {
create("downloadDeps")
}
dependencies {
// JSON
configurations["downloadDeps"]("com.fasterxml.jackson.core:jackson-databind:2.13.3")
configurations["downloadDeps"]("com.fasterxml.jackson.module:jackson-module-kotlin:2.13.3")
}
repositories {
// internal repository
maven {
url = uri("...")
credentials {
username = System.getenv("ARTIFACTORY_USER") ?: System.getProperty("ARTIFACTORY_USER") as String
password = System.getenv("ARTIFACTORY_TOKEN") ?: System.getProperty("ARTIFACTORY_TOKEN") as String
}
}
}
tasks.register<Copy> ("downloadDeps") {
from(configurations["downloadDeps"])
into("lib/")
}
If I reference the "downloadDeps" dependency like configuration.downloadDeps or downloadDeps("com.fasterxml.jackson.core:jackson-databind:2.13.3"). I get an error about an unresolved reference to "downloadDeps".
Why does implementation("...") or configuration.implementation.get() work?
The documentation #Slaw provided helped me understand why I can do something like this:
implementation("group:artifact:1.0.0")
but not
myCustomConfig("group:artifact:1.0.0")
implementation being declared that way is supported because it comes from a plugin (the Kotlin/Java plugins)
The simplest way to associate a dependency with myCustomConfig would be to do this (see these docs):
"myCustomConfig"("group:artifact:1.0.0")

Room Migration test failing : schema not found

I'm try to implement android test for my room database, to test migrations. For this, I generated the schema needed, and I follow the step from the Android documentation.
When I run my migration test, it shows that the schema cannot be loaded, despite I added the assets line in the Gradle build. I added multiple other build types, it was not helping. I'm making something wrong, but I can't find where.
Room Version : 2.3.0
The error :
Cannot find the schema file in the assets folder. Make sure to include the exported json schemas in your test assert inputs. See https://developer.android.com/training/data-storage/room/migrating-db-versions#export-schema for details. Missing file: Asset file database.Sauvegarde/1.json not found
java.io.FileNotFoundException: Cannot find the schema file in the assets folder. Make sure to include the exported json schemas in your test assert inputs. See https://developer.android.com/training/data-storage/room/migrating-db-versions#export-schema for details. Missing file: Asset file database.Sauvegarde/1.json not found
at androidx.room.testing.MigrationTestHelper.loadSchema(MigrationTestHelper.java:326)
at androidx.room.testing.MigrationTestHelper.createDatabase(MigrationTestHelper.java:152)
at globalTests.migrations.MigrationTest.migrate1To2(MigrationTest.java:31)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:61)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:575)
at org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$0(SandboxTestRunner.java:263)
at org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:89)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
In test structure:
MigrationTest :
package globalTests.migrations;
import ...;
#RunWith(AndroidJUnit4.class)
public class MigrationTest {
private static final String TEST_DB = "migration-test";
#Rule
public MigrationTestHelper helper;
public MigrationTest() {
helper = new MigrationTestHelper(InstrumentationRegistry.getInstrumentation(),
Sauvegarde.class.getCanonicalName(),
new FrameworkSQLiteOpenHelperFactory());
}
#Test
public void migrate1To2() throws IOException {
SupportSQLiteDatabase db = helper.createDatabase(TEST_DB, 1);
// Prepare for the next version.
db.close();
// Re-open the database with version 2 and provide
// MIGRATION_1_2 as the migration process.
db = helper.runMigrationsAndValidate(TEST_DB, 2, true, Migrations.MIGRATION_1_2);
// MigrationTestHelper automatically verifies the schema changes,
// but you need to validate that the data was migrated properly.
}
}
gradle.build :
testOptions {
execution 'ANDROIDX_TEST_ORCHESTRATOR'
}
javaCompileOptions {
annotationProcessorOptions {
arguments += ["room.schemaLocation":
"$projectDir/schemas".toString()]
}
}
sourceSets {
// Adds exported schema location as test app assets.
debug.assets.srcDirs += files("$projectDir/schemas".toString())
customDebugType.assets.srcDirs += files("$projectDir/schemas".toString())
androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
test.assets.srcDirs += files("$projectDir/schemas".toString())
}
In schemas location :
The problem is like this one, but the solution not worked for me ...
Speaking from experience, one possible source of this issue is the stripping of assets during packaging, i.e., if you have something like the rule below. It seems like it should apply to the release build only, but, alas, it applies do debug as well and will remove your schema files from view.
buildTypes {
debug {...}
release {
aaptOptions {
ignoreAssetsPattern '!*.json'
}
}
}
Something else you could do is to look at what assets are visible to the various contexts you have available to you in the test itself:
println("Instrumentation context.assets")
var assets = InstrumentationRegistry.getInstrumentation().context.assets
assets.list("")?.forEachIndexed { index, it ->
println("$index -> $it")
}
println("Instrumentation targetContext.assets")
assets = InstrumentationRegistry.getInstrumentation().targetContext.assets
assets.list("")?.forEachIndexed { index, it ->
println("$index -> $it")
}
println("ApplicationProvider context.assets")
assets = ApplicationProvider.getApplicationContext<App>().assets
assets.list("")?.forEachIndexed { index, it ->
println("$index -> $it")
}
I found the problem,
Roboelectric didn't import my Android resources for the tests
you need to add this to Gradle:
testOptions {
unitTests{
includeAndroidResources = true
}
}
Source

Ktor - post unhanldled error with coroutines

I a new to Kotlin and Ktor in particular, so I have tried to do simple post request. As you can see below, there is nothing special.
routing {
post("/articles/add"){
val post = call.receive<ArticleRequest>()
println(post)
}
Error shown in logs is below and I don't understand why I should use here coroutines.
ERROR Application - Unhandled: POST - /articles/add
java.lang.IllegalStateException: Using blocking primitives on this dispatcher is not allowed. Consider using async channel instead or use blocking primitives in withContext(Dispatchers.IO) instead.
I am using 1.4.2 version. I would appreciate any help.
If you are using Jackson this is a bug and there is a suggested workaround:
routing {
post("/articles/add") {
with(Dispatchers.IO) {
val post = call.receive<ArticleRequest>()
println(post)
}
}
}
Or you can rollback to 1.4.1 until the bug is solved.
I've experienced the same issue after upgrading to ktor 1.4.2 and Kotlin 1.4.20, and I used both Moshi and Gson on this specific project but I don't believe they are causing this issue.
If you have a 'gradle.properties' file, add these ( or whatever version you wish to use ) :
ktor_version=1.3.2
kotlin_version=1.3.70.
Otherwise, in your 'build.gradle' file, create variables for different version :
buildscript {
ext.kotlin_version = '1.3.70'
ext.ktor_version = '1.3.2'
repositories {
jcenter()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
Then sync your gradle, run project.. all should be good.
However if you still experience some gradle-related issue, try this :
go to gradle (folder) -> wrapper -> open gradle_wrapper.properties and make sure the url has version 6.x.x or 5.x.x.
Mine looks like this currently:
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

Strange exception thrown in Ktor

Today i encountered a strange status page exception being thrown in Ktor.
I am trying to build a simple api with ktor and i did this Route:
fun Route.phrase(db : Repository){
post(PHRASE_ENDPOINT){
val request = call.receive<Request>()
val phrase = db.add(EmojiPhrase(request.toString(), request.toString()))
this.call.respond(phrase)
}}
when i try to send the request i get
java.lang.ClassNotFoundException: kotlinx.coroutines.io.ByteReadChannel
has anyone encountered this problem
im using :
ktor_version=1.3.2,
kotlin_version=1.4.10,
moshi_version= 1.0.1
Issue appears to be in moshi converter: https://github.com/rharter/ktor-moshi/issues/7#issuecomment-580977097
Until the PR is merged, you can use the patched version through
jitpack
buildscript {
repositories {
jcenter()
maven { url 'https://jitpack.io' }
}
}
dependencies {
implementation 'com.github.cs125-illinois:ktor-moshi:7252ca49ed'
}

java.lang.UnsupportedOperationException: Packages and file facades are not yet supported in Kotlin reflection

When starting a basic Ktor app, I get:
Exception in thread "main" java.lang.UnsupportedOperationException: Packages and file facades are not yet supported in Kotlin reflection. Meanwhile please use Java reflection to inspect this class: class com.example.ApplicationKt
at kotlin.reflect.jvm.internal.KClassImpl.reportUnresolvedClass(KClassImpl.kt:301)
at kotlin.reflect.jvm.internal.KClassImpl.access$reportUnresolvedClass(KClassImpl.kt:43)
at kotlin.reflect.jvm.internal.KClassImpl$Data$descriptor$2.invoke(KClassImpl.kt:53)
at kotlin.reflect.jvm.internal.KClassImpl$Data$descriptor$2.invoke(KClassImpl.kt:44)
at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:92)
at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:31)
at kotlin.reflect.jvm.internal.KClassImpl$Data.getDescriptor(KClassImpl.kt)
at kotlin.reflect.jvm.internal.KClassImpl$Data$objectInstance$2.invoke(KClassImpl.kt:106)
at kotlin.reflect.jvm.internal.ReflectProperties$LazyVal.invoke(ReflectProperties.java:62)
at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:31)
at kotlin.reflect.jvm.internal.KClassImpl$Data.getObjectInstance(KClassImpl.kt)
at kotlin.reflect.jvm.internal.KClassImpl.getObjectInstance(KClassImpl.kt:239)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.createModuleContainer(ApplicationEngineEnvironmentReloading.kt:328)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.executeModuleFunction(ApplicationEngineEnvironmentReloading.kt:317)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.instantiateAndConfigureApplication(ApplicationEngineEnvironmentReloading.kt:275)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.createApplication(ApplicationEngineEnvironmentReloading.kt:127)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.start(ApplicationEngineEnvironmentReloading.kt:247)
at io.ktor.server.netty.NettyApplicationEngine.start(NettyApplicationEngine.kt:106)
at io.ktor.server.netty.NettyApplicationEngine.start(NettyApplicationEngine.kt:18)
at io.ktor.server.engine.ApplicationEngine$DefaultImpls.start$default(ApplicationEngine.kt:52)
at io.ktor.server.netty.EngineMain.main(EngineMain.kt:17)
at com.example.ApplicationKt.main(Application.kt:10)
The app is just:
fun main(args: Array<String>): Unit = EngineMain.main(args)
fun Application.demoModule() {
routing {
get("/") {
call.respondText("Hello ${call.parameters["name"]}")
}
}
}
I just noticed the file resources.application.conf had an issue.
It had the wrong module name. I changed com.example.ApplicationKt.module to com.example.ApplicationKt.demoModule:
ktor {
deployment {
port = 8080
port = ${?PORT}
}
application {
modules = [ com.example.ApplicationKt.demoModule ]
}
}
What's annoying is that the error help says nothing about it.