micronaut-projects / micronaut-maven-plugin

Maven plugin to execute Micronaut applications
https://micronaut-projects.github.io/micronaut-maven-plugin/latest/
Apache License 2.0
20 stars 21 forks source link

No embedded container found when micronaut-runtime added transitively #452

Open subash89 opened 2 years ago

subash89 commented 2 years ago

Expected Behavior

I have a java maven library which has micronaut Application(main method) and pretty much everything. And I use that library as a maven dependency in a separate application project. When I try to run mvn mn:run

10:52:26.046 [main] INFO io.micronaut.runtime.Micronaut - No embedded container found. Running as CLI application

This only works if I directly add micronaut-runtime module in the current project pom. Even though micronaut-runtime comes transitively from other java library.

Why this is happening ?

Actual Behaviour

No response

Steps To Reproduce

No response

Environment Information

JDK 11 Micronaut 3.5.1

Example Application

No response

Version

3.5.1

yawkat commented 2 years ago

it just means there's no http server or similar present in the micronaut application. it's not an error.

subash89 commented 2 years ago

@yawkat It works all well when I add micronaut-runtime dependency to my pom.xml directly. Not working when I get micronaut comes from a different dependency as follows. Is there a way to tell micronaut where to load the classes, like a package path ? Beause it clearly does not like when micronaut maven dependency comes transitively.

project-y pom.xml Here I have Micronaut Main method, all micronaut dependencies etc.

project-x pom.xml This project use project-y and provide the jaxrs resource class.

    <dependency>
      <groupId>com.myapp.core</groupId>
      <artifactId>project-y</artifactId>
    </dependency>

And inside this project-x I do mvn mn:run. And it complains no container.

yawkat commented 2 years ago

@alvarosanchez think this might be related to maven? i would think the classpath for both setups would be basically the same.

subash89 commented 2 years ago

@yawkat found something else also related. Added direct dependency so I can start micronaut for the moment. There's a @Singleton class in project-y. And if I try to inject that in my project-x's jaxrs resource class, it will complain

Caused by: io.micronaut.context.exceptions.NoSuchBeanException: No bean of type [org.example.ExampleService] exists. Make sure the bean is not disabled by bean requirements (enable trace logging for 'io.micronaut.context.condition' to check) and if the bean is enabled then ensure the class is declared a bean and annotation processing is enabled (for Java and Kotlin the 'micronaut-inject-java' dependency should be configured as an annotation processor).
    at io.micronaut.context.DefaultBeanContext.resolveBeanRegistration(DefaultBeanContext.java:2778)
    at io.micronaut.context.DefaultBeanContext.getBean(DefaultBeanContext.java:1594)
    at io.micronaut.context.AbstractBeanResolutionContext.getBean(AbstractBeanResolutionContext.java:66)
    at io.micronaut.context.AbstractInitializableBeanDefinition.resolveBean(AbstractInitializableBeanDefinition.java:2055)
    ... 29 common frames omitted

I think for same reason, things in a different project/dependency, it does not like it. Even singletons.

Is there any set of dependencies that micronaut does not like other projects to bring ? If so then I can try excluding all those from external dependency to see i f it work.

alvarosanchez commented 2 years ago

@subash89 the setup you are trying is not really supported. The Micronaut Maven Plugin has only been tested when added to Micronaut applications.

That said, if you share a reproducible example, I can take a look

subash89 commented 2 years ago

@alvarosanchez Thanks for the response. I am preparing a project to recreate this easily. Meanwhile can you tell me whether we must use micronaut maven plugin ? Is there any other way like a creating a shaded jar and run it like java -jar? (I tried that too, it complains about some invalid signature of the manifest of the jar).

alvarosanchez commented 2 years ago

Running a shaded jar works, but again, this is only supported when using the Micronaut Maven Plugin

subash89 commented 2 years ago

Can you clarify a bit ? My understanding was, micronaut maven plugin does not need a shade plugin. Is there any example project I can refer to

subash89 commented 2 years ago

projecty.zip projectx.zip

Added two projects as in the above scenario.

  1. Build project x.(mvn clean install)
  2. Go inside projectx and do mvn mn:run
  3. Then curl -i --header "AppId: 123" http://localhost:8080/hello

This will throw that error No bean of type [my.micronaut.core.ServiceX] exists. Basically project x trying to use a Singleton defined in project y. This is necessary if you want to maintain a set of common functionalities as a library and distribute it to teams who want to use them with in an org.

subash89 commented 2 years ago

When further troubleshooting, since project-y is a regular java module, it won't do anything at compile time like a micronaut project like project-x do. So I tried to add micronaut dependencies and annotation processor to project-y as well. Then when I compile the project-y jar, it went fine and the jar now has all micronaut META-INF services etc. But then when I try to compile project-x again, it complains following.

Related to this issue,

Caused by: io.micronaut.context.exceptions.NonUniqueBeanException: Multiple possible bean candidates found: [io.micronaut.aop.InterceptorRegistry, io.micronaut.aop.InterceptorRegistry] at io.micronaut.context.DefaultBeanContext.findConcreteCandidate(DefaultBeanContext.java:2445) at io.micronaut.context.DefaultApplicationContext.findConcreteCandidate(DefaultApplicationContext.java:484) at io.micronaut.context.DefaultBeanContext.lastChanceResolve(DefaultBeanContext.java:3222) at io.micronaut.context.DefaultBeanContext.findConcreteCandidateNoCache(DefaultBeanContext.java:3113) at io.micronaut.context.DefaultBeanContext.findConcreteCandidate(DefaultBeanContext.java:3031) at io.micronaut.context.DefaultBeanContext.findBeanDefinition(DefaultBeanContext.java:784) at io.micronaut.context.DefaultBeanContext.resolveBeanRegistration(DefaultBeanContext.java:2763) at io.micronaut.context.DefaultBeanContext.getBean(DefaultBeanContext.java:1594) at io.micronaut.context.DefaultBeanContext.getBean(DefaultBeanContext.java:863) at io.micronaut.context.DefaultBeanContext.getBean(DefaultBeanContext.java:855) at io.micronaut.aop.chain.InterceptorChain.resolveInterceptors(InterceptorChain.java:205) at io.micronaut.aop.chain.InterceptorChain.resolveAroundInterceptors(InterceptorChain.java:125) at example.micronaut.$HelloResource$Definition$Intercepted.<init>(Unknown Source) at example.micronaut.$HelloResource$Definition$Intercepted$Definition.build(Unknown Source) at io.micronaut.context.DefaultBeanContext.resolveByBeanFactory(DefaultBeanContext.java:2331) ... 94 common frames omitted

subash89 commented 2 years ago

@alvarosanchez @yawkat is there a way to define via compiler plugin, to say use only these packages at compile time to avoid "Multiple possible bean candidates found" . Other than that, cannot think of a way we can achieve this. Any other way?

subash89 commented 2 years ago

Turns out micronaut-parent pom is a must to compile a micronaut project, and then only it create those META-INF bean references in the built jar. So in order to achieve original scenario, I tried adding micronaut parent pom and annotation processors to a existing project that has bunch of Java code, libraries like jersey, database dependencies etc.

I am not sure what the parent pom plugins does, but I see very weird behaviors, like compilation fails on complaining some totally irrelevant Classes in regular "cannot find symbol" style errors. The moment I take out micronaut-parent, the project compiles fine.

The reason I mentioned above example is, have we proved that we can compile any arbitrary java-maven project via micronaut compiler plugin ?

yawkat commented 2 years ago

FYI alvaro is currently on vacation. It may take a while for him to respond.

alvarosanchez commented 2 years ago

@subash89 I yet need to find some time to check your example, but to shed some light:

  1. The Parent POM it's not the only way you can make Micronaut work, it's just the only way we support. But at the end of the day, the parent pom it's mostly plugin management with some configuration defaults, and a bunch of properties. You should be able to apply the same configuration to your POM directly.
  2. Note that the Parent POM has another parent, io.micronaut:micronaut-bom. That contains all the dependency management for version alignment.
subash89 commented 2 years ago

@alvarosanchez thanks for the response. Yes as you said it;s the plugins that comes from parent and possibly some dependencies. Please let us know when you able to try it out. I tried many options I could think of to isolate this.

subash89 commented 2 years ago

mn-jaxrs.zip @alvarosanchez Got a good example of complications on building third party code with micronaut parent pom. Simple code, only two classes.

Here I attached a sample jaxrs example that using some thrird party code. In this example, mongodb.

  1. Download the attached maven project and do mvn clean install. This will fail saying "cannot find symbol"
  2. Remove micronaut-parent-pom definition from the pom.xml
  3. Build success.
  4. But we know micronaut does not bring any mongodb dependencies. So how this is possible ?

    If you look at the mvn dependency:tree on with and without parent pom of this project, there is a mismatch. Is the plugins trying to manipulate transitive dependencies/versions ?

subash89 commented 2 years ago

Is there anything in micronaut parent pom maven plugins that tries to pull latest versions of transitive dependencies ?