Spring type application cannot find the main function no main manifest attribute, in / APP Jar, spring boot Maven plugin pot?

Posted by syth04 on Sat, 29 Jan 2022 06:58:08 +0100

Problem phenomenon

Error 1

An error is reported after the spring type application is started, no main manifest attribute, in / APP jar

Error 2

During the mvn build process, the message "repackage failed" will be prompted

Cause analysis

In most cases, it is because of the POM in spring application The spring boot Maven plugin is not used in XML to package the plug-in, or the version of the plug-in is not specified, so it needs to be in POM Add the following content to the XML

<build>
    </plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>  //Please fill in the version number of your springboot here
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
    </plugins>
 </build>

intensive study

spring-boot-maven-plugin

spring boot Maven plugin is a self-contained plug-in for packaging. Its principle is to repackage the application's own class and its dependencies into a large jar during mvn package. As long as the specified version jre is installed, you can use Java - jar XXX Jar runs without downloading dependencies from the system's lib library. Those who are interested in details can have a look Spring boot Maven plugin principle , let's see the effect here.

First build a springboot helloword project, and pay attention to introducing the spring boot Maven plugin plug-in into pom

public class CsdemoApplication {
    @RequestMapping("/")
    public String greeting() {
        return "Greeting!";
    }  
 
    public static void main(String[] args) {
        SpringApplication.run(CsdemoApplication.class, args);
    }
}

Execute mvn clean package, and a jar file and a jar.jar file will be generated in the target directory The original file is less than 5K. In fact, this is the product of maven's own packaging tool to package the project's own code. The jar file is nearly 26MB, which is the product of spring boot maven plugin repackaging the original.

After decompressing and comparing the two files, we can find that the main change is that there is an lib folder in the jar, which stores all the jars that the project depends on. This folder is full of 25M, which leads to the increase of the volume of the whole jar package and why you can directly Java - jar XXX The reason for starting the jar program.


Students who have written more spring applications may have noticed that sometimes the line ${spring-boot.version} can be omitted, but sometimes an error will be reported. Why.

This depends on the dependency of your project. If the parent of your project is spring boot starter parent (or its subproject), you can omit the version attribute in the spring boot Maven plugin, and mvn will automatically go to the spring boot starter parent to find the corresponding version.

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

However, if the parent of your project is not spring boot starter parent (or its subproject), for example, it inherits from the parent made by the company itself, the version of spring boot Maven plugin is essential, otherwise the errors in Chapter 1 will appear.

maven dependent version management mechanism

maven can realize the unified version management of components in the dependencies module in two ways. One is to specify the whole project parent as spring boot starter parent, and the other is to introduce spring boot dependencies into dependency management. There is a little difference between the two:

The parent is specified as spring boot starter parent

If the parent of your project is spring boot starter parent, the version number of any spring related starter can be omitted when it is introduced into the dependency. The reason is that Spring Boot Dependencies has been introduced into the parent, which specifies most commonly used dependent versions:

If you want to modify a dependent version in your own application, you can specify it directly in properties:

<properties>
     <spring-data-releasetrain.version>Fowler-SR2</spring-data-releasetrain.version>
</properties>

If you want to exclude a dependency used by default in the parent and replace it with another one, you can do the following

<dependency>
      <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-data-rest</artifactId>
       <exclusions>
           <!-- filter lettuceļ¼Œuse jedis As redis client -->
           <exclusion>
               <groupId>io.lettuce</groupId>
               <artifactId>lettuce-core</artifactId>
           </exclusion>
       </exclusions>
</dependency>
<dependency>
      <groupId>redis.clients</groupId>
       <artifactId>jedis</artifactId>
</dependency>

Introducing spring boot dependencies into dependency management

If your project does not inherit from spring boot starter parent, but depends on the springboot plug-in introduced through dependency management, you can still omit the version number of each spring dependency in the dependencies module, but you must specify the version number in the build module (for example, the spring boot Maven plugin mentioned above is under the build module)

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

However, in this way, you cannot directly specify the spring dependent version in properties, but you need to modify the dependent version before spring boot dependencies in dependency management. For example, also modify the Spring Data release train:

<dependencyManagement>
    <dependencies>
        <!-- Override Spring Data release train provided by Spring Boot -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-releasetrain</artifactId>
            <version>Fowler-SR2</version>
            <scope>import</scope>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Topics: Maven Spring Spring Boot