IDEA Springboot启动报Command line is too long错误

启动报错:

Error running 'CmsFrontApplication': Command line is too long. Shorten command line for CmsFrontApplication or also for Spring Boot default configuration.

IDEA Springboot启动报Command line is too long错误

解决办法

IDEA Springboot启动报Command line is too long错误

 

IDEA Springboot启动报Command line is too long错误

原因分析

出现此问题的直接原因是:IDEA集成开发环境运行你的“源码”的时候(注意是源码基础上运行,并非打好的jar包哦),是通过命令(首行那个非常非常长的)来启动Java进程的。这个命令主要包含两大部分:

  1. vm 程序参数。也就是你看到的那些-XX -D等参数,这部分理论上可以无限长但实际上一般不会太长
  2. -classpath参数,它用于指定运行时jar包路径(因为jar包理论上是可以在任何地方的),这部分可能性就多了

关键就在于-classpath参数,它可以非常长,你依赖的jar包越多此路径就越长;你的base基路径越长它就越长;倘若你还要做复杂的Junit单元测试,那加入的jar包就更多长度可能就越长喽。总的来说:此part是很有可能超长从而导致Command line is too long现象的。

如果类路径太长(可能性大),或者您有许多VM参数(可能性小),则无法启动该程序。原因是大多数操作系统都有命令行长度限制。在这种情况下,IntelliJ IDEA将提供尝试缩短类路径的能力。


IDEA老版本方案

针对此问题,在之前版本(确切的说是2017.3之前的版本),需要通过XML文件配置来解决:找到工程下的.idea/workspace.xml这个文件,添加如下项:

<component name="PropertiesComponent">
    ...
    <!-- 这句是你需要添加的项 -->
    <property name="dynamic.classpath" value="true" />
    ...
</component>

再次启动程序发现问题解决。我有理由相信,在这个时间节点上应该没有人用这么古老的版本了吧,但你在网上搜的文章大多数都还是这种解决方案,因此请务必注意甄别哦(2017.3以后的版本请参照下面方案解决)。

任何不指定版本的解决方案、源码分析文章都是不太负责任的。作为一个程序员,应该适当提高自己的版本意识


IDEA新版本方案:命令行缩短器

在IDEA的2017.3版本中提供了一项新特性:命令行缩短器。旨在用来解决此类问题,也就是说从此版本开始,不再需要通过XML文件来编辑IDE的设置那么麻烦了,而是直接在界面操作即可:
IDEA Springboot启动报Command line is too long错误
最初,IntelliJ IDEA尝试将长类路径写入文本文件(这意味着应用程序是中间类加载器)。但是不幸的是,这不适用于某些框架,例如JMock。然后,IntelliJ IDEA尝试使用或多或少的标准方法,即将长类路径打包到classpath.jar中。不幸的是,对于其他一些框架,这也不起作用。

总结:这两种方案都不是100%完美的,具体情况具体分析

从上对话框中可以看到IDEA一共提供了三种命令行缩短器供你选择:

  1. none。这是默认选项。IDE不会缩短长类路径。如果命令行超出操作系统限制,则IDEA将无法运行您的应用程序
  2. jar manifest。IDE通过临时classpath.jar传递长类路径。原始类路径在MANIFEST.MF中定义为classpath.jar中的类路径属性
  3. classpath file。IDE将把长类路径写入文本文件

jar manifest方式

选择此种方式,运行测试程序,首行全部内容展示如下:

D:\developer\jdks\1.8.0_241\bin\java.exe -XX:TieredStopAtLevel=1 -noverify 
    -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote 
    -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain 
    -Dspring.application.admin.enabled=true 
    "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2020.1.1\lib\idea_rt.jar=5975:C:\Program Files\JetBrains\IntelliJ IDEA 2020.1.1\bin" -Dfile.encoding=UTF-8 
    -classpath C:\Users\xxx\AppData\Local\Temp\classpath1199511058.jar 
    com.xxx.Application

区别主要在于-classpath这一行,它不再是把所有jar的路径展示出来,而是“封装”到了一个jar文件里,这一下子让命令长度大幅减少,能够100%保证不会超长了,所以启动也就不会报错喽。

另外,在IDEA里你直接单击此jar路径是可以预览器内容的(真贴心):
IDEA Springboot启动报Command line is too long错误
当然,你也可以在你磁盘里找到此jar文件,然后查看其内容(说明:请确保hold住线程了再去找对应文件,否则临时文件是线程结束后就删除了的):
IDEA Springboot启动报Command line is too long错误
特别强调:我在实践过程中,使用此种方式出现过jar包没有被加载进来的情况,在此提醒各位,若你也有类似现象发生,请切换成使用classpath file方式吧。

毕竟官方也说了:这两种路径缩短方式,对某些框架可能存在不兼容情况,just可能而已哦~


classpath file方式

选择此种方式,运行测试程序,首行全部内容展示如下:

D:\developer\jdks\1.8.0_241\bin\java.exe -XX:TieredStopAtLevel=1 -noverify 
    -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote 
    -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain 
    -Dspring.application.admin.enabled=true 
    "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2020.1.1\lib\idea_rt.jar=5975:C:\Program Files\JetBrains\IntelliJ IDEA 2020.1.1\bin" -Dfile.encoding=UTF-8 
    -classpath C:\Users\xxx\AppData\Local\Temp\idea_classpath921151059
    com.xxx.Application

 



扩展知识:windows系统命令最大长度

这属于扩展知识,延伸阅读内容。

既然已经知道出现此问题的原因是命令超长了而“报错”,A哥就想那windows命令最长允许多少字符呢?带着这个问题,我开始了一番苦心寻找,最后终于在windows官网找到了我想要的答案。地址在这:https://docs.microsoft.com/zh-cn/windows/win32/api/processenv/nf-processenv-setenvironmentvariablea?redirectedfrom=MSDN

在Windows上,命令行长度最大为32767个字符(和shell长度、命令提示符长度的区别)。当提供足够大的类路径时,将违反此限制,并且Windows拒绝执行该命令并抛出错误代码87。推荐的解决方案有如下两种:

  1. 将所有jar复制到一个公共文件夹,例如c:\jars,然后将其包括在内。这样,每个jar都有一个短路径,即c:\jars(而不是长路径c:\program files\app\lib\app-jar1.jar),并且应该可以将这个路径们控制在38kb之内
  2. 如果步骤1不起作用,则可以将单个jar提取到一个文件夹中,并创建一个包含所有提取文件的新jar。这样就只需要引入这个新jar就可以了

这是两种解决问题的思想:短路径方式(简单高效)和打包方式(100%能解决问题)


思考题

  1. 为毛你的Spring Boot应用在生产环境下从来不用担心出现Command line is too long这种错误?
  2. 有哪些有效的方式可以避免你的开发环境出现此问题?

 

 

 

 
上一篇:Spring-Boot环境的快速搭建


下一篇:Hadoop MapReduce编程 API入门系列之压缩和计数器(三十)