24

I am trying use Spring Boot, and create a jar, and install it into my maven repo.

This is a library jar file that will be used as a dependency in my main application, which is also a Spring-Boot application. Right now, I am just working on a hello world example. here is my one class in this project:

public class MyLibrary {

  public String getMessage() {
    return "Hello World!";
  }
}

and my POM basically looks like this:

<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<groupId>com.me.plugin</groupId>
<artifactId>myLibrary</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.7.RELEASE</version>
</parent>

<dependencies> 
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
</dependencies>

But when I try to build, I get 'Unable to find main class" error. Which makes perfect sense to me, but how do I get spring to make a library jar. I know I could add an Application.java with a main method, but that's not what I want, I want a simple jar file, but with all the Spring-Boot annotations, injections, etc...

How would I go about doing this? Is spring boot not what I want here?

mmaceachran
  • 3,178
  • 7
  • 53
  • 102
  • You can make your librar a simple regular JAR as well. I would not try to fit the spring boot mechanics in a library module. – eckes Oct 22 '17 at 18:21
  • probably related https://stackoverflow.com/a/32711287/1032167 – varren Oct 22 '17 at 18:23
  • 1
    Spring boot is all about runnable applications, so even without knowing much more about what your library is meant to do, it does seem that you don't want spring boot dependencies. It would help to figure out what you library is meant to offer, then figure out what spring (non boot) dependencies you really need. – Aidan Moriarty Oct 22 '17 at 18:35
  • read spring for library and main module https://spring.io/guides/gs/multi-module/ – surya Oct 22 '17 at 19:19
  • @AidanMoriarty thats not complete truth. Spring-boot is also about ways of sharin g code and making plug&play libraries as the starters. – Rafael Oct 23 '18 at 10:46

3 Answers3

52

I am sure you are using spring-boot-maven-plugin in your pom.xml (as given below), which allows you to package executable jar or war archives and run an application.

With this plugin, spring searches for a main application.You don't need this plugin for a spring library project. Delete this plugin and clean install .

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

I assume you are creating some spring configuration files or components in this library project. You may not need big fat spring-boot-starter. But its fine if you need multiple spring modules and you want one place for all dependency.

rilaby
  • 603
  • 5
  • 15
surya
  • 2,581
  • 3
  • 22
  • 34
  • but if same thing i have to do with child jar within a springboot application – ThinkTank Feb 26 '19 at 12:04
  • You ll have separate Pom for each child jar , so include this for corresponding child project where you have main class (bootable jar) – surya Feb 26 '19 at 12:46
  • For those reading this answer, but having `spring-boot-maven-plugin` reference in your `build -> plugins` tag for some good reason, most of the time you may be able to fix it by using `maven-compiler-plugin` in that place. – rineez May 04 '22 at 13:42
0

The accepted answer posted by Surya is correct for Maven. However, if someone is using Gradle here's what should be done in the library's build.gradle file:

plugins {
  id 'org.springframework.boot' version '2.7.3' apply false
  id 'io.spring.dependency-management' version '1.0.13.RELEASE'
  // ... other plugins
}

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

The lines above should resolve the problem. Essentially, the Spring Boot plugin which produces an executable jar with a main class is no longer applied, but Spring's dependency management is still usuable.

If you are still having issues using the library jar in your main application, make sure that you have added this line to your dependencies in your main application's build.gradle file:

implementation project(':library')

Also these lines should be present in your root project's settings.gradle file:

include 'library'
include 'application'

I recommend going through this Spring guide since it explains your exact scenario. It covers both Maven and Gradle. Disabling the Spring Boot's Gradle plugin while keeping the Spring Boot's dependency management is also described here in the documentation

Robert
  • 11
  • 3
0

It's maybe a bit late but in our case the spring-boot-maven-plugin (1.5.22.RELEASE) use the configuration: <layout>MODULE</layout>. Notice we need to exclude unwanted libraries.

With this we can create a FAT JAR with multiple applications. At deployment time we specify which main class to use for each running instance.

  Bundle dependencies (excluding those with provided scope) and project resources.

Documented here: Available layouts

For the plugin 2.7.9, I'm still looking for a similar solution. I will probably have to try the FactoryLayout... I finally used the maven-assembly-plugin as described here: boot-inf directory causing aws lambda to fail

Martin P.
  • 654
  • 8
  • 18