user2577576
user2577576

Reputation:

How does spring-boot:run work with maven?

I'm learning the maven build process, and there's on point of contention that stands out as not making a whole lot of sense.

The way I understand maven, there's the default lifecycles (default, site, clean), each of which has multiple phases. There are some built-in plugins associated with a few phases, and by adding additional plugins, you are able to add extra functionality to the pre-existing phases.

When you specify a phase to run directly within maven, it will go through all the phases up to this point within the same lifecycle, and end with executing your specified phase. To the best of my knowledge however, spring-boot:run is a goal, and thus should not invoke other phases when run. That being said, running spring-boot:run via maven does run other phases (default-cli, pre-unit-test, default-resources, reserve-container-port, and some others). It looks to me that spring has created some new phases (reserve-container-port for instance), but I'm not sure how to find the jar file in which the configuration for these is located.

My questions thus are twofold:

  1. Is spring-boot:run a goal as I understand it to be? If so, how does running this goal in turn run other phases? To the best of my knowledge, only specifying a phase as a target will run the other previous phases in order, not directly specifying a goal.
  2. Where is the configuration file for all of this located? In which spring jar file can I find the configuration file that lets all of the above work correctly.

Upvotes: 6

Views: 16054

Answers (3)

Ahmed HENTETI
Ahmed HENTETI

Reputation: 1128

Is spring-boot:run a goal as I understand it to be

In fact, spring-boot is a maven plugin and run is one of its goals.

Here is the official documentation of this plugin.

In that documentation, I didn't find the default maven phase in which this goal is executed. But from the GitHub source code, I founnd out that this goal is executed in the TEST_COMPILE phase.

only specifying a phase as a target will run the other previous phases in order, not directly specifying a goal.

In fact, this is how maven works. Here is an introduction to the maven lifecycle.

Where is the configuration file for all of this located?

It is defined in your spring-boot pom parent:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>${spring-boot-starter-parent.version}</version>
</parent>

Upvotes: 6

Mark Bramnik
Mark Bramnik

Reputation: 42461

To directly answer your question from maven's standpoint:

All the stuff about the lifecycles, phases and associated plugins - you've got it correctly.

However, you miss one point, in maven it is possible to directly run plugin's goal. Think about these goals as logical unit of code that does something, a class with method "main" if you wish that you can run, give it parameters and so forth.

In maven's plugins world, a piece of code in plugin associated with a goal is called a Mojo, a class that maven can execute.

So one plugin contains at least one mojo, its possible that it will contain many if plugin developers decide that it should do many related things. Here is an example of a plugin having 4 different goals ( Mojos in code of the plugin itself) as of now.

So, the syntax of this direct invocation is:

mvn plugin-groupId:plugin-artifactId:plugin-version:goal
mvn plugin-groupId:plugin-artifactId:goal
mvn plugin-prefix:goal

Under some conditions (see official maven documentation), you can omit some of this syntax and this is exactly what happens in your case.

Of course, when you run goals directly like this it completely bypasses the lifecycle execution with phases and everything, so if you, say, want to run directly the goal of tests, but you've never compiled the tests, it will fail. Example:

mvn test // run all phases of the default lifecycle including compilation, tests 
         // compilation, test execution - will succeed on a "clean" project

mvn surefire:test // run directly a goal called "test" inside plugin called "surefire"

The same thing happens with mvn spring-boot:run

You're running spring boot maven plugin, maven resolves the version of the plugin to the version of the build since you don't specify it and then runs a goal called "run"

Upvotes: 3

user2577576
user2577576

Reputation:

As the other answer misses a bit of the information I was looking for, I thought I'd add the results of my research in case anyone else is curious. Looking in

C:\HOME_DIR.m2\repository\org\springframework\boot\spring-boot-maven-plugin\VERSION_NUMBER\META-INF\maven\plugin.xml

gives the configuration file for most of the related goals for spring with maven. Specifically, the snippet below describes how the spring-boot:run goal works.

<mojo>
      <goal>run</goal>
      <description>Run an executable archive application.</description>
      <requiresDependencyResolution>test</requiresDependencyResolution>
      <requiresDirectInvocation>false</requiresDirectInvocation>
      <requiresProject>true</requiresProject>
      <requiresReports>false</requiresReports>
      <aggregator>false</aggregator>
      <requiresOnline>false</requiresOnline>
      <inheritedByDefault>true</inheritedByDefault>
      <phase>validate</phase>
      <executePhase>test-compile</executePhase>
      <implementation>org.springframework.boot.maven.RunMojo</implementation>
      <language>java</language>
      <instantiationStrategy>per-lookup</instantiationStrategy>
      <executionStrategy>once-per-session</executionStrategy>
      <since>1.0.0</since>
      <threadSafe>false</threadSafe>
      ...
</mojo>

Specifically, the <executePhase> tag (detailed partially at https://maven.apache.org/developers/mojo-api-specification.html), which (I believe) lets this goal execute a different phase as it's run.

I missed this detail before (it doesn't seem to be documented anywhere very well either). Either way, this explanation is satisfactory enough for me. If anyone finds better documentation for this tag, I'd appreciate a link :)

Upvotes: 5

Related Questions