-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Devmode, Maven: Broken classpath when a local module depends via its parent on another local module #10484
Comments
/cc @quarkusio/devtools |
cc @aloubyansky & @geoand I would have taken a stab this already but it seems some things have to be decided first and I didn't want to jump in the wrong direction. I left all my thoughts under "Additional context" and since I don't think I will have (much) time to work on this in the next few days, you are more than welcome to take the lead. |
Thanks a lot for the analysis @famod! @aloubyansky is the best person to comment on this |
@aloubyansky if you want me to check out something, feel free to ask :) |
Describe the bug
Imagine the following Maven module structure:
level0
level1
depends onlevel0
level2
depends onlevel1
level2.submodule
(depends onlevel1
via parentlevel2
)runner
depends onlevel2
andlevel0
Each
level*
module contains a simple@ApplicationScoped
service that calls the service from the "next-lower" level (e.g.level1
->level0
).runner
contains a REST resource with two methods, one calling thelevel2
service and one directly calling thelevel0
service.Both methods are working as expected with runner-jar, but in devmode the call to
level2
fails in ArC with aNoClassDefFoundError
for thelevel0
service which is very confusing because the direct call tolevel0
does work!This is with the current
master
that includes #10421. With 1.6.0.Final (or any earlier version) which does not yet contain that change, you'll see aClassCastException
instead.Expected behavior
No error, should work in devmode the way it works with runner-jar.
Actual behavior
master
:java.lang.NoClassDefFoundError: org/acme/level0/Level0Service
To Reproduce
Steps to reproduce the behavior:
Configuration
n/a
Screenshots
n/a
Environment (please complete the following information):
uname -a
orver
:java -version
:master
(NCDFE) or 1.6.0.Final or earlier (CCE)mvnw --version
orgradlew --version
):Apache Maven 3.6.3
Additional context
I ran into this issue with Apache CXF: https://quarkusio.zulipchat.com/#narrow/stream/187030-users/topic/ClassCastException.20in.20dev.20mode.20but.20not.20with.20runner-jar
But in the end this has nothing to do with CXF specifically.
I'm 99% sure that I already know the root cause of this bug:
In
DevMojo
,level1
is not added to theDevModeContext
and ends up in theclassPathManifest
which in turn does (of course) not contain any other local projects/modules (which are part of theDevModeContext
).Because of this,
level1
cannot seelevel0
in its classloader (or sees it in a diferent classloader before #10421).level1
is not added to theDevModeContext
becauseLocalProject.collectSelfWithLocalDeps(LocalProject, Set<AppArtifactKey>, List<LocalProject>)
is working withgetRawModel().getDependencies()
, but that will only include the direct dependencies of a module, not the ones it inherits from its parent(s)! (it is just a "raw" model after all!)So it seems that
LocalProject
will have to check the parent models as well, but that would mean custom merging and leaves the question whether this should really be done "by hand" or whether this should be offloaded to some OOTB Maven interpolation instead.There is also a direct usage of
getRawModel().getDependencies()
inDevMojo.filterExtensionDependencies()
.There are also some more methods in
LocalProject
that are not considering any parent(s), see usages ofrawModel.getBuild()
.PS: From a design perspective, IMHO,
rawModel
should not be exposed like this byLocalProject
.I'd also strongly suggest to introduce a model cache to avoid costly re-parsing of already parsed parents.
The text was updated successfully, but these errors were encountered: