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

Allow to run native:compile and native:compile-no-fork from the command-line #273

Closed
snicoll opened this issue Jul 22, 2022 · 9 comments · Fixed by #281
Closed

Allow to run native:compile and native:compile-no-fork from the command-line #273

snicoll opened this issue Jul 22, 2022 · 9 comments · Fixed by #281
Assignees
Labels
enhancement New feature or request maven-plugin Related to Maven plugin
Milestone

Comments

@snicoll
Copy link
Collaborator

snicoll commented Jul 22, 2022

Is your feature request related to a problem? Please describe.
It is not possible to run ./mvnw native:build consistently from the command-line. If you run this goal from a project that you've never built before (i.e. target does not exist yet), this yield the following:

[ERROR] Failed to execute goal org.graalvm.buildtools:native-maven-plugin:0.9.13:build (default-cli) on project demo: Execution default-cli of goal org.graalvm.buildtools:native-maven-plugin:0.9.13:build failed: Cannot invoke "java.io.File.exists()" because "artifactFile" is null

However, if package has run before (potentially with outdated source) it will pick the state of the "latest" time package ran. To avoid that from happening, one can run ./mvnw package native:build.

Describe the solution you'd like
There is a way to instruct a goal that it has to run a phase first. Core maven plugins use this feature so that invoking the goal alone is all that it takes to produces an accurate result.

Spring Boot uses this feature as well for their buildpack integration (i.e. ./mvnw spring-boot:build-image will first build the application and then invoke buildpack on the updated repackaged archive).

This makes then the goal not really suitable to being added to a lifecycle execution, as package would then run twice. Core plugins implement a no-fork goal that does exactly the same thing as the original goal, except it doesn't execute the phase that it needs.

Spring Boot would like to provide a native profile that configures both our buildpack integration, and our NBT integration so that users can choose the tool they want. They can currently run ./mvnw -Pnative spring-boot:build-native. However ./mvnw -Pnative native:build does not work as expected for the reason explained above.

Describe alternatives you've considered
The alternative would be inconsistent command-line options where NBT requires an extra package.

Additional context
See spring-projects/spring-boot#31770

@snicoll snicoll added the enhancement New feature or request label Jul 22, 2022
lazar-mitrovic added a commit to lazar-mitrovic/native-build-tools that referenced this issue Jul 24, 2022
lazar-mitrovic added a commit to lazar-mitrovic/native-build-tools that referenced this issue Jul 24, 2022
Allow running native:build from the command-line graalvm#273
NullPointerException fix graalvm#270
lazar-mitrovic added a commit to lazar-mitrovic/native-build-tools that referenced this issue Jul 27, 2022
Allow running native:build from the command-line graalvm#273 (TODO: fix samples)
NullPointerException fix graalvm#270

Signed-off-by: Lazar Mitrović <lazar.mitrovic@oracle.com>
lazar-mitrovic added a commit to lazar-mitrovic/native-build-tools that referenced this issue Aug 1, 2022
Allow running native:build from the command-line graalvm#273 (TODO: fix samples)
NullPointerException fix graalvm#270
Rename Mojos (use native:compile from the command line)

Signed-off-by: Lazar Mitrović <lazar.mitrovic@oracle.com>
lazar-mitrovic added a commit to lazar-mitrovic/native-build-tools that referenced this issue Aug 1, 2022
Allow running native:build from the command-line graalvm#273 (TODO: fix samples)
NullPointerException fix graalvm#270
Rename Mojos (use native:compile from the command line)

Signed-off-by: Lazar Mitrović <lazar.mitrovic@oracle.com>
lazar-mitrovic added a commit to lazar-mitrovic/native-build-tools that referenced this issue Aug 4, 2022
Allow running native:build from the command-line graalvm#273
NullPointerException fix graalvm#270
Rename Mojos (use native:compile from the command line)

Signed-off-by: Lazar Mitrović <lazar.mitrovic@oracle.com>
@lazar-mitrovic lazar-mitrovic added the maven-plugin Related to Maven plugin label Aug 4, 2022
@lazar-mitrovic lazar-mitrovic self-assigned this Aug 4, 2022
@lazar-mitrovic
Copy link
Collaborator

Fixed by #274, as now we have native:compile goal.

@snicoll
Copy link
Collaborator Author

snicoll commented Aug 6, 2022

Thanks for the update. Is the change of name last minute? I don't remember seeing this when I reviewed the PR.

I can understand why you'd want to avoid the no-fork suffix but artificially changing the name of the goal isn't a good idea IMO.

Can we please reconsider adding the build goal as it was in the PR? The arguments for it are that they're doing the same thing and having another goal is strange. Users will wonder what is the difference between build and compile. Finally the no-fork suffix is well known in the Maven community and official plugins make use of it.

@sdeleuze sdeleuze added this to the 0.9.14 milestone Aug 8, 2022
@sdeleuze
Copy link
Collaborator

sdeleuze commented Aug 8, 2022

I also think native:compile is confusing and I am surprised by such change without discussion, as a consequence I reopen this issue.

To recap, we suggest to have mvn native:build as proposed initially for the command line, and have native:build-no-fork for execution configuration:

<execution>
  <id>build-native</id>
  <goals>
    <goal>build-no-fork</goal>
  </goals>
</execution>

This breaking change should be mentioned in the changelog and documented.

@sdeleuze sdeleuze reopened this Aug 8, 2022
@lazar-mitrovic
Copy link
Collaborator

lazar-mitrovic commented Aug 8, 2022

Hey, I added this change a long time ago, I saw that @snicoll commented on this so I thought that he noticed the change.

In the current state, my change isn't a breaking one. My reasoning was that we should have the same invocation as in Gradle:

gradle nativeCompile
mvn native:compile

as nativeBuild was deprecated in Gradle a long time ago.
That way, users that have already pinned the build goal to the package phase can just continue using it.
That would also greatly reduce the amount of bug reports related to the breaking change: flipping the meaning of build and build-no-fork.

However, I see your point that having a different verb is nasty. What I want to suggest is a different, but similar solution:

mvn native:compile # forking goal
# <goal>compile-no-fork</goal> <!-- a non forking goal -->
# <goal>build</goal> <!-- a non forking goal that is annotated with @Deprecated and outputs a warning-->

That way we have the best of both worlds:

  • same nomenclature for Maven and Gradle
  • we have a deprecation process for the build goal
  • we have a no-fork goal along the same named forking goal

WDYT @sdeleuze, @snicoll ?

@sdeleuze
Copy link
Collaborator

sdeleuze commented Aug 8, 2022

I think I am ok with this proposal, but let see how we should handle things on testing side in a profile-less fashion.

@snicoll
Copy link
Collaborator Author

snicoll commented Aug 8, 2022

-1 on using compile with Maven.

I think we need to take a step back and look at what we have irrespective of the limitation or the history as we're pre 1.0. What would be the natural goal that we would pick for this task? Unless we feel that native:build is wrong, then I wouldn't change it.

compile isn't a great candidate for Maven. Such term usually refers to what happens to the compile phase. Having a goal called compile that actually packages an artifact is really strange.

@sdeleuze
Copy link
Collaborator

sdeleuze commented Aug 8, 2022

@snicoll I understand the rationale, but with native:compile (the compile goal from the native plugin) I have the feeling the contextualization is enough and would allow consistency with the Gradle plugin (like for example we try to use the same vocabulary for Spring Boot Maven and Gradle plugins).

I understand that plugins need to adapt to Maven and Gradle specificities, but with mvn native:build on one side and gradle nativeCompile on the other I am afraid users will be lost. So while not perfect, for my own taste advantages are bigger than the drawbacks.

@lazar-mitrovic After discussing with Stéphane, I confirm it won't be possible to implement profile-less native testing so let's keep what we have.

@lazar-mitrovic
Copy link
Collaborator

I'd argue that what we are doing in this goal is actually compilation of java code to an executable file. In order to do that we are utilizing our compiler (along with our virtual machine).

As a part of our push for more streamlined nomenclature, we've dropped image from plugin name: native-image-plugin to native-plugin, because the concept of image is actually an implementation detail of SubstrateVM. Similarly (to my knowledge) native image building is should be replaced with compiling java code to native.

The fact that we need to execute our Mojos in the package phase (as this is the earliest phase in which we can get all of the required information and files), is IMO, also an implementation detail. ELF/PE/MachO file is not a packaging format per se - it is a product of compilation that can by itself later be packaged for deployment.

Yes, we are stretching the definition of phases here, but that is to be expected - Maven is a tool that is built in order to solve a specific problem, and we are trying to make it do something really different. :)

As for breaking changes, I agree that we are in 0.9.x for that exact reason. However this particular change would break literally every project that uses our plugin, with focus on every project that uses it transitively through Spring, Micronaut etc.
And it wouldn't show a nice error message either, it would either "work" by running the phase twice, or it would crash and burn with some random message that would create a lot of noise in the tickets and opened issues.

IMO, even if I thought that the build goal is a better solution, I'd be hesitant to implement it due to this fact alone. I'd much rather have a clean slate and a clear deprecation path.

@snicoll
Copy link
Collaborator Author

snicoll commented Aug 8, 2022

Thanks for the follow-up. If you think that compile is a better goal name for the Maven plugin, then I have no objection.

@sdeleuze sdeleuze changed the title Allow to run native:build from the command-line Aug 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request maven-plugin Related to Maven plugin
3 participants