Kaloyan Pashov
Kaloyan Pashov

Reputation: 165

How do I organize a project with a shared library in Maven

I am wondering if this the correct way to structure my project and how I can configure it so that I can build/test/package all of its individual components from a single build command?

I have a Maven project that contains multiple modules- Spring apps and a "library" shared between them as a dependency. I would like to be able to build all the apps together with the library so that I can execute integration tests whenever any of the modules change (lib or app).

Ideally, I should be able to compile each component, run unit tests per app/library, run integration tests, package each component into its executable jar. At some point, this process will be run on a Jenkins server with higher-level system tests.

Right now, I am using mvn clean install spring-boot:repackage. This works for each app individually,i.e. when running from Main Project/App1/. However, when I run it from the project root Main Project/, I am getting an error that the library cannot be spring-repackage'd because the library does not have a main class. This is fine- it's a library, it does not need an entry point.

So is this the correct way to structure a multi-app project in Maven or am I doing something very wrong?

The project structure is:

Main Project
|-SharedLibrary/
  |-src/
  |-pom.xml
|-App1/
  |-src/
  |-pom.xml
|-App2/
  |-src/
  |-pom.xml
|-App3/
  |-src/
  |-pom.xml
|-pom.xml

Upvotes: 2

Views: 4232

Answers (1)

user944849
user944849

Reputation: 14951

Instead of running the goal on the command line, consider adding configuration for the Spring Boot maven plugin repackage goal to the POMs. If the configuration is added, the repackage will run as part of the mvn clean install command.

First, add the plugin to the parent's POM in the pluginManagement section. This will ensure the version of Spring boot is consistent for all modules.

<pluginMangement>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <version>YourSpringBootVersion</version>
    </plugin>
  </plugins>
</pluginMangement>

Then add the repackage goal to the POMs for the Spring Boot modules. The goal binds to phase package by default, per the docs.

<plugins>
  <plugin>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <executions>
      <execution>
        <id>spring-boot-repackage</id>
        <goals>
          <goal>repackage</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
</plugins>

Alternately, since the app is using repackage in 3 of the 4 modules, you may add the configuration above to the parent. But, doing so executes the plugin goal for all modules which we know won't work. So, if you choose this option, then you need to tell the plugin not to run in the library:

<plugins>
  <plugin>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <executions>
      <execution>
        <id>spring-boot-repackage</id>
        <phase>none</phase>
        <goals>
          <goal>repackage</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
</plugins>

Note the addition of the <phase>none</phase>. This disables the plugin goal for this module only.

Upvotes: 1

Related Questions