Kotlin Coroutines dependency going into Overload Resolution Ambiguity - kotlin

I'm having a production ready Kotlin code and I want to refactor it from changing all CompletableFuture requests to Coroutines, but when I add the compile('org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.0') dependecy tu build.gradle, all my kotlin.collections imports are going into "Overload resolution ambiguity". Does anybody knows how to deal with this problem?
Here is a snippet from my code:
TX!

Generally this happens when indexes get stale in IDEA. Try to build with gradle to ensure there is no real clashes. Running File -> Invalidate caches / Restart should help.

Related

What is the use of LibraryEntitiesShouldNotBePublic Detekt Rule in Kotlin

I have a Kotlin Library into which I integrated the usage of Detekt static code linting. Most of the rules are clear to me and I fixed all the issues with my code except for one:
There is a rule called LibraryEntitiesShouldNotBePublic, which makes no sense in my opinion. It tells me for every public class, that it should not be public, but of what use is a library without any public classes.
I must admit I am rather new to Kotlin, coming from Java, so I might miss some language feature here.
Any hints would be greatly appreciated. Thanks.

fillcover red in initializer dependencies - Quarkus native

I try to build a native container with Quarkus (with -Pnative flag), I use -H:+PrintClassInitialization to generate the class initializer reports. I see a initilizer_dependencies_yyyymmdd_hhmmss.dot file is generated; in this file, I see some classes marked with [fillcover=red], could you tell me what this means? and what action is needed?
Thanks
it seems to me those classes are the ones that will be called but not in reflection configuration. I add them in reflection or initialize to solve it.

Concurrent Hash Map in Kotlin

Is it possible to implement a concurrent hash map purely in Kotlin (without Java dependency)? I am new to Kotlin and it looks like there is no obvious API available in kotlin.collections.
You can probably convert the source without too many issues. It's freely available, here for example. The concurrency model of Kotlin multiplatform (which I'm guessing is your goal, there's no point in reimplementing it if you only target the JVM) is a bit different than the one Java uses, there are no locks for example. But there's no reason why that would prevent it.
The following resources might also help you with the implementation:
Concurrency in Kotlin/Native
kotlin.native.concurrent package
Replacement for synchronized
Official Kotlin/Native Concurrency tutorial
You can try:
val emitters: ConcurrentMap<String, Any> = ConcurrentHashMap()
// get
val obj: Any = emitters[email]
// put:
emitters[email] = this
// delete
emitters.remove(email)
Such way, u don't need to add any library to your project

Gradle. Custom function in block plugins{}

Can i write in my custom plugin some function like kotlin("jvm")?
plugins {
java
kotlin("jvm") version "1.3.71"
}
I want to write function myplugin("foo") in my custom plugin and then use it like
plugins {
java
kotlin("jvm") version "1.3.71"
custom.plugin
myplugin("foo")
}
How i can do it?
I think that plugins block is some kind of a macro expression. It is parsed and precompiled using a very limited context. Probably, the magic happens somewhere in kotlin-dsl. This is probably the only way to get static accessors and extension functions from plugins to work in Kotlin. I've never seen a mention of this process in Gradle's documentation, but let me explain my thought. Probably, some smart guys from Gradle will correct me.
Let's take a look at some third-party plugin, like Liquibase. It allows you to write something like this in your build.gradle.kts:
liquibase {
activities {
register("name") {
// Configure the activity here
}
}
}
Think about it: in a statically compiled language like Kotlin, in order for this syntaxt to work, there should be an extension named liquibase on a Project type (as it is the type of this object in every build.gradle.kts) available in the classpath of a Gradle's VM that executes the build script.
Indeed, if you click on it, you'll see something like:
fun org.gradle.api.Project.`liquibase`(configure: org.liquibase.gradle.LiquibaseExtension.() -> Unit): Unit =
(this as org.gradle.api.plugins.ExtensionAware).extensions.configure("liquibase", configure)
But take a look at the file where it is defined. In my case it is ~/.gradle/caches/6.3/gradle-kotlin-dsl-accessors/cmljl3ridzazieb8fzn553oa8/cache/src/org/gradle/kotlin/dsl/Accessors39qcxru7gldpadn6lvh8lqs7b.kt. It is definitelly an auto-generated file. A few levels upper in a file tree — at ~/.gradle/caches/6.3/gradle-kotlin-dsl-accessors/ in my case — there are dozens of similar directories. I guess, one by every plugin/version I've ever used with Gradle 6.3. Here is another one for the Detekt plugin:
fun org.gradle.api.Project.`detekt`(configure: io.gitlab.arturbosch.detekt.extensions.DetektExtension.() -> Unit): Unit =
(this as org.gradle.api.plugins.ExtensionAware).extensions.configure("detekt", configure)
So, we have a bunch of .kt files defining all that extensions for different plugins applied to the project. That files are obviously pre-cached and precompiled and their content is available in build.gradle.kts. Indeed, you can find classes directories beside those sources.
The sources are generated based on the content of the applied plugins. It is probably a tricky task that includes some magic, reflection and introspection. Sometimes this magic doesn't work (due too chatic Groovy nature) and then you need to use some crappy DSL from this package.
How are they generated? I see no other way, but to
Parse the build.script.kts with an embedded Kotlin compiler / lexer
Extract all the plugins sections
Compile them, probably against some mocks (remember that Project is not yet available: we're not executing the build.gradle.kts itself yet!)
Resolve the declared plugins from Gradle Plugin repository (with some nuances coming from settngs.gradle.kts)
Introspect plugin's artifacts
Generate the sources
Compile the sources
Add the resulting classes to the script's classpath
And here is the gotcha: there is a very limited context (classpath, classes, methods — call it whatever) available when compiling the plugins block. Actually, no plugins are yet applied! Because, you know, you're parsing the block that applies plugins. Chickens, eggs, and their problems, huh…
So, and we're getting closer to the answer on your question, to provide custom DSL in plugins block, you need to modify that classpath. It's not a classpath of your build.gradle.kts, it's the classpath of the VM that parses build.gradle.kts. Basically, it's Gradle's own classpath — all the classes bundled in a Gradle distribution.
So, probably the only way to provide really custom DSLs in plugins block is to create a custom Gradle distribution.
EDIT:
Indeed, totally forgot to test the buildSrc. I've created a file PluginExtensions.kt in it, with a content
inline val org.gradle.plugin.use.PluginDependenciesSpec.`jawa`: org.gradle.plugin.use.PluginDependencySpec
get() = id("org.gradle.war") // Randomly picked
inline fun org.gradle.plugin.use.PluginDependenciesSpec.`jawa`(): org.gradle.plugin.use.PluginDependencySpec {
return id("org.gradle.cunit") // Randomly picked
}
And it seems to be working:
plugins {
jawa
jawa()
}
However, this is only working when PluginExtensions.kt is in the default package. Whenever I put it into a sub-package, the extensions are not recognized, even with an import:
Magic!
The kotlin function is just a simple extension function wrapping the traditional id method, not hard to define:
fun PluginDependenciesSpec.kotlin(module: String): PluginDependencySpec =
id("org.jetbrains.kotlin.$module")
However, this extension function is part of the standard gradle kotlin DSL API, which means it's available without any plugin. If you want to make a custom function like this available, you would need a plugin. A plugin to load your plugin. Not very practical.
I also tried using the buildSrc module to make an extension function like the above. But it turns out that buildSrc definitions aren't even available from the plugins DSL block, which has a very constrained syntax. That wouldn't have been very practical anyway, you would have needed to make a buildSrc folder for every project in which you have wanted to use the extension.
I'm not sure if this is possible at all. Try asking on https://discuss.gradle.org/.

How to JMock a Singleton

My application has this structure: there's a RepositoryFacade (that is a Singleton) that uses many other ObjectRepository that are Singleton (UserRepository, etc).
Now I'd like to test it, mocking the [Objetct]Repositiries. To do that I made the [Objetct]Repositiry implements an interface, and then i tried to:
final IUserRepository mockIUserRepository= context.mock(IUserRepository.class);
RepositoryFacade.getInstance().setUserRepository(mockIUserRepository);
final User testUser = new User("username");
// expectations
context.checking(new Expectations() {{
oneOf (mockIUserRepository).save(testUser);
}});
// execute
RepositoryFacade.getInstance().save(testUser);
And in RepositoryFacade I added:
public IUserRepository userRepository = UserRepository.getInstance();
But if I try to run the test, I obtain:
java.lang.SecurityException: class "org.hamcrest.TypeSafeMatcher"'s signer
information does not match signer information of other classes in the same
package
p.s. Originally my RepositoryFacade had not a IUserRepository variable, I used it asking always UserRepository.getInstance().what_i_want(). I introduced it to try to use JMock, so if not needed I'll be glad to remove that bad use of Singleton.
Thanks,
Andrea
The error you're getting suggests that you have a classloading issue with the org.hamcrest package rather than any issue with your singletons. See this question for more on this exception and this one for the particular problem with hamcrest and potential solutions.
Check your classpath to make sure you're not including conflicting hamcrest code from multiple jars. If you find hamcrest in multiple jars, this may be corrected by something as simple as changing their order in your classpath.
Junit itself comes in two versions - one may include an old version of hamcrest. Switching to the one not including hamcrest may also fix your problem.
If you can find a way to do it, it would be better in the long run to get rid of the singletons altogether and instead do dependency injection using something like Spring or Guice.
But what you're doing should work, once you deal with the classloading, and it's a reasonable approach to dealing with singletons in a testing context.