出现repackage failed: Unable to find a single main class from the following candidates的解决方法
一、问题描述
今天使用netty结合spring boot开发了一个网络代理服务器,在开发当中由于需要测试,所以在包名底下新建了一个Launcher的main函数入口,同时保留spring boot的Application入口。
Launcher的入口代码如下:
public class Launcher {
/**
static {
try {
File file = ResourceUtils.getFile("classpath:logback.xml");
System.out.println("path:"+file.getAbsolutePath());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
System.setProperty("logback.configurationFile", "classpath:logback.xml");
}*/
public void init(){
//加载日志配置
Logger logger = LoggerFactory.getLogger(Launcher.class);
logger.debug("222");
CreateProxyRequest request3 = new CreateProxyRequest();
request3.setProxyEnum(ProxyEnum.websocket);
ProxyDefinition proxyDefinition3 = service.createServer(request3);
proxyDefinition3.setLocalPort(8081);
service.startServer(proxyDefinition3.getId());
}
public static void main(String[] agrs){
new Launcher().init();
}
}
而spring boot的入口如下:
@SpringBootApplication
public class TcpProxyApplication {
//public static void main(String[] args) {
//
// SpringApplication.run(TcpProxyApplication.class, args);
//}
}
这两个运行入口在idea手动运行的时候没有任何问题,但是使用maven命令 mvn package -Dmaven.test.skip=true
打包后却提示如下错误:
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.388 s
[INFO] Finished at: 2019-09-15T17:57:40+08:00
[INFO] Final Memory: 27M/117M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.3.5.RELEASE:repackage (default) on project park-proxy: Execution default of goal org.springframework.boot:spring-boot-maven-plugin:1.3.5.RELEASE:repackage failed: Unable to find a single main class from the following candidates [io.igx.proxy.Launcher, io.igx.proxy.Test] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginExecutionException
二、解决办法
信息很多,我们来重点关注下错误提示语句:repackage failed: Unable to find a single main class from the following candidates
。
中文翻译:
打包失败:从以下候选者中找不到一个单独的入口。这里指的是:
io.igx.proxy.Launcher
和io.igx.proxy.Test
。
第一次遇到这个问题,心里有点慌,不过冷静想一下就得出了解决办法。既然提示多个候选者,那么我们删掉所有带有main函数的类,只保留一个线上自己需要的即可,删除后再运行打包命令直接打包成功!
所以解决办法是:
删除main函数的类或者隐藏掉main函数(类保留,只删除main函数),只保留一个main函数入口。
三、原因分析
一般利用maven或者别的工具将工程打包为jar包且这个包存在一个main入口(即可执行包)的时候出现这一类问题。根据定义java执行jar的命令:java -jar xxx.jar
我们得知,这里默认会从jar的main函数开始执行。这个信息会记录在jar包中的MANIFEST.MF描述文件中:
Main-Class: jar包执行入口(其实就是main函数所在的路径)
四、扩展
Manifest.MF文件被android的同学所熟知,但Jar中也有自己的Manifest结构,用来包含打包工具,程序入口,applet, extionsion`等信息。
其结构如下:
- Manifest-Version, Signature-Version: manifest/签名 文件的版本
- Created-By: 生成jar包的java版本
- Class-Path: 该jar包依赖的外部的class 的相对路径(相对该jar包的路径)
- Main-Class: jar包执行入口
- Implementation-, Specification- : 该jar包的描述,版本等信息
和我们熟悉的常规jar不一样,可执行的jar可以将工程中的资源文件打包进去,形成一个完整的包括资源的可执行包。
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。