Code Monkey home page Code Monkey logo

gs-multi-module's Introduction

This guide shows you how to create a multi-module project with Spring Boot. The project will have a library jar and a main application that uses the library. You could also use it to see how to build a library (that is, a jar file that is not an application) on its own.

What You Will Build

You will set up a library jar that exposes a service for simple “Hello, World” messages and then include the service in a web application that uses the library as a dependency.

Create a Root Project

This guide walks through building two projects, one of which is a dependency to the other. Consequently, you need to create two child projects under a root project. But first, create the build configuration at the top level. For Maven you will want a pom.xml with <modules> listing the subdirectories:

link:complete/pom.xml[role=include]

For Gradle, you will want a settings.gradle including the same directories:

link:complete/settings.gradle[role=include]

and (optionally) you could include an empty build.gradle (to help IDEs identify the root directory).

Create the Directory Structure

In the directory that you want to be your root directory, create the following subdirectory structure (for example, with mkdir library application on *nix systems):

└── library
└── application

In the root of the project, you will need to set up a build system, and this guide shows you how to use Maven or Gradle.

Create the Library Project

One of the two projects serves as a library that the other project (the application) will use.

Create the Directory Structure

In a the library directory, create the following subdirectory structure (for example, by using mkdir -p src/main/java/com/example/multimodule/service on *nix systems):

└── src
    └── main
        └── java
            └── com
                └── example
                    └── multimodule
                        └── service

Now you need to configure a build tool (Maven or Gradle). In both cases, note that the Spring Boot plugin is not used in the library project at all. The main function of the plugin is to create an executable “über-jar”, which we neither need nor want for a library.

Although the Spring Boot Maven plugin is not being used, you do want to take advantage of Spring Boot dependency management, so that is configured by using the spring-boot-starter-parent from Spring Boot as a parent project. An alternative would be to import the dependency management as a Bill of Materials (BOM) in the <dependencyManagement/> section of the pom.xml file.

Setting up the Library Project

For the Library project, you need not add dependencies. The basic spring-boot-starter dependency provides everything you need.

You can get a Maven build file with the necessary dependencies directly from the Spring Initializr. The following listing shows the pom.xml file that is created when you choose Maven:

link:initial/library/pom.xml[role=include]

You can get a Gradle build file with the necessary dependencies directly from the Spring Initializr. The following listing shows the build.gradle file that is created when you choose Gradle:

link:initial/library/build.gradle[role=include]

Adjusting the Library Project

If you generated the Library project from start.spring.io it will contain a wrapper script for the build system (mvnw or gradlew depending on the choice you made). You can move that script and its associated configuration up to the root directory:

$ mv mvnw* .mvn ..
$ mv gradlew* gradle ..

It is better that the library depends on the most narrowed dependencies, and not a starter. For our own use there org.springframework.boot:spring-boot has all the code that we need. Removing the -starter of the existing entry makes sure the library doesn’t bring up too much dependencies.

The Library project has no class with a main method (because it is not an application). Consequently, you have to tell the build system to not try to build an executable jar for the Library project. (By default, the Spring Initializr builds executable projects.)

To tell Maven to not build an executable jar for the Library project, you must remove the following block from the pom.xml created by the Spring Initializr:

<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
  </plugins>
</build>

The following listing shows the final pom.xml file for the Library project:

link:complete/library/pom.xml[role=include]

To tell Gradle to not build an executable jar for the Library project, you must add the following blocks to the build.gradle created by the Spring Initializr:

plugins {
  id 'org.springframework.boot' version '3.2.2' apply false
  id 'io.spring.dependency-management' version '1.1.4'
  // ... other plugins
}

dependencyManagement {
  imports {
    mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES
  }
}

The bootJar task tries to create an executable jar, and that requires a main() method. As a result, you need to disable it by disabling the the Spring Boot plugin, while keeping it for its dependency management features.

Also, now that we have disabled the Spring Boot plugin, it no longer automatically configures the JavaCompiler task to enable the -parameters option. This is important if you are using an expression that refers to a parameter name. The following enables this option:

tasks.withType(JavaCompile).configureEach {
  options.compilerArgs.add("-parameters")
}

The following listing shows the final build.gradle file for the Library project:

link:complete/library/build.gradle[role=include]

Create a Service Component

The library will provide a MyService class that can be used by applications. The following listing (from library/src/main/java/com/example/multimodule/service/MyService.java) shows the MyService class:

link:complete/library/src/main/java/com/example/multimodule/service/MyService.java[role=include]

To make it configurable in the standard Spring Boot idiom (with application.properties), you can also add a @ConfigurationProperties class. The ServiceProperties class (from library/src/main/java/com/example/multimodule/service/ServiceProperties.java) fills that need:

link:complete/library/src/main/java/com/example/multimodule/service/ServiceProperties.java[role=include]

You need not do it this way. A library might merely provide pure Java APIs and no Spring features. In that case, the application that consumes the library would need to provide the configuration itself.

Testing the Service Component

You will want to write unit tests for your library components. If you provide re-usable Spring configuration as part of the library, you might also want to write an integration test, to make sure that the configuration works. To do that, you can use JUnit and the @SpringBootTest annotation. The following listing (from library/src/test/java/com/example/multimodule/service/MyServiceTest.java) shows how to do so:

link:complete/library/src/test/java/com/example/multimodule/service/MyServiceTest.java[role=include]
Note
In the preceding listing, we have configured the service.message for the test by using the default attribute of the @SpringBootTest annotation. We do not recommend putting application.properties in a library, because there might be a clash at runtime with the application that uses the library (only one application.properties is ever loaded from the classpath). You could put application.properties in the test classpath but not include it in the jar (for instance, by placing it in src/test/resources).

Create the Application Project

The Application project uses the Library project, which offers a service that other projects can use.

Create the Directory Structure

In the application directory, create the following subdirectory structure (for example, with mkdir -p src/main/java/com/example/multimodule/application on *nix systems):

└── src
    └── main
        └── java
            └── com
                └── example
                    └── multimodule
                        └── application

Do not use the same package as the library (or a parent of the library package) unless you want to include all Spring components in the library by @ComponentScan in the application.

Setting up the Application Project

For the Application project, you need the Spring Web and Spring Boot Actuator dependencies.

You can get a Maven build file with the necessary dependencies directly from the Spring Initializr. The following listing shows the pom.xml file that is created when you choose Maven:

link:initial/application/pom.xml[role=include]

You can get a Gradle build file with the necessary dependencies directly from the Spring Initializr. The following listing shows the build.gradle file that is created when you choose Gradle:

link:initial/application/build.gradle[role=include]

You can delete the mvnw and/or gradlew wrappers and their associated configuration files:

$ rm -rf mvnw* .mvn
$ rm -rf gradlew* gradle

Adding the Library Dependency

The Application project needs to have a dependency on the Library project. You need to modify your Application build file accordingly.

For Maven, add the following dependency:

<dependency>
  <groupId>com.example</groupId>
  <artifactId>library</artifactId>
  <version>${project.version}</version>
</dependency>

The following listing shows the finished pom.xml file:

link:complete/application/pom.xml[role=include]

For Gradle, add the following dependency:

implementation project(':library')

The following listing shows the finished build.gradle file:

link:complete/application/build.gradle[role=include]

Write the Application

The main class in the application can be a @RestController that uses the Service from the library to render a message. The following listing (from application/src/main/java/com/example/multimodule/application/DemoApplication.java) shows such a class:

link:complete/application/src/main/java/com/example/multimodule/application/DemoApplication.java[role=include]

Because DemoApplication is inside a different package (com.example.multimodule.application) than MyService (com.example.multimodule.service), @SpringBootApplication cannot automatically detect it. There are different ways to let `MyService be picked up:

  • Import it directly with @Import(MyService.class).

  • Fetch everything from its package by using @SpringBootApplication(scanBasePackageClasses={…​}).

  • Specifying the parent package by name: com.example.multimodule. (This guide uses this method)

Note
If your application also uses JPA or Spring Data, the @EntityScan and @EnableJpaRepositories (and related) annotations inherit only their base package from @SpringBootApplication when not explicitly specified. That is, once you specify scanBasePackageClasses or scanBasePackages, you might also have to also explicitly use @EntityScan and @EnableJpaRepositories with their package scans explicitly configured.

Create the application.properties File

You need to provide a message for the service in the library in application.properties. In the source folder, you need to create a file named src/main/resources/application.properties. The following listing shows a file that would work:

link:complete/application/src/main/resources/application.properties[role=include]

Test the Application

Test the end-to-end result by starting the application. You can start the application in your IDE or use the command line. Once the application is running, visit the client application in the browser, at http://localhost:8080/. There, you should see Hello, World reflected in the response.

If you use Gradle, the following command (really two commands run in sequence) will first build the library and then run the application:

$ ./gradlew build && ./gradlew :application:bootRun

If you use Maven, the following command (really two commands run in sequence) will first build the library and then run the application:

$ ./mvnw install && ./mvnw spring-boot:run -pl application

Summary

Congratulations! You have used Spring Boot to create a re-usable library and then used that library to build an application.

gs-multi-module's People

Contributors

0scvr avatar bmscomp avatar buzzardo avatar dsyer avatar elarbi avatar exl avatar fuxingloh avatar gregturn avatar robertmcnees avatar snicoll avatar spring-operator avatar wilkinsona avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gs-multi-module's Issues

While listing dependencies of the application module, com.example:multi-module-library:0.0.1-SNAPSHOT FAILED

After the fixes made in #30

To Simulate, In terminal run
cd complete/
then
gradlew application:dependencies --configuration compileClasspath

The console shows the following

> Task :application:dependencies

------------------------------------------------------------
Project :application
------------------------------------------------------------

compileClasspath - Compile classpath for source set 'main'.
+--- org.springframework.boot:spring-boot-starter-actuator -> 2.2.0.RELEASE
|    +--- org.springframework.boot:spring-boot-starter:2.2.0.RELEASE
|    |    +--- org.springframework.boot:spring-boot:2.2.0.RELEASE
|    |    |    +--- org.springframework:spring-core:5.2.0.RELEASE
|    |    |    |    \--- org.springframework:spring-jcl:5.2.0.RELEASE
|    |    |    \--- org.springframework:spring-context:5.2.0.RELEASE
|    |    |         +--- org.springframework:spring-aop:5.2.0.RELEASE
|    |    |         |    +--- org.springframework:spring-beans:5.2.0.RELEASE
|    |    |         |    |    \--- org.springframework:spring-core:5.2.0.RELEASE (*)
|    |    |         |    \--- org.springframework:spring-core:5.2.0.RELEASE (*)
|    |    |         +--- org.springframework:spring-beans:5.2.0.RELEASE (*)
|    |    |         +--- org.springframework:spring-core:5.2.0.RELEASE (*)
|    |    |         \--- org.springframework:spring-expression:5.2.0.RELEASE
|    |    |              \--- org.springframework:spring-core:5.2.0.RELEASE (*)
|    |    +--- org.springframework.boot:spring-boot-autoconfigure:2.2.0.RELEASE
|    |    |    \--- org.springframework.boot:spring-boot:2.2.0.RELEASE (*)
|    |    +--- org.springframework.boot:spring-boot-starter-logging:2.2.0.RELEASE
|    |    |    +--- ch.qos.logback:logback-classic:1.2.3
|    |    |    |    +--- ch.qos.logback:logback-core:1.2.3
|    |    |    |    \--- org.slf4j:slf4j-api:1.7.25 -> 1.7.28
|    |    |    +--- org.apache.logging.log4j:log4j-to-slf4j:2.12.1
|    |    |    |    +--- org.slf4j:slf4j-api:1.7.25 -> 1.7.28
|    |    |    |    \--- org.apache.logging.log4j:log4j-api:2.12.1
|    |    |    \--- org.slf4j:jul-to-slf4j:1.7.28
|    |    |         \--- org.slf4j:slf4j-api:1.7.28
|    |    +--- jakarta.annotation:jakarta.annotation-api:1.3.5
|    |    \--- org.springframework:spring-core:5.2.0.RELEASE (*)
|    +--- org.springframework.boot:spring-boot-actuator-autoconfigure:2.2.0.RELEASE
|    |    +--- org.springframework.boot:spring-boot-actuator:2.2.0.RELEASE
|    |    |    +--- org.springframework.boot:spring-boot:2.2.0.RELEASE (*)
|    |    |    \--- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.10.0
|    |    |         +--- com.fasterxml.jackson.core:jackson-annotations:2.10.0
|    |    |         +--- com.fasterxml.jackson.core:jackson-core:2.10.0
|    |    |         \--- com.fasterxml.jackson.core:jackson-databind:2.10.0
|    |    |              +--- com.fasterxml.jackson.core:jackson-annotations:2.10.0
|    |    |              \--- com.fasterxml.jackson.core:jackson-core:2.10.0
|    |    +--- org.springframework.boot:spring-boot-autoconfigure:2.2.0.RELEASE (*)
|    |    +--- com.fasterxml.jackson.core:jackson-databind:2.10.0 (*)
|    |    +--- org.springframework:spring-core:5.2.0.RELEASE (*)
|    |    \--- org.springframework:spring-context:5.2.0.RELEASE (*)
|    \--- io.micrometer:micrometer-core:1.3.0
|         +--- org.hdrhistogram:HdrHistogram:2.1.11
|         \--- org.latencyutils:LatencyUtils:2.0.3
+--- org.springframework.boot:spring-boot-starter-web -> 2.2.0.RELEASE
|    +--- org.springframework.boot:spring-boot-starter:2.2.0.RELEASE (*)
|    +--- org.springframework.boot:spring-boot-starter-json:2.2.0.RELEASE
|    |    +--- org.springframework.boot:spring-boot-starter:2.2.0.RELEASE (*)
|    |    +--- org.springframework:spring-web:5.2.0.RELEASE
|    |    |    +--- org.springframework:spring-beans:5.2.0.RELEASE (*)
|    |    |    \--- org.springframework:spring-core:5.2.0.RELEASE (*)
|    |    +--- com.fasterxml.jackson.core:jackson-databind:2.10.0 (*)
|    |    +--- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.10.0
|    |    |    +--- com.fasterxml.jackson.core:jackson-core:2.10.0
|    |    |    \--- com.fasterxml.jackson.core:jackson-databind:2.10.0 (*)
|    |    +--- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.10.0 (*)
|    |    \--- com.fasterxml.jackson.module:jackson-module-parameter-names:2.10.0
|    |         +--- com.fasterxml.jackson.core:jackson-core:2.10.0
|    |         \--- com.fasterxml.jackson.core:jackson-databind:2.10.0 (*)
|    +--- org.springframework.boot:spring-boot-starter-tomcat:2.2.0.RELEASE
|    |    +--- jakarta.annotation:jakarta.annotation-api:1.3.5
|    |    +--- org.apache.tomcat.embed:tomcat-embed-core:9.0.27
|    |    +--- org.apache.tomcat.embed:tomcat-embed-el:9.0.27
|    |    \--- org.apache.tomcat.embed:tomcat-embed-websocket:9.0.27
|    |         \--- org.apache.tomcat.embed:tomcat-embed-core:9.0.27
|    +--- org.springframework.boot:spring-boot-starter-validation:2.2.0.RELEASE
|    |    +--- org.springframework.boot:spring-boot-starter:2.2.0.RELEASE (*)
|    |    +--- jakarta.validation:jakarta.validation-api:2.0.1
|    |    \--- org.hibernate.validator:hibernate-validator:6.0.17.Final
|    |         +--- org.jboss.logging:jboss-logging:3.3.2.Final -> 3.4.1.Final
|    |         \--- com.fasterxml:classmate:1.3.4 -> 1.5.0
|    +--- org.springframework:spring-web:5.2.0.RELEASE (*)
|    \--- org.springframework:spring-webmvc:5.2.0.RELEASE
|         +--- org.springframework:spring-aop:5.2.0.RELEASE (*)
|         +--- org.springframework:spring-beans:5.2.0.RELEASE (*)
|         +--- org.springframework:spring-context:5.2.0.RELEASE (*)
|         +--- org.springframework:spring-core:5.2.0.RELEASE (*)
|         +--- org.springframework:spring-expression:5.2.0.RELEASE (*)
|         \--- org.springframework:spring-web:5.2.0.RELEASE (*)
\--- com.example:multi-module-library:0.0.1-SNAPSHOT FAILED

Solution:

Copying gradlew.bat, gradlew files and gradle folder from complete to application, should resolve this.
Next cd to application directory, then execute
gradlew dependencies --configuration compileClasspath

Add license section in readme

Update the LICENSE section in the README file to enhance the presentation. To add license badge and update the text with a cleaner format, including a hyperlink to the LICENSE file.
I would like to work on this issue.

Shouldn't maven parent reference parent POM?

in library and application we both have:

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.4.3</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

but shouldn't it be instead:

	<parent>
		<groupId>org.springframework</groupId>
		<artifactId>gs-multi-module</artifactId>
		<version>0.1.0</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

and have the first one (spring-boot-starter-parent) specified in parent POM?

Refactor to represent a nearer real case.

The advantage of using Maven multi-module layouts is to share commons in the parent pom.
This example is using spring-boot-starter-parent as parent pom in the modules and it is not using the parent pom owned by the project, so I think that it is not a good example.

On the other hand, usually, in a multi-module project, Spring and no Spring modules are mixed. In the case of modules that are not related to Spring we don't want any dependency with it.

So I think that it is necessary to refactor this example to:

  • Refactor parent pom to add common stuff like properties, version, dependency manager for no Spring dependencies, surefire and failsafe configuration, etc.
  • Refactor Spring modules to use the parent pom in the project and use Spring BOM instead of the spring-boot-starter-parent.
  • Add a no-Spring module with no Spring dependencies.

Thoughts??

'bootRun' not found in project ' : for both library and aplication from complete folder in windows

I have used git files with no changes
I have run the following commands:
D:\Backend programs\Gradle\gs-multi-module-master\complete>gradle build

BUILD SUCCESSFUL in 6s
1 actionable task: 1 up-to-date
D:\Backend programs\Gradle\gs-multi-module-master\complete>gradle :library:bootRun

FAILURE: Build failed with an exception.

  • What went wrong:
    Task 'bootRun' not found in project ':library'.

  • Try:
    Run gradle tasks to get a list of available tasks. Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

  • Get more help at https://help.gradle.org

BUILD FAILED in 5s

D:\Backend programs\Gradle\gs-multi-module-master\complete>gradle :library:bootRun --stacktrace

FAILURE: Build failed with an exception.

  • What went wrong:
    Task 'bootRun' not found in project ':library'.

  • Try:
    Run gradle tasks to get a list of available tasks. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

  • Exception is:
    org.gradle.execution.TaskSelectionException: Task 'bootRun' not found in project ':library'.
    at org.gradle.execution.DefaultTaskSelector.getSelection(DefaultTaskSelector.java:113)
    at org.gradle.execution.DefaultTaskSelector.getSelection(DefaultTaskSelector.java:78)
    at org.gradle.execution.CompositeAwareTaskSelector.getSelection(CompositeAwareTaskSelector.java:93)
    at org.gradle.execution.commandline.CommandLineTaskParser.parseTasks(CommandLineTaskParser.java:43)
    at org.gradle.execution.TaskNameResolvingBuildConfigurationAction.configure(TaskNameResolvingBuildConfigurationAction.java:46)
    at org.gradle.execution.DefaultBuildConfigurationActionExecuter.configure(DefaultBuildConfigurationActionExecuter.java:55)
    at org.gradle.execution.DefaultBuildConfigurationActionExecuter.access$000(DefaultBuildConfigurationActionExecuter.java:26)
    at org.gradle.execution.DefaultBuildConfigurationActionExecuter$1.proceed(DefaultBuildConfigurationActionExecuter.java:63)
    at org.gradle.execution.DefaultTasksBuildExecutionAction.configure(DefaultTasksBuildExecutionAction.java:45)
    at org.gradle.execution.DefaultBuildConfigurationActionExecuter.configure(DefaultBuildConfigurationActionExecuter.java:55)
    at org.gradle.execution.DefaultBuildConfigurationActionExecuter.access$000(DefaultBuildConfigurationActionExecuter.java:26)
    at org.gradle.execution.DefaultBuildConfigurationActionExecuter$1.proceed(DefaultBuildConfigurationActionExecuter.java:63)
    at org.gradle.execution.ExcludedTaskFilteringBuildConfigurationAction.configure(ExcludedTaskFilteringBuildConfigurationAction.java:48)
    at org.gradle.execution.DefaultBuildConfigurationActionExecuter.configure(DefaultBuildConfigurationActionExecuter.java:55)
    at org.gradle.execution.DefaultBuildConfigurationActionExecuter.lambda$select$0(DefaultBuildConfigurationActionExecuter.java:42)
    at org.gradle.internal.Factories$1.create(Factories.java:31)
    at org.gradle.api.internal.project.DefaultProjectStateRegistry.withMutableStateOfAllProjects(DefaultProjectStateRegistry.java:141)
    at org.gradle.api.internal.project.DefaultProjectStateRegistry.withMutableStateOfAllProjects(DefaultProjectStateRegistry.java:128)
    at org.gradle.execution.DefaultBuildConfigurationActionExecuter.select(DefaultBuildConfigurationActionExecuter.java:40)
    at org.gradle.initialization.DefaultTaskExecutionPreparer.prepareForTaskExecution(DefaultTaskExecutionPreparer.java:38)
    at org.gradle.initialization.BuildOperationFiringTaskExecutionPreparer$CalculateTaskGraph.populateTaskGraph(BuildOperationFiringTaskExecutionPreparer.java:117)
    at org.gradle.initialization.BuildOperationFiringTaskExecutionPreparer$CalculateTaskGraph.run(BuildOperationFiringTaskExecutionPreparer.java:68)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:56)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$run$1(DefaultBuildOperationExecutor.java:71)
    at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.runWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:45)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:71)
    at org.gradle.initialization.BuildOperationFiringTaskExecutionPreparer.prepareForTaskExecution(BuildOperationFiringTaskExecutionPreparer.java:56)
    at org.gradle.initialization.DefaultGradleLauncher.prepareTaskExecution(DefaultGradleLauncher.java:233)
    at org.gradle.initialization.DefaultGradleLauncher.doClassicBuildStages(DefaultGradleLauncher.java:167)
    at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:148)
    at org.gradle.initialization.DefaultGradleLauncher.executeTasks(DefaultGradleLauncher.java:124)
    at org.gradle.internal.invocation.GradleBuildController$1.create(GradleBuildController.java:72)
    at org.gradle.internal.invocation.GradleBuildController$1.create(GradleBuildController.java:67)
    at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:213)
    at org.gradle.internal.invocation.GradleBuildController.doBuild(GradleBuildController.java:67)
    at org.gradle.internal.invocation.GradleBuildController.run(GradleBuildController.java:56)
    at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:31)
    at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
    at org.gradle.launcher.exec.BuildOutcomeReportingBuildActionRunner.run(BuildOutcomeReportingBuildActionRunner.java:63)
    at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
    at org.gradle.tooling.internal.provider.FileSystemWatchingBuildActionRunner.run(FileSystemWatchingBuildActionRunner.java:77)
    at org.gradle.launcher.exec.BuildCompletionNotifyingBuildActionRunner.run(BuildCompletionNotifyingBuildActionRunner.java:41)
    at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:49)
    at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:44)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:62)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$call$2(DefaultBuildOperationExecutor.java:76)
    at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.callWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:54)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:76)
    at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:44)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.lambda$execute$0(InProcessBuildActionExecuter.java:54)
    at org.gradle.composite.internal.DefaultRootBuildState.run(DefaultRootBuildState.java:86)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:53)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:29)
    at org.gradle.launcher.exec.BuildTreeScopeLifecycleBuildActionExecuter.lambda$execute$0(BuildTreeScopeLifecycleBuildActionExecuter.java:33)
    at org.gradle.internal.buildtree.BuildTreeState.run(BuildTreeState.java:49)
    at org.gradle.launcher.exec.BuildTreeScopeLifecycleBuildActionExecuter.execute(BuildTreeScopeLifecycleBuildActionExecuter.java:32)
    at org.gradle.launcher.exec.BuildTreeScopeLifecycleBuildActionExecuter.execute(BuildTreeScopeLifecycleBuildActionExecuter.java:27)
    at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:104)
    at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:55)
    at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:64)
    at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:37)
    at org.gradle.tooling.internal.provider.SessionScopeLifecycleBuildActionExecuter.lambda$execute$0(SessionScopeLifecycleBuildActionExecuter.java:54)
    at org.gradle.internal.session.BuildSessionState.run(BuildSessionState.java:67)
    at org.gradle.tooling.internal.provider.SessionScopeLifecycleBuildActionExecuter.execute(SessionScopeLifecycleBuildActionExecuter.java:50)
    at org.gradle.tooling.internal.provider.SessionScopeLifecycleBuildActionExecuter.execute(SessionScopeLifecycleBuildActionExecuter.java:36)
    at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:36)
    at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:25)
    at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:59)
    at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:31)
    at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:55)
    at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:41)
    at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:47)
    at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:31)
    at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:65)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:39)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:29)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:35)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:78)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:75)
    at org.gradle.util.Swapper.swap(Swapper.java:38)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:75)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:63)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:84)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
    at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:52)
    at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
    at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
    at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)

  • Get more help at https://help.gradle.org

BUILD FAILED in 5s

D:\Backend programs\Gradle\gs-multi-module-master\complete>gradle :application:bootRun

FAILURE: Build failed with an exception.

  • What went wrong:
    Task 'bootRun' not found in project ':application'.

  • Try:
    Run gradle tasks to get a list of available tasks. Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

  • Get more help at https://help.gradle.org

BUILD FAILED in 5s

Spring boot maven multiple module project run failed with error "Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean".

I followed this project's guide, here is my project Spring Cloud in Practice. When I run one of the module with ./mvnw install && ./mvnw spring-boot:run -pl user, it failed with the following log.

...
2019-12-20 13:33:58.886  INFO 8830 --- [  restartedMain] n.j.scip.user.api.ScipApplication        : Starting ScipApplication on jagger-mbp with PID 8830 (/Users/jagger/projects/jaggerwang/spring-cloud-in-practice/user/target/classes started by jagger in /Users/jagger/projects/jaggerwang/spring-cloud-in-practice/user)
2019-12-20 13:33:58.890  INFO 8830 --- [  restartedMain] n.j.scip.user.api.ScipApplication        : No active profile set, falling back to default profiles: default
2019-12-20 13:33:58.930  INFO 8830 --- [  restartedMain] o.s.b.devtools.restart.ChangeableUrls    : The Class-Path manifest attribute in /Users/jagger/.m2/repository/org/glassfish/jaxb/jaxb-runtime/2.3.2/jaxb-runtime-2.3.2.jar referenced one or more files that do not exist: file:/Users/jagger/.m2/repository/org/glassfish/jaxb/jaxb-runtime/2.3.2/jakarta.xml.bind-api-2.3.2.jar,file:/Users/jagger/.m2/repository/org/glassfish/jaxb/jaxb-runtime/2.3.2/txw2-2.3.2.jar,file:/Users/jagger/.m2/repository/org/glassfish/jaxb/jaxb-runtime/2.3.2/istack-commons-runtime-3.0.8.jar,file:/Users/jagger/.m2/repository/org/glassfish/jaxb/jaxb-runtime/2.3.2/stax-ex-1.8.1.jar,file:/Users/jagger/.m2/repository/org/glassfish/jaxb/jaxb-runtime/2.3.2/FastInfoset-1.2.16.jar,file:/Users/jagger/.m2/repository/org/glassfish/jaxb/jaxb-runtime/2.3.2/jakarta.activation-api-1.2.1.jar
2019-12-20 13:33:58.930  INFO 8830 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2019-12-20 13:33:58.931  INFO 8830 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2019-12-20 13:33:59.109  WARN 8830 --- [  restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
2019-12-20 13:33:59.235 ERROR 8830 --- [  restartedMain] o.s.boot.SpringApplication               : Application run failed

org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:156) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:544) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE]
	at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:140) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE]
	at net.jaggerwang.scip.user.api.ScipApplication.main(ScipApplication.java:48) ~[classes/:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
	at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.2.1.RELEASE.jar:2.2.1.RELEASE]
Caused by: org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getWebServerFactory(ServletWebServerApplicationContext.java:203) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:179) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:153) ~[spring-boot-2.2.1.RELEASE.jar:2.2.1.RELEASE]
	... 12 common frames omitted

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  13.211 s
[INFO] Finished at: 2019-12-20T13:33:59+08:00
[INFO] ------------------------------------------------------------------------

It seems that the embed tomcat servlet container is not auto starting with the application. I checked the jar package, it contains tomcat.

$ jar -tf user/target/spring-cloud-in-practice-user-1.0-SNAPSHOT.jar| grep tomcat
BOOT-INF/lib/spring-boot-starter-tomcat-2.2.1.RELEASE.jar
BOOT-INF/lib/tomcat-embed-core-9.0.27.jar
BOOT-INF/lib/tomcat-embed-el-9.0.27.jar
BOOT-INF/lib/tomcat-embed-websocket-9.0.27.jar

Upgrade Spring Boot to the latest version

Update the guide to use the most recent Spring Boot version.

To do so, change the Spring Boot version in:

initial/build.gradle
initial/pom.xml
complete/build.gradle
complete/pom.xml

Document how to run from command-line

./mvnw clean package spring-boot:run

[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.5.2.RELEASE:run (default-cli) on project gs-multi-module-library: Unable t
o find a suitable main class, please add a 'mainClass' property -> [Help 1]

Test the `complete` directory for 2.0.0.RC1

I usually work with Spring Framework and Gradle with the multimodule approach.
So I know how configure Gradle

I have a situation for a Spring Boot multimodule app through Gradle (version 4.5.1).

Note: it working together with STS 3.9.2.

When I work with the following way: springBootVersion = '2.0.0.RC1'

The dependencies between projects fails.

dependencies {
	compile('org.springframework.boot:spring-boot-starter')
	testCompile('org.springframework.boot:spring-boot-starter-test')
	
	compile project(':boot-04-infrastructure')  <---- practically ignored
		
}

If I change to springBootVersion = '1.5.10.RELEASE' all work fine. (Such as your current code)

I have read: Creating a Multi Module Project and that's why I have arrived to this project sample in Github.

I have downloaded the project, executed the complete directory and all works fine.

I want confirm that this problem would be a bug, but when I do the following updates:

  • build.gradle within application
buildscript {
    ext { springBootVersion = '2.0.0.RC1' } //upgrated
    repositories { mavenCentral()
                maven { url "https://repo.spring.io/snapshot" } //<---new
      		maven { url "https://repo.spring.io/milestone" }//<---new
    }
    dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'

jar {
    baseName = 'gs-multi-module-application'
    version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8

repositories { mavenCentral()
                maven { url "https://repo.spring.io/snapshot" }//<---new
  		maven { url "https://repo.spring.io/milestone" }//<---new
}

dependencies {
    compile('org.springframework.boot:spring-boot-starter-actuator')
    compile('org.springframework.boot:spring-boot-starter-web')
    compile project(':library')
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

  • build.gradle within library
buildscript {
    repositories { mavenCentral()
                maven { url "https://repo.spring.io/snapshot" }//<---new
      		maven { url "https://repo.spring.io/milestone" }//<---new
    }
}

plugins { id "io.spring.dependency-management" version "1.0.0.RELEASE" }

ext { springBootVersion = '2.0.0.RC1' } //Upgrated

apply plugin: 'java'
apply plugin: 'eclipse'

jar {
    baseName = 'gs-multi-module-library'
    version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8

repositories { mavenCentral()
                maven { url "https://repo.spring.io/snapshot" }//<---new
  		maven { url "https://repo.spring.io/milestone" }//<---new
}

dependencies {
    compile('org.springframework.boot:spring-boot-starter')
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

dependencyManagement {
    imports { mavenBom("org.springframework.boot:spring-boot-dependencies:${springBootVersion}") }
}

I get the following when I execute gradle build

FAILURE: Build failed with an exception.

* What went wrong:
Could not resolve all files for configuration ':application:compileClasspath'.
> Could not find org.springframework.boot:spring-boot-starter-actuator:.
  Required by:
      project :application
> Could not find org.springframework.boot:spring-boot-starter-web:.
  Required by:
      project :application
> Could not find org.springframework.boot:spring-boot-starter:.
  Required by:
      project :application > project :library

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 2s
3 actionable tasks: 1 executed, 2 up-to-date

During the build, one or more dependencies that were declared without a version failed to resolve:
    org.springframework.boot:spring-boot-starter-actuator:
    org.springframework.boot:spring-boot-starter-web:
    org.springframework.boot:spring-boot-starter:

Did you forget to apply the io.spring.dependency-management plugin to the application project?

Thus I am blocked to confirm if my case is a bug or really is missing some extra configuration. With this confirmation if it is a bug I would report in peace the bug in Spring Boot

Thanks in advance Greg.

-Manuel

Unable to execute mvn spring-boot:run

It's not possible to run the complete project from the command line using spring-boot:run.
mvn spring-boot:run -pl 'com.example:gs-multi-module-application' -am

Results in the following error:

[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for gs-multi-module-library 0.0.1-SNAPSHOT:
[INFO] 
[INFO] gs-multi-module-library ............................ FAILURE [  2.948 s]
[INFO] gs-multi-module-application ........................ SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  4.510 s
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.1.4.RELEASE:run (default-cli) on project gs-multi-module-library: Unable to find a suitable main class, please add a 'mainClass' property

Jdk version:
openjdk version "1.8.0_191"

Jre version:
OpenJDK Runtime Environment (build 1.8.0_191-8u191-b12-2ubuntu0.18.04.1-b12)

Any help is greatly appreciated.

can a Gradle multi-project build be added to this guide?

Hi all

Current "complete" folder does not have a build.gradle on "root" level, thus each project has to deal with dependencies completely autonomously

I would like to see more "conventional" multi-module (multi-project) Gradle build config, that would for example let me define shared ("allprojects") logic in the root build.gradle and then only add module-specific customizations in each module's build.gradle files?

Say, then the project structure could look like this:

root
|-app1
   |-build.gradle
|-app2
   |-build.gradle
|-lib
   |-build.gradle
build.gradle
settings.gradle

I am currently trying to structure such build based on suggestions from here https://stackoverflow.com/a/59435028/2583044 but I have some issues where dependencies are "not found" and it looks like gradle does not know which version to apply to them These dependencies ARE in the spring-boot-dependencies-2.4.0.pom, like

Could not find org.springframework.boot:spring-boot-starter-test:.

[Question] Is this only reusable for Spring boot applications?

I'm currently writing a library as describe in the documentation so I can reuse it in my other Spring boot applications. I have some colleagues that might benefit from this library as well, but they're not always using Spring boot or even Spring. Can they also use this library?

Cannot build multiple module project with spring data jpa.

I just created a sample project shows the problem. (https://github.com/XieEDeHeiShou/Spring-multipe-module-project-sample)

The 'app' dependent on 'lib'.
In 'lib/test/java/sample/dengchao/lib/LibServiceTest', LibService call LibRepository to find a LibEntity with id '1'. The test passed.

In 'app/main/java/sample/dengchao/app/Main', it test the same thing, but failed because of

Parameter 0 of constructor in sample.dengchao.lib.LibService required a bean of type 'sample.dengchao.lib.LibRepository' that could not be found.

cannot run with the following issue

Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/boot/SpringApplication
	at com.ykb.dsc.DemoApplication.main(DemoApplication.java:32)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: java.lang.ClassNotFoundException: org.springframework.boot.SpringApplication
	at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	... 6 more

Unable to run gradle build on application module in intellij Idea - Project with path ':library' could not be found

To simulate the issue, cd to complete/application directory in terminal
Command to run : gradlew build(Win) or ./gradlew build(Linux)

Build Output:

FAILURE: Build failed with an exception.

* Where:
Build file '..\gs-multi-module\complete\application\build.gradle' line: 18

* What went wrong:
A problem occurred evaluating root project 'multi-module-application'.
> Project with path ':library' could not be found in root project 'multi-module-application'.

Solution:
Since application & library module act like multi repo modules as they have their own settings.gradle file. The project should be migrated to use gradle composite build.

More on Gradle composite builds here:
https://docs.gradle.org/current/userguide/composite_builds.html
https://blog.jetbrains.com/idea/2017/03/webinar-recording-composite-builds-with-gradle/

Spring Boot parent

Is there any reason to prefer having spring-boot-starter-parent as the parent of the "child" modules (e.g. gs-multi-module-library) instead of gs-multi-module? It seems that it would be easier to have gs-multi-module inherit from spring-boot-starter-parent and the other sub-modules inherit from gs-multi-module. I have used this setup myself and it works properly.

gradle test for lib not working

Hello,

The test is not working for lib using gradle.

Adding this to build.gradle for lib corrected the problem for me :

test {
useJUnitPlatform()
}

Export and import jar file

According to the description, the goal is to export (or create, respectively) a jar file from some library project and to import that jar file into some root project.

Unfortunately, the library sources are directly imported and no jar file is created.

I would appreciate if the import and export jar tasks can be added to the tutorial.

Can run with MVNW

Hello,

when I run command ./mvnw spring-boot:run inside complete folder I get following error:

image

There are millions of people search and follow this structure everyday to create multi module springboot application.
This is like a bible. Please fix it.

The configuration used in this guide will not find repositories and entities defined in the library module

The current setup will not find JPA entities and repositories defined in the library module, but this paragraph gives the impression that it will:

Because DemoApplication is inside a different package (hello.app) than MyService (hello.service), @SpringBootApplication won't detect it initially. There are different ways to allow `MyService to be picked up:

  • Import it directly with @Import(MyService.class).
  • Fetch everything from it's package using @SpringBootApplication(scanBasePackageClasses={...}).
  • The method this guide uses--specifying the parent package by name, hello.

But if in the shared lib, we have entity classes defined under hello.entity and repositories under hello.repository, @SpringBootApplication(scanBasePackages = "hello") won't pick them up.

To make the app module pickup the entity and repository types, either DemoApplication should be defined in the hello package (as opposed to hello.app) or it is should be annotated with @EntityScan("hello.entity") and @EnableJpaRepositories("hello.repository").

Maven build is not working.

Running in (complete) folder:
./mvnw install && ./mvnw spring-boot:run -pl application

ERROR:
Failed to execute goal on project multi-module-application-complete: Could not resolve dependencies for project com.example:multi-module-application-complete:jar:0.0.1-SNAPSHOT: Could not find artifact com.example:library:jar:0.0.1-SNAPSHOT -> [Help 1]

image

I'm using docker
docker run -it --rm --name my-project -v "$(pwd)":/root -w /root adoptopenjdk/maven-openjdk11:latest mvn clean install

Its works with gradle:
./gradlew build && ./gradlew :application:bootRun

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.