-1

Background

I wrote a spring boot project using gradle and it works fine. I would like to split up the project into libraries (jars) so that I can reuse them.

These are the requirements

  1. Each of the projects are in sibling folders, each containing its own .git repo.
  2. The multi-build project should be in sibling folder, not in the folder that contains the child projects. It also contains its own .git repo.
  3. Projects that are used as libraries only (jar) have tests annotated with @SpringBootTest and these should be runnable independently.
  4. Projects that are used as class libraries should be provided to other projects as "thin jars" without any dependencies included. The using project needs to add whatever dependencies are accumulated by all the projects it uses.
  5. It should be possible to build each child project independently. For projects that depend on other projects in the suite, this means that building the project will use the output of the other projects (jar) that it needs, and if that output is not ready, gradle will first build those projects.
  6. It should be possible to build all projects from the mult-project parent (Dependencies will be worked out and only necessary builds will occur).
  7. Building the entire suite with the multi-project will create a deployable folder containing the parent boot jar and all its dependencies.
  8. I would like to be able to author the projects, edit and debug all of the above with Intellij.

Minimal, Reproducible Example

I have uploaded a minimal, reproducible example (reprex) here: https://github.com/david-sackstein/multiproject
It contains three folders:

  1. productcommon is a jar with a public class ProductFactory.
  2. productservice is a SpringBoot application with a single @RestController that invokes a public method of ProductFactory in one of its methods. productservice has a project dependcy on productcommon.
  3. multiproject is a gradle project with no code that depends on productcommon and productservice
  4. I setup the build.gradle and settings.gradle in all three projects accordingly.

When I build productservice it fails - evidently because the project import of productcommon fails.

What is missing or incorrect in this example?

David Sackstein
  • 500
  • 1
  • 5
  • 19
  • What doesn't work? Just create those libraries and make sure the spring-boot-plugin isn't applied. It is just a regular jar not a spring boot project. That being said `@SpringBootTest` won't work either because of the simple fact it isn't a spring boot project. – M. Deinum Nov 18 '19 at 07:05
  • There were a number of problems. Probably because there are a number of decisions that need to be made and I did not know how. Here are a few. 1. Which (if any) of the projects should contain a gradle task to copy the output to somewhere - and where? 2. How does one specify a dependency on a project that is in a sibling folder? Do I need to use the settings.gradle file for this or should it be done in the gradle file or both? 3. How do I enforce the dependency order at the multi-build project level (it seems to build in alphabetical order - and then fails due to lacking dependencies). – David Sackstein Nov 18 '19 at 08:30
  • Why would you need to copy things around, declare a dependency from 1 project to the other and you should be fine (use a `project` dependency as explained in the gradle documentation). Gradle figures out the order in too which build things, or enforce it by putting them in `settings.gradle`. All of these answers can be found by reading the Gradle documentation. – M. Deinum Nov 18 '19 at 08:32
  • And where will I find all the outputs? (The documentation is very difficult to read. I am looking for a very basic set of requirements and cannot find one simple example that does all of the above). – David Sackstein Nov 18 '19 at 08:35
  • I will try to create a sample project and upload it here. – David Sackstein Nov 18 '19 at 08:35
  • Which outputs? The only output, eventually, that you are interested in is the executable jar. As with all the gradle projects the output is in the respective `build/libs` directory. Again simply declare the proper dependencies on projects and Gradle will figure that out. You are overthinking things (or trying to do things manually that you shouldn't be doing manually) and with that make things more complex then necessary. Almost everything you want, works out-of-the-box, 1 thing won't. Spring Boot tests won't work on non-spring boot projects, so need to write "basic" unit /spring based tests. – M. Deinum Nov 18 '19 at 08:36
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/202557/discussion-between-david-sackstein-and-m-deinum). – David Sackstein Nov 18 '19 at 10:14

1 Answers1

0

Today I came across this excellent post on the subject: https://reflectoring.io/spring-boot-gradle-multi-module by Tom Hombergs

Tom also provides a great example at: https://github.com/thombergs/buckpal

I may have some follow on questions on the subject after working with his architecture but for the moment, I am happy with this solution.

David Sackstein
  • 500
  • 1
  • 5
  • 19