Filename too long in Windows


(Sathyakumar Seshachalam) #1

I am beginning to move my maven based project to a gradle based java application that runs on Windows 7. I ran in to an error java.io.IOException: CreateProcess error=206, The filename or extension is too long because of a really long classpath dependencies. I worked around it by shortening the path to my code and java executable location, While this was Ok for sometime, I hit that limit again today when I added few command line argument.

My questions are -

  1. What’s the prescribed way to run applications that have a huge dependency graph. ( I think what I’m working on is relatively small considering other big java apps I have seen).
  2. Is there a way to shorten some paths that gradle adds. For e.g I could see that classpath is pointing to a cached folder org.apache.pdfbox\fontbox\1.8.1`32879bb6bb87b15c6d53bc358e83ede40fc729ae`\fontbox-1.8.1.jar

Ideally I would love to use Gradle to just run my app gradle run. But at the moment, I feel that its not viable in its current state as even adding few extra command line arguments is going to break this in Windows.


JavaExec fails for long classpaths on Windows
(Mark Vieira) #2

This is a known limitation. There are some possible workarounds. See this response to a similar question for info.


(Jason Hatton) #3

I have encountered a similar issue with the generated start up scripts from the Application plugin and in particular the Spring Boot plugin where the classpath created results in an “Input too long” error. This link is a reference to the issue in the old forums.

Here is a Gradle script modification that uses relative paths to fix the issue. This would help avoid any out of order classpath problems using the asterisks workaround. Just depends on the use case which one is most valuable, neither is more right.

startScripts {
    // Support closures to add an additional element to
    // CLASSPATH definition in the start script files.
    def configureClasspathVar = { findClasspath, pathSeparator, line ->

        // Looking for the line that starts with either CLASSPATH=
        // or set CLASSPATH=, defined by the findClasspath closure argument.
        line = line.replaceAll(~/^${findClasspath}=.*$/) { original ->

            // Get original line and append it
            // with the configuration directory.
            // Use specified path separator, which is different
            // for Windows or Unix systems.
            original = original.replaceAll '%APP_HOME%\\\\', ''    
        }

    }

    def configureUnixClasspath = configureClasspathVar.curry('CLASSPATH', ':')
    def configureWindowsClasspath = configureClasspathVar.curry('set CLASSPATH', ';')

    // The default script content is generated and
    // with the doLast method we can still alter
    // the contents before the complete task ends.
    doLast {

        // Alter the start script for Unix systems.
        unixScript.text =
                unixScript
                        .readLines()
                        .collect(configureUnixClasspath)
                        .join('\n')

        // Alter the start script for Windows systems.
        windowsScript.text =
                windowsScript
                        .readLines()
                        .collect(configureWindowsClasspath)
                        .join('\r\n')

    }
}

Maybe someone can take this and work on a pull request that would introduce a relative path concept to the script generation, or another even better solution.


(Jaroslaw Nowosad) #7

How did you use “long path tool” to solve this? Not see anything in common… Please share.
At the moment looking into manifest-jar solution, but is not so straight forward :frowning:


(Stefan Oehme) #8

Please ignore the long path tool spam. Unfortunately some of them slip through spam detection.


(Trejkaz (pen name)) #9

Is there a ticket for this to get fixed properly in Gradle core?

It seems like a bit of a joke to me that a self-proclaimed “declarative” build system is forcing us to write all this procedural code just to get something basic like JavaExec to work at all. And not even a particularly funny joke.


(Trejkaz (pen name)) #10

Another half a year has passed - does JavaExec work in Gradle core yet?


(Frederik Santibanez) #12

Some people don’t believe that Long path tool is a waste but I did really use it for this problem and it work. I don’t understand why it doesn’t work for others. Why don’t give it a try?


(Malcolm McRoberts) #14

I think I understand how to add the classpath to the manifest. How does that reduce the command length? Don’t I also have to remove this path somewhere else? I’m trying to build a project someone else built, but I’m the only one that seems to be having this problem.