Bootstrap

[运行报错] Maven打包SpringBoot项目,运行报错:no main manifest attribute, in xxx.jar

问题描述

IDEA创建SpringBoot 2.6.13项目(仅引入SpringMVC依赖),对生成的代码不做修改直接Maven打包。但运行报错:

# java -jar xxx.jar 
no main manifest attribute, in xxx.jar

检查jar包,

# jar -xvf xxx.jar 
# cat META-INF/MANIFEST.MF 
Manifest-Version: 1.0
Build-Jdk-Spec: 1.8
Created-By: Maven JAR Plugin 3.3.0

解决办法

pom.xml中注释掉创建时spring-boot-maven-plugin<configuration><skip>true</skip>(忽略配置):

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <mainClass>com.example.MinWebDemoApplication</mainClass>
<!--                    <skip>true</skip>-->

重新用maven打包(先clean, 再package),即可✅。

注意到,此时META-INF/MANIFEST.MF包含了Start-Class和Main-Class

# jar -xvf xxx.jar 
# cat META-INF/MANIFEST.MF 
...
Start-Class: com.example.MinWebDemoApplication
...
Main-Class: org.springframework.boot.loader.JarLauncher

附录

root@node01:~/web-app# java -jar min-web-demo-0.0.1-SNAPSHOT.jar 
no main manifest attribute, in min-web-demo-0.0.1-SNAPSHOT.jar

root@node01:~/web-app# jar -xvf min-web-demo-0.0.1-SNAPSHOT.jar 
  created: META-INF/
 inflated: META-INF/MANIFEST.MF
  created: com/
  created: com/example/
  created: com/example/demos/
  created: com/example/demos/web/
  created: static/
  created: META-INF/maven/
  created: META-INF/maven/com.example/
  created: META-INF/maven/com.example/min-web-demo/
 inflated: application.properties
 inflated: com/example/demos/web/BasicController.class
 inflated: com/example/demos/web/PathVariableController.class
 inflated: com/example/demos/web/User.class
 inflated: com/example/MinWebDemoApplication.class
 inflated: static/index.html
 inflated: META-INF/maven/com.example/min-web-demo/pom.xml
 inflated: META-INF/maven/com.example/min-web-demo/pom.properties
root@node01:~/web-app# cat META-INF/MANIFEST.MF 
Manifest-Version: 1.0
Build-Jdk-Spec: 1.8
Created-By: Maven JAR Plugin 3.3.0

root@node01:~/web-app# jar -xvf min-web-demo-0.0.2-SNAPSHOT.jar 
  created: META-INF/
 inflated: META-INF/MANIFEST.MF
  created: org/
  created: org/springframework/
  created: org/springframework/boot/
  created: org/springframework/boot/loader/
 inflated: org/springframework/boot/loader/ClassPathIndexFile.class
 inflated: org/springframework/boot/loader/ExecutableArchiveLauncher.class
 inflated: org/springframework/boot/loader/JarLauncher.class
 inflated: org/springframework/boot/loader/LaunchedURLClassLoader$DefinePackageCallType.class
 inflated: org/springframework/boot/loader/LaunchedURLClassLoader$UseFastConnectionExceptionsEnumeration.class
 inflated: org/springframework/boot/loader/LaunchedURLClassLoader.class
 inflated: org/springframework/boot/loader/Launcher.class
 inflated: org/springframework/boot/loader/MainMethodRunner.class
 inflated: org/springframework/boot/loader/PropertiesLauncher$1.class
 inflated: org/springframework/boot/loader/PropertiesLauncher$ArchiveEntryFilter.class
 inflated: org/springframework/boot/loader/PropertiesLauncher$ClassPathArchives.class
 inflated: org/springframework/boot/loader/PropertiesLauncher$PrefixMatchingArchiveFilter.class
 inflated: org/springframework/boot/loader/PropertiesLauncher.class
 inflated: org/springframework/boot/loader/WarLauncher.class
  created: org/springframework/boot/loader/archive/
 inflated: org/springframework/boot/loader/archive/Archive$Entry.class
 inflated: org/springframework/boot/loader/archive/Archive$EntryFilter.class
 inflated: org/springframework/boot/loader/archive/Archive.class
 inflated: org/springframework/boot/loader/archive/ExplodedArchive$AbstractIterator.class
 inflated: org/springframework/boot/loader/archive/ExplodedArchive$ArchiveIterator.class
 inflated: org/springframework/boot/loader/archive/ExplodedArchive$EntryIterator.class
 inflated: org/springframework/boot/loader/archive/ExplodedArchive$FileEntry.class
 inflated: org/springframework/boot/loader/archive/ExplodedArchive$SimpleJarFileArchive.class
 inflated: org/springframework/boot/loader/archive/ExplodedArchive.class
 inflated: org/springframework/boot/loader/archive/JarFileArchive$AbstractIterator.class
 inflated: org/springframework/boot/loader/archive/JarFileArchive$EntryIterator.class
 inflated: org/springframework/boot/loader/archive/JarFileArchive$JarFileEntry.class
 inflated: org/springframework/boot/loader/archive/JarFileArchive$NestedArchiveIterator.class
 inflated: org/springframework/boot/loader/archive/JarFileArchive.class
  created: org/springframework/boot/loader/data/
 inflated: org/springframework/boot/loader/data/RandomAccessData.class
 inflated: org/springframework/boot/loader/data/RandomAccessDataFile$1.class
 inflated: org/springframework/boot/loader/data/RandomAccessDataFile$DataInputStream.class
 inflated: org/springframework/boot/loader/data/RandomAccessDataFile$FileAccess.class
 inflated: org/springframework/boot/loader/data/RandomAccessDataFile.class
  created: org/springframework/boot/loader/jar/
 inflated: org/springframework/boot/loader/jar/AbstractJarFile$JarFileType.class
 inflated: org/springframework/boot/loader/jar/AbstractJarFile.class
 inflated: org/springframework/boot/loader/jar/AsciiBytes.class
 inflated: org/springframework/boot/loader/jar/Bytes.class
 inflated: org/springframework/boot/loader/jar/CentralDirectoryEndRecord$1.class
 inflated: org/springframework/boot/loader/jar/CentralDirectoryEndRecord$Zip64End.class
 inflated: org/springframework/boot/loader/jar/CentralDirectoryEndRecord$Zip64Locator.class
 inflated: org/springframework/boot/loader/jar/CentralDirectoryEndRecord.class
 inflated: org/springframework/boot/loader/jar/CentralDirectoryFileHeader.class
 inflated: org/springframework/boot/loader/jar/CentralDirectoryParser.class
 inflated: org/springframework/boot/loader/jar/CentralDirectoryVisitor.class
 inflated: org/springframework/boot/loader/jar/FileHeader.class
 inflated: org/springframework/boot/loader/jar/Handler.class
 inflated: org/springframework/boot/loader/jar/JarEntry.class
 inflated: org/springframework/boot/loader/jar/JarEntryCertification.class
 inflated: org/springframework/boot/loader/jar/JarEntryFilter.class
 inflated: org/springframework/boot/loader/jar/JarFile$1.class
 inflated: org/springframework/boot/loader/jar/JarFile$JarEntryEnumeration.class
 inflated: org/springframework/boot/loader/jar/JarFile.class
 inflated: org/springframework/boot/loader/jar/JarFileEntries$1.class
 inflated: org/springframework/boot/loader/jar/JarFileEntries$EntryIterator.class
 inflated: org/springframework/boot/loader/jar/JarFileEntries$Offsets.class
 inflated: org/springframework/boot/loader/jar/JarFileEntries$Zip64Offsets.class
 inflated: org/springframework/boot/loader/jar/JarFileEntries$ZipOffsets.class
 inflated: org/springframework/boot/loader/jar/JarFileEntries.class
 inflated: org/springframework/boot/loader/jar/JarFileWrapper.class
 inflated: org/springframework/boot/loader/jar/JarURLConnection$1.class
 inflated: org/springframework/boot/loader/jar/JarURLConnection$JarEntryName.class
 inflated: org/springframework/boot/loader/jar/JarURLConnection.class
 inflated: org/springframework/boot/loader/jar/StringSequence.class
 inflated: org/springframework/boot/loader/jar/ZipInflaterInputStream.class
  created: org/springframework/boot/loader/jarmode/
 inflated: org/springframework/boot/loader/jarmode/JarMode.class
 inflated: org/springframework/boot/loader/jarmode/JarModeLauncher.class
 inflated: org/springframework/boot/loader/jarmode/TestJarMode.class
  created: org/springframework/boot/loader/util/
 inflated: org/springframework/boot/loader/util/SystemPropertyUtils.class
  created: BOOT-INF/
  created: BOOT-INF/classes/
  created: BOOT-INF/classes/com/
  created: BOOT-INF/classes/com/example/
  created: BOOT-INF/classes/com/example/demos/
  created: BOOT-INF/classes/com/example/demos/web/
  created: BOOT-INF/classes/static/
  created: META-INF/maven/
  created: META-INF/maven/com.example/
  created: META-INF/maven/com.example/min-web-demo/
 inflated: BOOT-INF/classes/application.properties
 inflated: BOOT-INF/classes/com/example/demos/web/BasicController.class
 inflated: BOOT-INF/classes/com/example/demos/web/PathVariableController.class
 inflated: BOOT-INF/classes/com/example/demos/web/User.class
 inflated: BOOT-INF/classes/com/example/MinWebDemoApplication.class
 inflated: BOOT-INF/classes/static/index.html
 inflated: META-INF/maven/com.example/min-web-demo/pom.xml
 inflated: META-INF/maven/com.example/min-web-demo/pom.properties
  created: BOOT-INF/lib/
extracted: BOOT-INF/lib/spring-boot-2.6.13.jar
extracted: BOOT-INF/lib/spring-boot-autoconfigure-2.6.13.jar
extracted: BOOT-INF/lib/logback-classic-1.2.11.jar
extracted: BOOT-INF/lib/logback-core-1.2.11.jar
extracted: BOOT-INF/lib/log4j-to-slf4j-2.17.2.jar
extracted: BOOT-INF/lib/log4j-api-2.17.2.jar
extracted: BOOT-INF/lib/jul-to-slf4j-1.7.36.jar
extracted: BOOT-INF/lib/jakarta.annotation-api-1.3.5.jar
extracted: BOOT-INF/lib/snakeyaml-1.29.jar
extracted: BOOT-INF/lib/jackson-databind-2.13.4.2.jar
extracted: BOOT-INF/lib/jackson-annotations-2.13.4.jar
extracted: BOOT-INF/lib/jackson-core-2.13.4.jar
extracted: BOOT-INF/lib/jackson-datatype-jdk8-2.13.4.jar
extracted: BOOT-INF/lib/jackson-datatype-jsr310-2.13.4.jar
extracted: BOOT-INF/lib/jackson-module-parameter-names-2.13.4.jar
extracted: BOOT-INF/lib/tomcat-embed-core-9.0.68.jar
extracted: BOOT-INF/lib/tomcat-embed-el-9.0.68.jar
extracted: BOOT-INF/lib/tomcat-embed-websocket-9.0.68.jar
extracted: BOOT-INF/lib/spring-web-5.3.23.jar
extracted: BOOT-INF/lib/spring-beans-5.3.23.jar
extracted: BOOT-INF/lib/spring-webmvc-5.3.23.jar
extracted: BOOT-INF/lib/spring-aop-5.3.23.jar
extracted: BOOT-INF/lib/spring-context-5.3.23.jar
extracted: BOOT-INF/lib/spring-expression-5.3.23.jar
extracted: BOOT-INF/lib/slf4j-api-1.7.36.jar
extracted: BOOT-INF/lib/spring-core-5.3.23.jar
extracted: BOOT-INF/lib/spring-jcl-5.3.23.jar
extracted: BOOT-INF/lib/spring-boot-jarmode-layertools-2.6.13.jar
 inflated: BOOT-INF/classpath.idx
 inflated: BOOT-INF/layers.idx
root@node01:~/web-app# cat META-INF/MANIFEST.MF 
Manifest-Version: 1.0
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
Spring-Boot-Layers-Index: BOOT-INF/layers.idx
Start-Class: com.example.MinWebDemoApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Build-Jdk-Spec: 1.8
Spring-Boot-Version: 2.6.13
Created-By: Maven JAR Plugin 3.3.0
Main-Class: org.springframework.boot.loader.JarLauncher

root@node01:~/web-app# java -jar min-web-demo-0.0.2-SNAPSHOT.jar 

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::               (v2.6.13)

2024-02-15 12:54:39.935  INFO 48664 --- [           main] com.example.MinWebDemoApplication        : Starting MinWebDemoApplication using Java 1.8.0_392 on node01 with PID 48664 (/root/web-app/min-web-demo-0.0.2-SNAPSHOT.jar started by root in /root/web-app)
2024-02-15 12:54:39.937  INFO 48664 --- [           main] com.example.MinWebDemoApplication        : No active profile set, falling back to 1 default profile: "default"
2024-02-15 12:54:40.659  INFO 48664 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2024-02-15 12:54:40.670  INFO 48664 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2024-02-15 12:54:40.670  INFO 48664 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.68]
2024-02-15 12:54:40.725  INFO 48664 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2024-02-15 12:54:40.725  INFO 48664 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 742 ms
2024-02-15 12:54:40.886  INFO 48664 --- [           main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
2024-02-15 12:54:40.960  INFO 48664 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2024-02-15 12:54:40.967  INFO 48664 --- [           main] com.example.MinWebDemoApplication        : Started MinWebDemoApplication in 1.343 seconds (JVM running for 1.751)


;