Discussion:
Problem sharing objects between extension and plugin
Paul Benedict
2018-10-09 15:45:45 UTC
Permalink
Good day. I hope this post is acceptable. I don't mean to "cross post" but
I think my problem may be too difficult for the common question on the user@
list.

I scoured all the MNG tickets regarding extensions and class loading
documentation on the Maven site (and elsewhere), but cannot find a clear
answer to my problem. This problem is a roadblock for my work. I can't seem
to make any headway; so any expedient response would be overwhelmingly
appreciated. This may or may not be related to MNG-6209.

TL;DR link to my user@ list post [1].

The quick summary:
*) Project A (library of @Components and other utility classes)
*) Project B (build plugin)
*) Project C (uses build <extension> of Project A and build <plugin> of
Project B)

The quick problem:
In Project A, there is a lifecycle callback that takes an injected
component from A, and stores it in the plugin context of B. When B
retrieves the object, I receive a "type X cannot be case to type X" error.

Is this intended? I am getting conflicted documentation.
Curiously, the older documentation in SVN is much more descriptive. I wish
this was the one on the site -- if it is still valid. Is it still valid
information? Should this be really what the official mini guide should be?
*) Published 2018-10-15: This is the #1 google hit for "maven class loader"
search [1]. This is on the Maven site itself... There is no mention here a
restriction on extensions and plugins unable to share classes.
*) Published 2018-04-30: This is the #3 google hit for "maven class loader"
search [1]. This is from SVN... There is mention here that "it is not
possible" for extensions and plugins to share classes.

Lastly, if the last documentation is the truth, is there any escape hatch?
IMO, it is very valuable when a build extension is able to setup one-time
data that plugins can later use. In my use case, I had to retrieve some
complex information, which then allowed me to dynamically add a dependency
to the build -- but I don't want to lose the ancillary information that
went with the retrieval. I want that available to the plugin for further
logic. Thoughts, please?

References:
[1]
https://lists.apache.org/thread.html/341a92e7b9b4dab328077d32a8490df3bc9866c544bfcc03b5e4c6d9@%3Cusers.maven.apache.org%3E
[2] https://maven.apache.org/guides/mini/guide-maven-classloading.html
[3]
https://svn.apache.org/repos/infra/websites/production/maven/content/reference/maven-classloading.html

Cheers and God bless,
Paul
Robert Scholte
2018-10-09 18:22:52 UTC
Permalink
MNG-6209 is indeed the first issue that comes to my mind and I wonder if
this is fixed. I thought it was reverted after issues with the 3.5.1
release.

Together with Stephen we've tried to define how this should work.
He wrote some tests[1] to demonstrate the issue.
I've tried to show the difference in behavior between 3.5.0 and the
(cancelled) 3.5.1 Maven releases.

Have a look at it, try to run it and share your experience.
I consider this as a critical bug, but it is in the heart of Maven, not
many dare to touch this part but I think we should once we agree on the
expected behavior.

thanks,
Robert

[1] https://github.com/stephenc/mng-6209
[2]
https://cwiki.apache.org/confluence/download/attachments/2329841/classrealms.pdf?api=v2
Post by Paul Benedict
Good day. I hope this post is acceptable. I don't mean to "cross post" but
list.
I scoured all the MNG tickets regarding extensions and class loading
documentation on the Maven site (and elsewhere), but cannot find a clear
answer to my problem. This problem is a roadblock for my work. I can't seem
to make any headway; so any expedient response would be overwhelmingly
appreciated. This may or may not be related to MNG-6209.
*) Project B (build plugin)
*) Project C (uses build <extension> of Project A and build <plugin> of
Project B)
In Project A, there is a lifecycle callback that takes an injected
component from A, and stores it in the plugin context of B. When B
retrieves the object, I receive a "type X cannot be case to type X" error.
Is this intended? I am getting conflicted documentation.
Curiously, the older documentation in SVN is much more descriptive. I wish
this was the one on the site -- if it is still valid. Is it still valid
information? Should this be really what the official mini guide should be?
*) Published 2018-10-15: This is the #1 google hit for "maven class loader"
search [1]. This is on the Maven site itself... There is no mention here a
restriction on extensions and plugins unable to share classes.
*) Published 2018-04-30: This is the #3 google hit for "maven class loader"
search [1]. This is from SVN... There is mention here that "it is not
possible" for extensions and plugins to share classes.
Lastly, if the last documentation is the truth, is there any escape hatch?
IMO, it is very valuable when a build extension is able to setup one-time
data that plugins can later use. In my use case, I had to retrieve some
complex information, which then allowed me to dynamically add a dependency
to the build -- but I don't want to lose the ancillary information that
went with the retrieval. I want that available to the plugin for further
logic. Thoughts, please?
[1]
[2] https://maven.apache.org/guides/mini/guide-maven-classloading.html
[3]
https://svn.apache.org/repos/infra/websites/production/maven/content/reference/maven-classloading.html
Cheers and God bless,
Paul
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-***@maven.apache.org
For additional commands, e-mail: dev-***@maven.apache.org
Paul Benedict
2018-10-09 20:56:55 UTC
Permalink
For clarity, I was testing against 3.3.9. I tried with 3.5.4 today without
a change in results. However, I did discover something interesting that I
confirmed in both versions...

Given my setup:
*) Utility jar has several plexus components and non-components
*) Utility jar has an AbstractMavenLifecycleParticipant component
*) Plugin has a dependency on the utility jar
*) In target project, utility jar is an <extension> and <plugin> is used

Findings:
1) For the plugin, if the dependent utility jar is set to scope
"compile|test|runtime", I get class duplication. This is the case that
generates the "class X cannot be cast to class X" error. My debugging shows
the extension class loader and the plugin class loader are both using
different Class<X> instantiations.
2) For the plugin, if the dependent utility jar is set to scope "provided",
the COMPONENTS are nicely accessible to both .... but none of the
non-component classes are.

I am still looking for an escape hatch. Each case gives me some progress
but not enough to meet my requirements.

So is this the way Maven or MNG-6209 is meant to work? Is any of this
unexpected to you all?

Cheers and God bless,
Paul
Post by Robert Scholte
MNG-6209 is indeed the first issue that comes to my mind and I wonder if
this is fixed. I thought it was reverted after issues with the 3.5.1
release.
Together with Stephen we've tried to define how this should work.
He wrote some tests[1] to demonstrate the issue.
I've tried to show the difference in behavior between 3.5.0 and the
(cancelled) 3.5.1 Maven releases.
Have a look at it, try to run it and share your experience.
I consider this as a critical bug, but it is in the heart of Maven, not
many dare to touch this part but I think we should once we agree on the
expected behavior.
thanks,
Robert
[1] https://github.com/stephenc/mng-6209
[2]
https://cwiki.apache.org/confluence/download/attachments/2329841/classrealms.pdf?api=v2
Post by Paul Benedict
Good day. I hope this post is acceptable. I don't mean to "cross post" but
list.
I scoured all the MNG tickets regarding extensions and class loading
documentation on the Maven site (and elsewhere), but cannot find a clear
answer to my problem. This problem is a roadblock for my work. I can't seem
to make any headway; so any expedient response would be overwhelmingly
appreciated. This may or may not be related to MNG-6209.
*) Project B (build plugin)
*) Project C (uses build <extension> of Project A and build <plugin> of
Project B)
In Project A, there is a lifecycle callback that takes an injected
component from A, and stores it in the plugin context of B. When B
retrieves the object, I receive a "type X cannot be case to type X" error.
Is this intended? I am getting conflicted documentation.
Curiously, the older documentation in SVN is much more descriptive. I wish
this was the one on the site -- if it is still valid. Is it still valid
information? Should this be really what the official mini guide should be?
*) Published 2018-10-15: This is the #1 google hit for "maven class loader"
search [1]. This is on the Maven site itself... There is no mention
here
Post by Paul Benedict
a
restriction on extensions and plugins unable to share classes.
*) Published 2018-04-30: This is the #3 google hit for "maven class loader"
search [1]. This is from SVN... There is mention here that "it is not
possible" for extensions and plugins to share classes.
Lastly, if the last documentation is the truth, is there any escape hatch?
IMO, it is very valuable when a build extension is able to setup one-time
data that plugins can later use. In my use case, I had to retrieve some
complex information, which then allowed me to dynamically add a dependency
to the build -- but I don't want to lose the ancillary information that
went with the retrieval. I want that available to the plugin for further
logic. Thoughts, please?
[1]
[2] https://maven.apache.org/guides/mini/guide-maven-classloading.html
[3]
https://svn.apache.org/repos/infra/websites/production/maven/content/reference/maven-classloading.html
Post by Paul Benedict
Cheers and God bless,
Paul
---------------------------------------------------------------------
Loading...