Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev mode pulls in dependencies from Maven profiles of other modules if profile with same name is present in parent #19152

Closed
famod opened this issue Aug 1, 2021 · 10 comments
Labels
Milestone

Comments

@famod
Copy link
Member

famod commented Aug 1, 2021

Describe the bug

Ok, that's a very dodgy one:

Imagine you have a multi module Maven project with:

  • parent contains a Maven profile mocks with nothing in it (!)
    • core
      • contains a service that depends on a bean implementing SupportInterface
      • produces a secondary jar from test-classes with classifier mocks that includes a producer that produces a Mockito Mock for SupportInterface (via @AlternativePriority(-1))
    • support
      • contains the "real" implementation of SupportInterface
      • contains a Maven profile mocks (same name as in parent!) that defines dependency on mocks jar from core
    • dist depends on all other modules and is the place where dev mode is started

Please note that the mocks profile in support doesn't make much sense here as support is already providing the "real" implementation. In my real project we have a few other modules that have such a profile (not the support one which is actually called idp), but I wanted to keep the numbers of modules to an absolute minimum and decided to describe the setup of the reproducer instead of my real project.

So with this setup, when calling mvn clean quarkus:dev -f dist -Pmocks and calling the rest resource, instead of using the "real" impl of the interface from support, the mock producer from the secondary mocks core jar is called.
To make things worse, a NoClassDefFoundError is thrown for SupportInterface which highlights that something in dev mode Maven bootstrapping (and classloading) is really going wrong with this setup.

Expected behavior

Dependencies in profiles of upstream modules don't leak into dev mode started in the current module, even if a profile with the same name is activated that is defined in the parent/root pom.xml of the project.

Actual behavior

Dependencies in such profiles from upstream modules must not be pulled in. Only dependencies in activated profiles defined in the current module or any of the current modules' parent(s) may be pulled in.

How to Reproduce?

  1. clone https://github.com/famod/modmono-quarkus
  2. switch to issue-19152-devmode-mvnprofile
  3. mvn clean install
  4. mvn clean quarkus:dev -f dist -Pmocks
  5. as an early indication of the problem you should see something like:
    Listening for transport dt_socket at address: 5005
    :::: file:/home/famod/.m2/repository/com/github/famod/modmono-quarkus/modmono-quarkus-core/1.0-SNAPSHOT/modmono-quarkus-core-1.0-SNAPSHOT-mocks.jar
    
    which is the an output of SupportMockProducer when its class is being loaded (which should not happen at all!).
  6. curl http://localhost:18080/hello -> NoClassDefFoundError: com/github/famod/modmono_quarkus/support/SupportInterface

Output of uname -a or ver

Linux BIGBLUE 4.19.128-microsoft-standard #1 SMP Tue Jun 23 12:58:10 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

Output of java -version

OpenJDK 64-Bit Server VM AdoptOpenJDK-11.0.11+9 (build 11.0.11+9, mixed mode)

GraalVM version (if different from Java)

n/a

Quarkus version or git rev

2.0.3.Final and 2.1.0.Final

Build tool (ie. output of mvnw --version or gradlew --version)

Apache Maven 3.8.1

Additional information

What I found additionally dodgy is that when I do not use clean to start dev mode, the results are inconsistent:

  • mvn quarkus:dev -f dist -> 🟢
  • mvn quarkus:dev -f dist -Pmocks -> 🟢⚡
  • mvn clean quarkus:dev -f dist -Pmocks -> 🔴
  • mvn quarkus:dev -f dist -> 🔴⚡
  • mvn clean quarkus:dev -f dist -> 🟢

Btw, <type>test-jar</type> doesn't change anything and mvn dependency:tree -f dist -Pmocks shows no sign of the mocks jar.

I can work around this specific case via @UnlessBuildProperty (or similar) on the producer but that might not work for other variations.

See also: https://quarkusio.zulipchat.com/#narrow/stream/187030-users/topic/Producer.20in.20src.2Ftest.2Fjava.20vs.2E.20dev.20mode

@famod famod added the kind/bug Something isn't working label Aug 1, 2021
@quarkus-bot
Copy link

quarkus-bot bot commented Aug 1, 2021

/cc @quarkusio/devtools

famod added a commit to famod/modmono-quarkus that referenced this issue Aug 1, 2021
@famod
Copy link
Member Author

famod commented Aug 1, 2021

To add more sense to this setup:
We have a qdev profile in our root pom.xml that configures some global stuff for dev mode (e.g. <buildGoal>quarkus:dev</buildGoal>, bind to 0.0.0.0 for WSL2 etc.) and to support starting dev mode with a fraction of our app, certain modules add specific things to qdev (e.g. mock producer jar from core) by defining their own qdev profiles.
While profiles are not really "extendable" due to how Maven handles them, this still allows us to get what we want (basic properties and settings plus module specific dev mode dependencies and maybe also further properties).

@geoand
Copy link
Contributor

geoand commented Aug 2, 2021

cc @aloubyansky

@famod
Copy link
Member Author

famod commented Aug 10, 2021

@aloubyansky are you going to look at this anytime soon? (welcome back, btw)

@aloubyansky
Copy link
Member

Yes, I was going to. I have a few issues accumulated during my absence, so a bit slow.

@famod
Copy link
Member Author

famod commented Aug 10, 2021

Alright, please let me know if/how I can support. I might be slow to respond as I'm very busy in these last days before my PTO.

@aloubyansky
Copy link
Member

The clean use-case is expected. We cache/persist the app model on the disk disk and re-use it on the next launch.

@aloubyansky
Copy link
Member

Just to clarify, if you execute mvn clean package -Pmocks from the root dir the mocks jar is expected to end up in the in lib dir (and so mvn clean quarkus:dev -Pmocks launched from the root is expected to add the mocks jar to the classpath) but using -f dist -Pmocks is supposed to activate the profile only in the specified module.

mvn clean package -Pmocks -f dist does not include the mocks jar in the lib.

@famod
Copy link
Member Author

famod commented Aug 10, 2021

FTR (as discussed on Zulip):

  • I fixed a dependency problem in the support module of the reproducer
  • the problem also occurs if cd-ing into dist
  • if running from root without -f (or -pl), -Pmocks is expected to pull in the dependency from the profile in support (as per Maven default behavior)

@famod
Copy link
Member Author

famod commented Dec 27, 2021

Not seeing this anymore in 2.4.0.CR1 or newer. Might have been fixed in #20500. /cc @aloubyansky

@famod famod closed this as completed Dec 27, 2021
@famod famod added this to the 2.4.0.CR1 milestone Dec 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants