image
NightSnow

池浅王八多 遍地是大哥

记IDEA 运行SpringBoot 启动类命令超长的问题

NightSnow    2019-03-20 10:54

IntelliJ IDEA 2017.3 以后的版本;

运行SpringBoot 启动器类 启动失败,报错

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

命令行过长问题, 说的直白点就是 在cmd 或 shell bash 执行命令的时候写了太多字, 超过了操作系统的设置极限,然后操作系统不鸟这个命令了,结果当然就是报错了。 有的朋友可能觉得很奇怪,为什么前几天没设置也没毛病, 为啥今天就大姨妈了。。。 问题就很简单,前几天你引用的第三方jar 或模块少,总共加起来 classpath 直接写在命令行上都没有超长; 然而不幸的是,昨天你加了点第三方依赖,然后在临界的时候超长了, 就会出现这个问题了。  还有可能会觉得这个问题很奇葩, 为什么同事的Eclipse 就没问题, 而自己的IDEA 就有问题,乍一看这个问题很尿性。 但是看完下面的内容你再回想这个问题,wo x  这理所当然的, 想要研究一下Eclipse 为什么能运行,建用看一下Eclipse 对于项目的启动命令,了解一下Eclipse对于超长命令的解决方案,估计这个也就能明白了。

某搜索引擎搜索结果如下

     在.idea 文件夹中打开workspace.xml文件找到<component name="PropertiesComponent">,在标签里加一行  <property name="dynamic.classpath" value="true" />  

问题并没有解决,并不是说这个配置有问题,而是这个配置不满足。

具体解决办法参考 官方原文: 

=====================================================================
Configurable command line shortener

When the classpath gets too long, or you have many VM arguments, the program cannot be launched. The reason is that most operating systems have a command line length limitation. In such cases IntelliJ IDEA will try to shorten the classpath.

There are several approaches to shorten the classpath. Initially, IntelliJ IDEA tried to write the long classpath into the text file (which means an intermediate classloader to the application). But unfortunately, this didn’t work for some frameworks, e.g. JMock. Then, IntelliJ IDEA tried to use a more or less standard way, which was to pack the long classpath into the classpath.jar. Unfortunately, that didn’t work either, for some other frameworks.

And, sadly, there is no way to predict which kind of shortening would work for the user application. So the user is left having to make this decision. For Application, JUnit and TestNG configurations, 2017.3 EAP provides a way to configure the shortener.

Starting with this EAP, there is no more need to edit the settings of your IDE through the XML files.

IntelliJ IDEA 2017.3 EAP build provides a convenient way to specify the method to shorten command line, for each configuration.

Screen Shot 2017-10-09 at 08.58.33
In the Run/Debug Configuration dialog, a new field appeared: Shorten command line. The new field allows you to choose the way the IDE will shorten the command line from a drop-down list:

None: This is the default option. The IDE doesn’t shorten the long classpath. If the command line exceeds the OS limitation, the IDEA will not be able to run your application, but the tooltip will suggest configuring the shortener.

JAR Manifest: The IDE passes the long classpath via a temporary classpath.jar. The Original classpath is defined inside MANIFEST.MF as a Class-Path attribute in classpath.jar.

classpath file: The IDE will write a long classpath into a text file.

User-local default: Legacy property. This option is set automatically for projects created before this EAP. The IDE will configure this setting, depending on the value of the properties set in: idea/workspace.xml file, property: “dynamic.classpath” and idea.config.path/options/options.xml file, property: “idea.dynamic.classpath.jar”.
So you will have 
User-local default: none – if nothing was specified for the classpath shortener before, 
User-local default: JAR Manifest – if your settings specified the shortener via classpath, 
and User-local default: classpath file: – if your settings specified the shortener through the text file.

You can set up a default way to shorten the command line and use it as a template for further configurations. IntelliJ IDEA 2017.3 enables you to share your configuration with your colleagues, so all team members will have the same behavior for the application/tests, even on different operating systems. The only exception is for the parameter User-local default: this parameter won’t be shared if the configuration itself is shared. If you want the team to have the same experience, it’s advised to explicitly set this option.

Up until now, when the IDE shortened the classpath via classpath.jar, you would see only the classpath of the temporary jar: -classpath C:\Users\jetbrains\AppData\Local\Temp\classpath.jar.

In the new IntelliJ IDEA 2017.3 EAP you can preview the full command line if a long classpath was shortened via classpath.jar (JAR Manifest option in Run/Debug Configuration dialog box).

Screen Shot 2017-10-10 at 13.26.14

================================================================

总结如下, 针对于短命令行模式 有三种可设置:None, JAR mainfest, classpath file; 

User-local default: None/JAR mainfest/classpath file ; 和总的三种是一样的, 只不过是通过 workspace.xml 或者 idea.dynamic.classpath.jar 属性配置(IDEA 安装路径中有此属性配置);

想研究具体区别,直接在控制台中拿到第一行的启动命令, 主要看 -classpath 的区别:

jar mainfest

"C:\Program Files\Java\jdk8\bin\java.exe" -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:8357,suspend=y,server=n -XX:TieredStopAtLevel=1 -noverify -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8356 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=localhost -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true -javaagent:C:\Users\DaeDalu$\.IntelliJIdea2018.3\system\captureAgent\debugger-agent.jar -Dfile.encoding=UTF-8 -classpath C:\Users\DaeDalu$\AppData\Local\Temp\classpath1381944796.jar com.yonyou.ucf.basedoc.application.UcfBasedocApplication

classpath file

"C:\Program Files\Java\jdk8\bin\java.exe" -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:8107,suspend=y,server=n -XX:TieredStopAtLevel=1 -noverify -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8106 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=localhost -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true -javaagent:C:\Users\DaeDalu$\.IntelliJIdea2018.3\system\captureAgent\debugger-agent.jar -Dfile.encoding=UTF-8 -classpath "D:\IntelliJ IDEA\IntelliJ IDEA 2018.3\lib\idea_rt.jar" com.intellij.rt.execution.CommandLineWrapper C:\Users\DaeDalu$\AppData\Local\Temp\idea_classpath879602976 com.yonyou.ucf.basedoc.application.UcfBasedocApplication

这里 的临时文件 C:\Users\DaeDalu$\AppData\Local\Temp\classpath1381944796.jar   C:\Users\DaeDalu$\AppData\Local\Temp\idea_classpath879602976  在实际的文件夹路径中并未找到 , 但是可以通过控制台的超链接点开查看具体内容。

jar mainfest

classpath file

至于启动命令的的什么原理就不说了,自己体会一下。 猜测classpathfile 的模式是IDEA工具自带的解决方案, 通过com.intellij.rt.execution.CommandLineWrapper  实现classpath 的包装解析,避免了命令行过长。

Views: 9.9K

[[total]] comments

Post your comment
  1. [[item.time]]
    [[item.user.username]] [[item.floor]]Floor
  2. Click to load more...
  3. Post your comment