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

feat!(generator): load endpoints from Spring components and stop using Maven/Gradle at each generation #2616

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

Conversation

cromoteca
Copy link
Contributor

@cromoteca cromoteca commented Jul 18, 2024

Removes the need of calling Maven (or Gradle) at each code generation during development.

Endpoints are now searched between the available Spring Beans. When building for production mode, since the application is not running, some code provided by Spring is run to be able to get a list of beans as if the application was running.

The generator configuration through Maven is no longer possible, since the application can be run directly as a main class. The idea is to provide it as a singleton, which should become a Spring bean. At the moment, it's just an ordinary class and cannot be configured externally, but since that's internal code, the change can happen in future, when some configuration means has been chosen.

Gradle support is work in progress, not tested (doesn't even compile, actually).

Many tests are touched by these changes and some no longer work, so further fixes are needed, to the tests themselves to accommodate for the new workflow, or to the code if those tests should keep passing.

The new annotations package should probably be renamed as it also contains a type.

@cromoteca cromoteca force-pushed the feat/avoid-running-maven branch 4 times, most recently from 30c2e88 to 236efd5 Compare July 31, 2024 16:36
@cromoteca cromoteca changed the title feat!(generator): avoid running Maven at each generation feat!(generator): load endpoints from Spring components and stop using Maven/Gradle at each generation Oct 17, 2024
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you consider the introduction of an interface to make the endpoint search independent of Spring AOT?

Something like

    @FunctionalInterface
    public interface EndpointProvider {
        List<Class<?>> findEndpoints(EngineConfiguration configuration) throws ExecutionFailedException;
    }

and making AotEndpointFinder implement it.
The EngineGenerateMojo mojo would then have a @Paramter annotated EngineConfiguration.EndpointProvider field, defaulting to AotEndpointFinder and would simply do var endpoints = endpointProvider.findEndpoints(conf);.

This should allow implementing custom endpoint finders not based on Spring by configuring the plugin; for example the implementation can search a Jandex index.

<endpointProvider implementation="org.vaadin.test.MyEndpointPRovider"></endpointProvider>

Actually, I don't know how to make it work in Gradle, but I suppose this should be possible.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another question: why does it need to run SpringApplicationAotProcessor to find endpoints? Couldn't the scan be done with Flow ClassFinder?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have the general feeling that making Hilla depend more on Spring will actually make easier to isolate Spring dependency. For example, at the moment Spring is heavily used in the connector, but not in the generator.

The whole point of this PR is to let Spring decide which endpoints are available. A single provider must be trusted both in the code generation and in the controller which runs in the application. When they will be coherent, it will be easier to swap the "source of truth".

Concerning the ClassFinder, while I don't know it well, I guess it's just another way to walk the classpath searching for annotated classes. Correct me if I'm wrong, but that's what I'm trying to avoid here: finding too many endpoints, that are in the classpath, but not loaded by Spring.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. Thanks for clarification.

Copy link

codecov bot commented Nov 18, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 92.64%. Comparing base (0e4ba3e) to head (df20ab7).
Report is 5 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #2616   +/-   ##
=======================================
  Coverage   92.64%   92.64%           
=======================================
  Files          83       83           
  Lines        2842     2842           
  Branches      739      739           
=======================================
  Hits         2633     2633           
  Misses        158      158           
  Partials       51       51           
Flag Coverage Δ
unittests 92.64% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.


🚨 Try these New Features:

Copy link

sonarcloud bot commented Nov 22, 2024

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.

3 participants