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

Use maven embedder #68

Draft
wants to merge 76 commits into
base: main
Choose a base branch
from
Draft

Conversation

fabapp2
Copy link
Contributor

@fabapp2 fabapp2 commented Feb 9, 2024

What needs to be done?

Spike to figure out how to replace the custom Maven parsing with something more solid.

Why does it need to be done?

The parsing of Maven projects is implemented with (naive) custom code that parses trivial and most common Maven projects. But, it has many limitations compared to Maven's parsing capabilities.
Attempting to remove these limitations would require a reimplementation of Maven's parsing logic which is not feasible.

Requirements

  • Maven's internals need to be accessed to e.g. retrieve the resolved Paths to the jars on the classpath, these can change depending on e.g. profile settings
  • The internals can be retrieved from MavenSession.
  • MavenSession is accessible through Maven ExecutionListeners
  • The ExecutionListeners can be registered on the MavenExecutionRequest
  • To access the required internals it is required to register an ExecutionListener and retrieve the session when the build is finished.
  • The PLexusContainer setup and Maven internals are no trivial and a solution should use Maven code whenever possible

Options

Different options exist to execute Maven goals from Java code.
These are the options I am aware of and have looked into:

  • MavenInvoker
    • Invoker
    • Can be started from inside JVM
    • executes Maven on command line starting the Maven build in an external process with no access to internals
    • Can "only" access the command output but not intercept the execution, e.g. with a listener.
    • It requires M2_HOME or MAVEN_HOME to point to a Maven install
  • MavenEmbedder
    • Simulates the CLI but executes in the same JVM
    • Does not allow registering an ExecutionListener through MavenCli.
  • Maven Extension
    • Allows access to MavenSession, MavenProject, and others and to register ExecutionListeners
    • Requires the "installation" of a jar on the machine, either in the project META-INF/maven/extension.xml, or (preferably) in a central location ${maven.home}/lib/ext.
    • The extension would still run in the Maven process and the instances re not accessible form outside
  • Maven Plugin
    • Separate process
  • Shrinkwrap EmbeddedMaven ☑️
    • Has a EmbeddedMaven class that allows executing Maven goals. It defines a withMavenInvoker method that takes a org.apache.maven.shared.invoker.InvocationRequest. This code does what's required (it seems)
    • Scanning PropagateExecutionContextMojo makes me think if the approach could work for the current problem as well.
    • Provides a "Embedded Gradle API" too
  • Reimplementation of Maven parsing
    • That was the current approach after the classpath issues in Boot application after using Maven Internals
    • Not feasable
    • Maven internals
      • We had problems when used in a Boot application. The ClassWorld class loading was conflicting with Boot class loading
      • Probably more complexity to come

Solution

None of the solutions above fulfill the requirements.
But, the MavenCli has everything required to start a Maven build from within the same JVM process.
It hides the access to the MavenExecutionResult.
I created a shameless copy of the MavenCli and provide the listener through this implementation.
This guarantees that the build is as close as possible to what Maven does with the EmbeddedMaven.

  • WIP

  • Check if OpenRewrite's build plugin code can be incorporated as is to reuse as much of their logic as possible.

  • Solve ClassLoader conflicts with ClassWorld running in a Spring Boot application 🤞

@fabapp2 fabapp2 force-pushed the use-maven-embedder branch from 4de042b to 4244f98 Compare March 22, 2024 12:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant