Error: Main method not found despite I have declared a main function - kotlin

I am new to kotlin and I am trying to use main function together with a class.
fun main() {
var demo = Person("Hello", 10)
println(demo)
}
private class Person (name: String, age: Int){
var name: String
var age: Int
init {
this.name = name
this.age = age
}
}
Although I have declared the main function, the compiler is still looking for the static main method in the class that I have defined, Person, and I got this error:
Error: Main method not found in class Person, please define the main method as:
public static void main(String[] args)
or a JavaFX application class must extend javafx.application.Application
What have I missed?

java Person is the problem, you are specifically telling it to look for the static void main method there. Top-level functions from Person.kt will be compiled into a PersonKt class by default and so you should run java PersonKt.
Also, the unnamed package you get by not specifying any package is weird in some ways, so I would recommend adding a package declaration from the start (and running java your.package.PersonKt).

Related

Protected inline method in parent class can't access other protected methods

I am having a problem getting IllegalAccessError for the following example:
I have a base class declared in a gradle module called arch
abstract class BaseClass {
protected abstract val value: Int
fun run() {
Log.d("Printme", "value $value")
}
protected inline fun getMyValue(): Lazy<Int> = lazy {
getAnEight()
}
protected fun getAnEight() = 8
}
and a child class declared in gradle module called app
class ChildClass: BaseClass() {
override val value by getMyValue()
}
It is worth saying I am creating a Kotlin project using Android Studio, but these classes are all simple Kotlin objects without any Android specific references. Of course these two modules also have different packages.
Now, from my main entry method I am doing the following (inside app module)
ChildClass().run()
I am calling my run() method declared in base class, which is accessing lazy initiated value property, which is in turn calling getAnEight() method. Since all methods are protected I would expect there is no reason a child class can't call all these. Even if one of the methods is marked as inline and this call gets replaced with method contents, it should still be able to call getAnEight() just fine.
Instead I am receiving IllegalAccessError saying BaseClass.getAnEight() is inaccessible to class ChildClass$$special$$inlined$getMeValue$1. This problem disappears when I remove inline modifier, or if I place BaseClass in the same package as ChildClass.
Is this a bug in Kotlin compiler? Or can someone explain to me this behavior if it's working as intended? Thanks in advance!
https://kotlinlang.org/docs/reference/inline-functions.html#public-inline-restrictions
When an inline function is public or protected and is not a part of a
private or internal declaration, it is considered a module's public
API. It can be called in other modules and is inlined at such call
sites as well.
This imposes certain risks of binary incompatibility caused by changes
in the module that declares an inline function in case the calling
module is not re-compiled after the change.
To eliminate the risk of such incompatibility being introduced by a
change in non-public API of a module, the public API inline functions
are not allowed to use non-public-API declarations, i.e. private and
internal declarations and their parts, in their bodies.
An internal declaration can be annotated with #PublishedApi, which
allows its use in public API inline functions. When an internal inline
function is marked as #PublishedApi, its body is checked too, as if it
were public.
EDIT: I made some bytecode research. The problem is that protected getMyValue() function is inlined into public constructor. In decompiled bytecode, ChildClass public constructor has a following line:
Lazy var4 = LazyKt.lazy((Function0)(new ChildClass$$special$$inlined$getMyValue$1(this)));
As you can see, it creates an instance of class ChildClass$$special$$inlined$getMyValue$1. Let's look at its declaration:
public final class ChildClass$$special$$inlined$getMyValue$1 extends Lambda implements Function0 {
final BaseClass this$0;
public ChildClass$$special$$inlined$getMyValue$1(BaseClass var1) {
super(0);
this.this$0 = var1;
}
public Object invoke() {
return this.invoke();
}
public final int invoke() {
return this.this$0.getAnEight(); // Here lies the problem
}
}
When you create a ChildClass instance, its constructor only creates a ChildClass$$special$$inlined$getMyValue$1 instance, that does not throw any errors. But when you call run(), invoke() method of class above is called. This method is public, its class is public, constructor was public, but getAnEight method is protected. That's how we get this error.

Kotlin compiler issue with overriding of Java final function in Kotlin

I’m dealing with following issue with Kotlin/Java Compiler.
Imagine following scenario: let First be a Java class with a final function and Second be a Kotlin class extending First with a function of the same name like the final function in First class, example:
// Java class
class First {
final void foo() { }
}
// Kotlin class
class Second: First() {
fun foo() { }
}
Obviously, it’s wrong because the final function foo() can not be overridden. However, compilation pass successfully and in run-time I get java.lang.LinkageError: Method void Second.foo() overrides final method in class First.
Is this correct behavior of compiler? I supposed that there will be some validations for this case. Thank you!

What is the difference between main and regular function?

Kotlin allows me to create two main() functions. But does not allow two myfun() functions.
What is special about main()? Are there other special functions?
Can I create two static myfun() functions in same package? I want them to have file scope like main.
Test1.kt:
package start
fun main(args: Array<String>) {
}
fun myfun(args: Array<String>) {
}
Test2.kt:
package start
// OK!
fun main(args: Array<String>) {
}
// Error! Conflicting overloads
fun myfun(args: Array<String>) {
}
Kotlin allows to have multiple top-level main functions in the same package due to practical reasons — so that one could have an entry point in an each file without moving these files to different packages.
It is possible because each .kt file with top-level members is compiled to the corresponding class file, so these main functions do not clash, because they are located in separate class files.
Why is it allowed for main functions and not for other top-level functions? Having multiple functions with the same name and signature in the same package would make it impossible to distinguish them when calling from Kotlin. This is not a problem for main function, because when it is used as an entry point for a program, it's required to specify the class name where it is located.
What is special about main()? Are there other special functions?
To start a Java program you need
a class file,
static void main(String[]) method in that class file.
So from outside of the package you'd be able to start any of these main methods.
However if you try to call the main method from another Kotlin file inside of the package, you'd get an error, because Kotlin can't disambiguate one method from the other.
You can call any of them from Java as you please because they're compiled in different class files (see further).
Can I create two static myfun() functions in same package?
You can't define two top-level methods with the same name in the same package in Kotlin (with the above exception).
This is what your code compiles to:
public final class Test1Kt {
public static final void main(#NotNull String[] args) { /* ... */ }
public static final void myFun(#NotNull String[] args) { /* ... */ }
}
public final class Test2Kt {
public static final void main(#NotNull String[] args) { /* ... */ }
public static final void myFun(#NotNull String[] args) { /* ... */ }
}
As far as JVM is concerned all of these methods could coexist in peace. But this is an implementation detail of Kotlin.
Let's forget for a second that Kotlin apps run on JVM. Pretend your only tool is Kotlin, and you can't use Java, perhaps you're writing a Kotlin cross-platform module. How could you have two top-level functions with the same name? How would you pick which one to call? Again, you'd get an error, because Kotlin couldn't disambiguate one method from the other.
Edit: As noted by #Todd this behavior has been even more strict in the past: Why does Kotlin lang allow only single main function in project?
Regarding the question about how to have file-scoped functions, by default top-level functions (those not declared within a class) are public, which means their signatures must be unique, including the package name. You can make functions local to the file, rather than the package, by prefixing them with the private modifier, e.g., in each file:
private fun myfun(args: Array<String>) {
// method body here
}

Kotlin SAM Runtime Error: NoSuchMethodError: No static method

Today I ran into a really strange runtime error while developing kotlin / android that involves SAM conversions and sub classing.
Here's a minimal example of pure java + kotlin. Here are two java classes:
public class A {
public interface I {
public void f();
}
public I i;
}
public class B extends A {}
And here is a kotlin main function:
fun main(args: Array<String>) {
A().i = B.I {}
}
This code compiles fine but at run time I get the following error:
Exception in thread "main" java.lang.NoSuchMethodError: B.I(Lkotlin/jvm/functions/Function0;)LA$I;
at MainKt.main(Main.kt:2)
Now, this is already bad -- if code like this does not work (it never will I guess) the compiler should raise an error. But at least one could say that it is bad idea to reference to the interface I via the subclass B instead of the place of definition A (i.e., A.I).
It's less clear though, if this code is in a sub class of B where I can reference I directly using I:
class C: B {
constructor() {
this.i = I {}
}
}
So my questions would be:
Why is this behavior happening at all?
If it is happening, why is the compiler not raising an error already?
PS: In android the error message looks similar to this, which is even more confusing:
Caused by: java.lang.NoSuchMethodError: No static method OnFocusChangeListener(Lkotlin/jvm/functions/Function2;)Landroid/view/View$OnFocusChangeListener; in class Landroid/widget/LinearLayout; or its super classes (declaration of 'android.widget.LinearLayout' appears in /system/framework/framework.jar:classes2.dex)
Define main method as static like-
companion object {
#JvmStatic fun main(args: Array<String>) {
A().i = B.I {}
}
}

Why do I get a compilation error when calling println method in the class body? #Java

class Test {
int a = 100;
System.out.println(a);
}
class Demo {
public static void main(String args[]) {
Test t = new Test();
}
}
I'm new to programming. I found this code when I'm practicing. I don't understand why I'm getting this error.
Here is the error I'm getting.
Demo.java:3: error: <identifier> expected
System.out.println(a);
^
Demo.java:3: error: <identifier> expected
System.out.println(a);
^
2 errors
Compilation failed.
Can you guys explain why I'm getting this error?
You can't call a method directly from the java class body.
Create a constructor in your Test class, and put the print in it :
class Test {
int a = 100;
public Test() {
System.out.println(a);
}
}
Note that if for some reason you really want a statement to be executed when the class is loaded without using a constructor, you can define a static block, here an example :
class Test {
static int a = 100;
static {
System.out.println(a);
}
}
However, this is just for reference and really not needed in your case.
From Declaring Classes in the Java tutorial:
In general, class declarations can include these components, in order:
Modifiers such as public, private, and a number of others that you will encounter later.
The class name, with the initial letter capitalized by convention.
The name of the class's parent (superclass), if any, preceded by the keyword extends. A class can only extend (subclass) one parent.
A comma-separated list of interfaces implemented by the class, if any, preceded by the keyword implements. A class can implement more than one interface.
The class body, surrounded by braces, {}.
You can't make any function calls outside of a method declaration.