Hi there, we use Spring Boot Version 2.1.5.RELEASE + maven 3.6.0 on a windows 10 machine to develop a spring webmvc application.
When invoking mvn spring-boot:run the following exception occurs:
Caused by: java.io.IOException: CreateProcess error=206, The filename or extension is too long
at java.lang.ProcessImpl.create (Native Method)
at java.lang.ProcessImpl.<init> (ProcessImpl.java:420)
at java.lang.ProcessImpl.start (ProcessImpl.java:151)
at java.lang.ProcessBuilder.start (ProcessBuilder.java:1107)
at java.lang.ProcessBuilder.start (ProcessBuilder.java:1071)
at org.springframework.boot.loader.tools.RunProcess.run (RunProcess.java:81)
at org.springframework.boot.maven.RunMojo.forkJvm (RunMojo.java:103)
Problem: Our classpath is too long as we have many dependencies.
A feature/fix to shorten the command line in such cases (e.g. use of temp argFile) would be awesome.
Comment From: philwebb
Out of interest, have you tried this: https://www.howtogeek.com/266621/how-to-make-windows-10-accept-file-paths-over-260-characters/
Comment From: pneuschwander
@philwebb Thank you for that hint. I tried it but sadly it does not work in this case. Still getting the same exception :-/
Maybe it is not about the filepath length limit. java.lang.ProcessImpl.create javadoc states "Create a process using the win32 function CreateProcess." Found these information sources: - https://devblogs.microsoft.com/oldnewthing/20031210-00/?p=41553 - https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa
stating that the command line length is limited to 32767 characters. Our classpath exceeds this limit as there are too many entries...
Comment From: philwebb
Thanks for trying, we'll have to try and investigate what options we have.
Comment From: wilkinsona
I believe ./gradlew bootRun will also be affected.
There's some interesting discussion of this in a couple of Gradle issues: https://github.com/gradle/gradle/issues/1989 and https://github.com/gradle/gradle/issues/10114. A pathing jar (jar that's used purely to declare the classpath via its manifest) is the most common solution but those issues point out some notable downsides. The latter of the two is tracking a fix for the problem that would mean we don't need to do anything on the Gradle side when using Gradle 6+.
Comment From: koosty
I have the same issue with 2.2.0.RELEASE but works fine with 2.1.9.RELEASE. I'm using Windows 10 and tested both with Maven 3.5.0 and 3.6.0
Comment From: rampem
I have similar issue with 2.2.0.RELEASE and 2.2.1.RELEASE while 2.1.10.RELEASE works fine. It could be the classpath which in my case is around 37500 characters.
Comment From: bjornmagnusson
We are also experiencing this issue when upgrading to 2.2.0.RELEASE. Worked fine in 2.1.2.RELEASE
Discovered our classpath was roughly 38000 characters long
The work-around we took was moving the USER_HOME/.m2/repository to C:/m2
Comment From: wilkinsona
For those experiencing the problem on update, I would guess that there's now an extra transitive dependency or some version numbers have gained an extra digit and this has been enough to cause the length of the classpath to exceed Windows' limits. You may want to compare the old classpath with the new to identity where the extra length has been introduced.
Comment From: Jeevamanivel-tech
We are experiencing same issue with Spring Boot 1.5.13.RELEASE, Maven 3.6.3. Please throw some light on this. Tried following workarounds, none of them fixes the issue. 1. Moved m2 repository from USER_HOME/.m2/repository to D:/m2 2. maven-jar-plugin : manifest : addClassPath : true - Its adding all the jar path to manifest file. But doesn't fix the issue
Comment From: rekhubs
We are experiencing same issue with Spring Boot 1.5.13.RELEASE, Maven 3.6.3. Please throw some light on this. Tried following workarounds, none of them fixes the issue.
- Moved m2 repository from USER_HOME/.m2/repository to D:/m2
- maven-jar-plugin : manifest : addClassPath : true - Its adding all the jar path to manifest file. But doesn't fix the issue
this works for me: https://stackoverflow.com/a/54246754/2893542
Comment From: JavaWebinar
Forking is enabled by default since Spring Boot 2.2. See https://stackoverflow.com/questions/61125404/since-2-2-0-spring-boot-maven-plugin-create-2-java-process-may-cause-createproc question and solution
Comment From: H3llK33p3r
Why not being able to customize the plugin to use a file classpath (@argfile) ? Intellij offers this possibility to shorten the size of the arguments.
Comment From: cquoss
Wouldn't it be possible to switch the classpath from the command line (-cp) to the CLASSPATH environment variable? This would reduce the length of the command line drastically. I forked spring-boot to give this option a try.
Comment From: philwebb
@cquoss That might be an option, although I suspect it would work when the fork option is false
Comment From: cquoss
Yeah. But why not have it work with fork, too?
Comment From: cquoss
Well. My PR was rejected. I wanted to use CLASSPATH env var instead of -cp command line option.
You mentioned something of a better solution being using the Classpath entry in MANIFEST.MF of a dedicated classpath-only jar. But how is this activated when using spring-boot:run Maven goal on the Windows command line? How has the POM file to be changed to use this? Please advise.
Please note: My solution would have worked out-of-the-box. No changes in POM etc. needed.
Comment From: philwebb
@cquoss There's currently no way configure the POM file to use a pathing jar. We'd need to make changes to the code in order to support long paths.
Comment From: cquoss
Well then. Looks like my solution goes into a customized spring-boot maven plugin, then, here at our site. We need a solution.
Comment From: WoodenAndrew
Out of interest, have you tried this: https://www.howtogeek.com/266621/how-to-make-windows-10-accept-file-paths-over-260-characters/
Not applicable to Windows server 2012.
Comment From: boly38
I would try a workaround description of what did work for us
@regmebaby sources states that
command line length is limited to 32767 characters.
In order to diagnose your classpath length, use mvn debug mode (ie. mvn -X spring-boot:run). check Classpath for forked process output.
To make shortest your classpath component (java home and .m2), you could use this @rekhubs sources tips (cmd.exe)
mklink /J C:\M C:\Users\boly38\.m2\repository
mklink /J C:\J C:\Tools\Java\java-1.8.0-openjdk-1.8.0.275-1.b01
Then try again(I'm using git bash)
JAVA_HOME=/C/J mvn -Dmaven.repo.local=/C/M spring-boot:run
Windows <3
Comment From: kterry
This has become more relevant for Spring Boot 3 since fork option has been removed from the Maven plugin. This issue is currently blocking the migration of our projects to Spring Boot 3. An option to generate a pathing jar as suggested above would be ideal, akin to Exec Maven Plugin's longClasspath option.
Comment From: tomekdski
This thread is about spring-boot:run, but we also have a scenario for spring-boot:start Solution implemented in https://github.com/spring-attic/spring-native/pull/1585 looks great and would be a nice option.
Comment From: mhalbritter
We're now using an argfile when running on Windows. I explored the avenue with the pathing JAR, however it was a lot more code (because we need to separate directories from JARs, because only JARs can go in the manifest) and other funny stuff. The argfile change is pretty minimal.
Comment From: liudongmiao
@mhalbritter Could you make the file be deleted when exit? After the temp file is created, call file.toFile().deleteOnExit() or similiar should be enough.
Comment From: philwebb
Thanks for the suggestion @liudongmiao, I've opened #42841