Quarkus: Create a main entry point for *ide* runs

Created on 18 Apr 2019  路  15Comments  路  Source: quarkusio/quarkus

I was chatting with someone that had the following arguments:

  • some people have a hard time to do mvn calls from their IDE e.g. mvn compile quarkus:dev
  • and it makes it hard to then attach the debugger
  • and he likes that SB and Micronaut do generate a main method in the like of this
public class Application {
    public static int main(String[] args) {
        Quarkus.startDev(Application.class);
    }
}

I don't know how true the assumptions are and wether we could have the main in our starters?
And even whether this kind of thing is possible with our approach

Most helpful comment

Quarkus' remote-dev can be used in Kubernetes pods and it's much much more efficient that anything else I have seen.

All 15 comments

As per the assumption about people finding using maven and/or remote debugger hard:

I have seen this myself a lot in coworkers (in previous jobs). Plenty of people I have worked with actively hated interacting with the build tool and preferred to do as much as possible from the IDE.

Another potential usage is CLI where users would prefer to own main()

+1 to have users own their main.

We discussed this use case in a design session for shutdown, and it's listed as one of the goals.

We plan to wrap it the other way around though: the user defines his "main()", Quarkus generates its own main so to invoke the user's one and be able to cleanup its own resources in a generated finally block which wraps it.

Needs a volunteer to be implemented though...

+1 for this. Quarkus could make available a class similar to io.quarkus.runner.GeneratedMain for development/debugging purposes. I am not sure what exactly goes inside this GeneratedMain, but it could be a simplified version or something like that, just to give developers a chance to run and debug within an IDE.

I tried to have a go at this, as I consider this extremely important for day-to-day use.
I've stumbled a bit on how the dev run lifecycle goes, because (as I understood) the logic is split between the DevMojo and the DevModeMain.
My current line of thinking (which I'm not yet sure is the best way to do it) is that this could be handled by replicating the logic of dependency/classpath matching from the DevMojo to the DevModeMain. Then a user could include the quarkus-development-mode artifact in their dependencies (possibly in test scope) and generate their own main, which would be required to simply delegate to DevModeMain.
I would appreciate your thoughts on this approach

This is similar to what spring-boot does, with spring-devtools. This proved to be good for spring, I think we don't need to reinvent the wheel here :). If someone needs a hot reload they can use this else can skip this. I am more inclined towards frameworks which can sync code changes directly inside a kubernetes pod with minimal layer rebuilds. Bonus if it can work with google's jlib (https://github.com/GoogleContainerTools/jib), both spring boot and Micronaut supports it completely.

Quarkus' remote-dev can be used in Kubernetes pods and it's much much more efficient that anything else I have seen.

For anyone interested, one _hacky_ way for easy debugging inside the IDE is a custom test class under test sources named TestMain so that it doesn't match surefire/failsafe patters, which uses @QuarkusTest and simply sleeps:

@QuarkusTest
public class TestMain {
    @Test
    public void startApp() throws Exception {
        while (true) {
            TimeUnit.SECONDS.sleep(1);
        }
    }
}

This uses the test http port (8081 by default) as described in the documentation, so either use it under port 8081, or add quarkus.http.test-port=8080 in application.properties

What's wrong with having IDE plugins expose the run/debug hooks via buttons & keymappings?

I guess this is solved now and can be closed, as there is now a possibility to create a "main" method:
https://quarkus.io/guides/lifecycle

I guess this is solved now and can be closed, as there is now a possibility to create a "main" method:
https://quarkus.io/guides/lifecycle

Still doesn't works for me, see an example. Tested on Intellij 2019.3

Looks like it's related to Intellij's output path

```
Exception in thread "main" java.lang.RuntimeException: io.quarkus.bootstrap.BootstrapException: Failed to determine the Maven artifact associated with the application
at io.quarkus.launcher.QuarkusLauncher.launch(QuarkusLauncher.java:46)
at io.quarkus.runtime.Quarkus.launchFromIDE(Quarkus.java:93)
at io.quarkus.runtime.Quarkus.run(Quarkus.java:79)
at io.quarkus.runtime.Quarkus.run(Quarkus.java:38)
at com.mageddo.resource.Main.main(Main.java:14)
Caused by: io.quarkus.bootstrap.BootstrapException: Failed to determine the Maven artifact associated with the application
at io.quarkus.bootstrap.BootstrapAppModelFactory.resolveAppModel(BootstrapAppModelFactory.java:241)
at io.quarkus.bootstrap.app.QuarkusBootstrap.bootstrap(QuarkusBootstrap.java:140)
at io.quarkus.launcher.QuarkusLauncher.launch(QuarkusLauncher.java:41)
... 4 more
Disconnected from the target VM, address: '127.0.0.1:60377', transport: 'socket'

Process finished with exit code 1

````

Weird... I'm using Eclipse, there it works fine.

have the same error on gradle build

Exception in thread "main" java.lang.RuntimeException: io.quarkus.bootstrap.BootstrapException: Failed to determine the Maven artifact associated with the application
    at io.quarkus.launcher.QuarkusLauncher.launch(QuarkusLauncher.java:46)
    at io.quarkus.runtime.Quarkus.launchFromIDE(Quarkus.java:93)
    at io.quarkus.runtime.Quarkus.run(Quarkus.java:79)
    at io.quarkus.runtime.Quarkus.run(Quarkus.java:38)
    at com.wtools.Runner.main(Runner.java:12)
Caused by: io.quarkus.bootstrap.BootstrapException: Failed to determine the Maven artifact associated with the application
    at io.quarkus.bootstrap.BootstrapAppModelFactory.resolveAppModel(BootstrapAppModelFactory.java:241)
    at io.quarkus.bootstrap.app.QuarkusBootstrap.bootstrap(QuarkusBootstrap.java:140)
    at io.quarkus.launcher.QuarkusLauncher.launch(QuarkusLauncher.java:41)
    ... 4 more

I am having the same issue as well with intellij and gradle as https://github.com/quarkusio/quarkus/issues/2143#issuecomment-630734811

This seems to still be an issue.

  • IDE: VS Code 1.50.1
  • JDK: AdoptOpenJDK 14.0.1.7-hotspot
  • Quarkus: 1.9.0.Final
  • Dependencies: io.quarkus:quarkus-resteasy
  • Main class:
@QuarkusMain
public class Main {
  public static void main(String... args) {
    Quarkus.run(args);
  }
}
  • Stacktrace:
Exception in thread "main" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
        at io.quarkus.launcher.QuarkusLauncher.launch(QuarkusLauncher.java:57)
        at io.quarkus.runtime.Quarkus.launchFromIDE(Quarkus.java:92)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:79)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:38)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:104)
        at uk.dansiviter.microservices.Main.main(Main.java:10)
Caused by: java.lang.reflect.InvocationTargetException
        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:564)
        at io.quarkus.launcher.QuarkusLauncher.launch(QuarkusLauncher.java:54)
        ... 5 more
Caused by: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.ClassNotFoundException: io.quarkus.deployment.dev.IDEDevModeMain
        at io.quarkus.bootstrap.IDELauncherImpl.launch(IDELauncherImpl.java:60)
        ... 10 more
Caused by: java.lang.RuntimeException: java.lang.ClassNotFoundException: io.quarkus.deployment.dev.IDEDevModeMain
        at io.quarkus.bootstrap.app.CuratedApplication.runInCl(CuratedApplication.java:132)
        at io.quarkus.bootstrap.app.CuratedApplication.runInAugmentClassLoader(CuratedApplication.java:82)
        at io.quarkus.bootstrap.IDELauncherImpl.launch(IDELauncherImpl.java:58)
        ... 10 more
Caused by: java.lang.ClassNotFoundException: io.quarkus.deployment.dev.IDEDevModeMain
        at io.quarkus.launcher.RuntimeLaunchClassLoader.findClass(RuntimeLaunchClassLoader.java:25)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:589)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
        at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:412)
        at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:365)
        at io.quarkus.bootstrap.app.CuratedApplication.runInCl(CuratedApplication.java:127)
        ... 12 more
  • Notes: Add io.quarkus:quarkus-core-deployment as a dependency (at provided scope so it's not needlessly bundled). Gets a little further but no features are being found:
__  ____  __  _____   ___  __ ____  ______ 
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
2020-10-28 21:05:05,774 INFO  [io.quarkus] (Quarkus Main Thread) Quarkus 1.9.0.Final on JVM started in 1.045s.
2020-10-28 21:05:05,802 INFO  [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2020-10-28 21:05:05,806 INFO  [io.quarkus] (Quarkus Main Thread) Installed features: []
Was this page helpful?
0 / 5 - 0 ratings