IntelliJ - cannot run Kotlin Class in mixed (Java/Kotlin) mode - kotlin

I am constantly getting the error (bottom right), but I have configured everything to run Kotlin/Java together. So, where is the missing bit which I cannot see.
UPDATE
A comment indicated that my pkg name was wrong, but it didn't matter regardless, as the below updated screenshot shows
Regards,

If you want to write the main function without any parameters, it has to be outside of the class like this:
package org.example
fun main() {
println("Hello World!")
}
Note that in this case, the main function will be inside an artificial implicit class that is called like the containing file suffixed with Kt. This means, that in your example where you place the main function inside a file AppKt.kt, the resulting main class is called AppKtKt.
If you want to have the main function inside a class, you have to specify a parameter for the arguments. Also, it needs to be static, i.e. it has to be inside an object and must be annotated with #JvmStatic.
This can be done by declaring an object:
object AppKt {
#JvmStatic
fun main(args: Array<String>) {
println("Hello World!")
}
}
Or you can put the main function inside the companion object of a class:
class AppKt {
companion object {
#JvmStatic
fun main(args: Array<String>) {
println("Hello World!")
}
}
}

In Kotlin, your main function goes outside any class definition.

Related

How to create a member variable of Arrow Atomic in kotlin

Arrow-fx has a type Atomic which is similar to java AtomicRef but with an initial value, which means I don't need to check every time while accessing the atomic value whether it's null.
Here is a simple example
import arrow.fx.coroutines.*
suspend fun main() {
val count = Atomic(0)
(0 until 20_000).parTraverse {
count.update(Int::inc)
}
println(count.get())
}
Now I would like to create a class member variable with this type, but since it's only possible to initialize within a suspend function I would like to know the possibility here.
The easiest way is to make a "fake constructor" in the companion object.
public class Thingy private constructor(
val count: Atomic<Int>
) {
companion object {
suspend fun invoke() = Thingy(Atomic(0))
}
}
Now when you write Thingy(), you're actually calling the invoke function in Thingy.Companion. For that function there are no restrictions over suspending, so you can initialize Atomic as shown above.

Dagger Dependency Injection in main function

I am calling a function in a class S3FileOperationsAdapter from the main function in my kotlin code. I am injecting the class S3FileOperationsAdapter in the main function file. So it looks like
class Runner {
#set:Inject
lateinit var s3FileOperationsAdapter: S3FileOperationsAdapter
fun main(args: Array<String>) {
s3FileOperationsAdapter.readFunction()
}
}
Now the issue is:
When I try to run the above code, I get the error Error: Main method is not static in class com.amazon.bram.sim.BatchJobRunner, please define the main method as:. This is understandable.
And we can only make a static function within an object in kotlin. So upon doing that, I cannot Inject the dependency, because Dagger does not support injection into Kotlin objects. So it feels like a deadlock.
My question is, I want to inject the dependency in this file anyhow so that I can call the respective function. And I am calling this function from the "fun main()" in kotlin. How can I achieve this? Has anyone ever faced this before?
In order to inject anything in Dagger, you must first create an instance of your component. Since no code at all will run before fun main(), this needs to be done during main itself (or in a field initializer).
After creating an instance of the component, you can ask it for an instance of S3FileOperationsAdapter directly.
fun main(args: Array<String>) {
// Create the component.
val component = DaggerMyComponent.create()
// or use the Component.Builder or Component.Factory you defined for MyComponent.
// Get an object from the component.
// This method should be defined in your component interface.
val adapter = component.s3FileOperationsAdapter()
// Use the object.
adapter.readFunction()
}
If your actual code is more complicated, with multiple injected objects and a longer main() function, this may be a bit unwieldy. In that case, you can extract your current main() into its own class and let Dagger provide that class in main().

How to force immediate instantiation of enum values?

How to force immediate instantiation of enum values?
By default, in Kotlin enums are instantiated on first access (like objects/singletons), i.e., the following minimal example
class Foo
fun create(msg: String) = Foo().also { println("$msg") }
enum class A(val foo: Foo) {
ONE(create("1")),
TWO(create("2"))
}
enum class B(val foo: Foo) {
THREE(create("3")),
FOUR(create("4"))
}
fun main() {
println("main")
println(A.ONE)
}
outputs:
main
1
2
ONE
Is it possible to force the enums to be instantiated directly/statically before main, such that the output is as follows?
1
2
3
4
main
ONE
Sure, I could just put something like val ignore = listOf(A.ONE, B.THREE) somewhere, but I'd like to avoid such manual repetition.
Maybe there's a way using some existing annotation, or creating a new one, or something else? :)
JVM loads classes only on first access. This is not only for kotlin but also for Java. For Java we have ways to initialize a class before main, for instance, static initializer block, or Class.forName. Similarly you can use the static initializer block in Kotlin.
object Temp {
init {
A.ONE
}
#JvmStatic fun main(args: Array<String>) {
println("main")
println(A.ONE)
}
}

how to call a (samename) method declared outside with(){} scope in Kotlin

I want to call the dada() declared outside with()
There's a line below that supposed to do what I need but doesn't compile.
data class Person(val name: String, val age: Int)
fun main(args: Array<String>) {
var muchos = "muchos"
fun dada(){
println("dada")}
var someRun = Runnable { println(muchos) }
with(someRun){
fun dada(){
println("dodo")}
run()
muchos = "holas"
//*********************//DOES'T COMPILE *******************
this#OuterClass.dada() //DOES'T COMPILE *******************
run()
}
}
Kotlin does not provide a syntax for disambiguating between multiple local functions with the same name. The OuterClass in the this#OuterClass syntax is the name of a specific class that was used in the example where you copied this line from; it does not have a generic meaning of "outer scope".
To make it possible to call both functions, simply give them different names.

the content in the parameter of the main fun in kotlin

I'm a beginner of Kotlin language and I want to understand everything in this programming language so.
1- what mean of the args: Array<String> in the parameter of the main function ?
2- why compilation error is shown when this line is removed ?
The main(Array<String>) function is an entry point of a program. The strings passed are the command-line arguments.
That is, when you run something like
$ java myprogram foo bar
the main function is called with ["foo", "bar"] as the argument.
This is very much the same thing that Java does, and Java emulates C in this regard.
I keep replacing it with vararg everywhere
object Application {
#JvmStatic
fun main(vararg args: String) {
Micronaut.build()
.packages("example")
.mainClass(Application::class.java)
.start()
}
}
fun main(args : Array<String>) {
println("Hello, world!")
}
In this example, a function named main is defined which returns Unit and takes an Array of strings as a parameter.
Depend on Java convention, this Kotlin code bellow's the same with Java code.
Kotlin code:
fun main(args : Array<String>) {
println("Hello, world!")
}
Java code:
public static void main(String[] args) {
println("Hello, world!");
}
According to #9000 "The main(Array) function is an entry point of a program. The strings passed are the command-line arguments." Each program must have the start entry point. That's just a convention to get the function call parameter.