-1

Is there a way I can compile a main() method statically inside an existing class in Kotlin? I'm trying to get Gradle to build this as an application with a main() method, but I'm having no luck. I've been trying several workarounds too...

class MyApp: App() {

    override val primaryView = MyView::class

    companion object Launcher {
        @JvmStatic
        fun main(args: Array<String>): Unit {
            launch(*args)
        }
    }
}

In my Gradle script, I am trying to specify the MyApp class has a main() method. It errors out and can't find the class however when I call run.

mainClassName = 'path.to.application.MyApp'

EDIT

I apologize for the confusion but part of my issue might have to do with subclassing and not necessarily finding the main() class.

The main() function needs access to the launch() method that is defined in App. For some reason putting the companion keyword disallows this :/ Can we rethink the downvotes if this information is relevant?

13
  • I think you need 'path.to.application.MyApp.Companion' Commented Mar 2, 2016 at 15:41
  • 1
    Is the package for MyApp the same as path.to.application? In Kotlin package directives do not have to match file locations. Commented Mar 2, 2016 at 15:50
  • 1
    The mainClassName is correct assuming the path.to.application is the correct package name. Naming the companion or not doesn't affect the static method which is placed on MyApp always. You can check this in Intellij by right clicking on the main and picking create com.bla.bla... for a new configuration and seeing the class name chosen. You don't show the package name for sure of MyApp and you do not show the exact error you get. So we cannot be sure. Please share the missing pieces of the puzzle. Commented Mar 2, 2016 at 16:01
  • Possible duplicate of how to run compiled class file in Kotlin? Commented Mar 2, 2016 at 16:17
  • Your question is misleading if your answer was successful. Because you actually tried to run path.to.application.MyApp.Launcher but didn't say that. Otherwise the code below would not work. Remove Launcher from the mainClassName and also from the companion object name, it isn't needed and is what confused you. Commented Mar 2, 2016 at 16:24

1 Answer 1

3

A static method in a companion object is placed onto the enclosing class. So in your case MyApp. This is true regardless of you naming the companion object, and you do not need to reference the companion in any way when running the class.

Therefore your code is correct, assuming the following is true:

  1. You have the application plugin applied in your Gradle
  2. You named your package containing the code above as path.to.application (you don't show package statement)
  3. You are getting a class not found error for path.to.application.MyApp and that matches #2, (you don't show the actual error from Gradle)
  4. You are running the correct gradle task (which task are you running?)
  5. The code is actually compiled, looking at your latest comments indicates you likely had a compiler error (launch() method not accessible from companion) which meant that you couldn't run something not yet compiled.

What you can do to check the classname is right click on the main() method within Intellij IDEA and pick create path.to.app... menu option that is just below run/debug options and when that opens the runtime configuration dialog you can see the full classname there. That should be the same one used in your Gradle. If you already have a runtime configuration, just view the full classname there. If this does not work, the problem is elsewhere and you need to provide the missing information (what Gradle task, what is the actual error, what is the package statement for the class)

Some information is missing from the question that would help narrow this down.

This example:

package org.test.kotlin

class MyApp {
    companion object Launcher {
        @JvmStatic
        fun main(args: Array<String>) {
            println("hello")
        }
    }
}

Works fine when running class org.test.kotlin.MyApp

So does this, without the word Launcher:

package org.test.kotlin

class MyApp {
    companion object {
        @JvmStatic
        fun main(args: Array<String>) {
            println("hello")
        }
    }
}

And this works by accident but is not doing what you expected, but is creating a nested class and adding the static there and run using class org.test.kotlin.MyApp.Launcher. If this is working, then the question isn't showing the actual main classname it is using that is failing:

package org.test.kotlin

class MyApp {
    object Launcher {
        @JvmStatic
        fun main(args: Array<String>) {
            println("hello")
        }
    }
}

About possible compiler errors (#5 above): In your code you reference the launch() method which you do not show, maybe it is in the ancestor class. But you did not create an instance of any class. So this will fail with compiler error. Change this to:

class MyApp: App() {
    override val primaryView = MyView::class
    companion object {
        @JvmStatic
        fun main(args: Array<String>): Unit {
            MyApp().launch(*args)
        }
    }
}

Similar tips are in these other related questions:

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, this is very helpful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.