# JavaExec fails for long classpaths on Windows

**URL:** <https://discuss.gradle.org/t/javaexec-fails-for-long-classpaths-on-windows/15266>\
**Category:** Bugs\
**Created:** [March 18, 2016, 12:36pm UTC](https://discuss.gradle.org/t/javaexec-fails-for-long-classpaths-on-windows/15266 "2016-03-18T12:36:28Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![ThiporKong](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/thiporkong/32/4493_2.png) [@ThiporKong](https://discuss.gradle.org/u/ThiporKong)\
**Post date:** [March 18, 2016, 12:36pm UTC](https://discuss.gradle.org/t/javaexec-fails-for-long-classpaths-on-windows/15266/1 "2016-03-18T12:36:28Z")

</div>

JavaExec doesn’t work for long classpaths on Windows. The problem is similar to the ones described [here](https://discuss.gradle.org/t/filename-too-long-in-windows/9222) or [here](https://discuss.gradle.org/t/test-classpath-gets-too-long-for-windows/6524).

The underlying reason is, that the JavaExecHandleBuilder (from which DefaultJavaExecAction derives) just [puts the whole classpath into the ‘-cp’ command line parameter](https://github.com/gradle/gradle/blob/master/subprojects/core/src/main/groovy/org/gradle/process/internal/JavaExecHandleBuilder.java#L47) for the JVM.

- Are there any plans for supporting long classpaths properly out-of-the-box?
- If not, what’s the proper approach to configure the use of your own JavaExecAction implementation?

I have seen there are [ExecActionFactory.newJavaExecAction()](https://github.com/gradle/gradle/blob/master/subprojects/core/src/main/groovy/org/gradle/process/internal/ExecActionFactory.java#L25) and [ProjectScopeServices.createExecActionFactory()](https://github.com/gradle/gradle/blob/master/subprojects/core/src/main/groovy/org/gradle/internal/service/scopes/ProjectScopeServices.java#L115), but couldn’t figure out how to plug in my own factories.

---

<div class="post-metadata">

**Author:** ![ThiporKong](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/thiporkong/32/4493_2.png) [@ThiporKong](https://discuss.gradle.org/u/ThiporKong)\
**Post date:** [March 18, 2016, 1:06pm UTC](https://discuss.gradle.org/t/javaexec-fails-for-long-classpaths-on-windows/15266/2 "2016-03-18T13:06:08Z")

</div>

Feel free to make use of this specialization of DefaultJavaExecAction:

```
public class LongClasspathExecAction extends DefaultJavaExecAction {
    public LongClasspathExecAction(final FileResolver fileResolver) {
        super(fileResolver);
    }

    @Override
    public List<String> getAllJvmArgs() {
        final List<String> allArgs = new ArrayList<>(getJvmArgs());
        final FileCollection classpath = getClasspath();
        if (!classpath.isEmpty()) {
            try {
                final File jarFile = toJarWithClasspath(classpath.getFiles());
                allArgs.add("-cp");
                allArgs.add(jarFile.toString());
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }
        return allArgs;
    }

    private static final String MATCH_CHUNKS_OF_70_CHARACTERS = "(?<=\\G.{70})";

    private static File toJarWithClasspath(final Set<File> files) throws IOException {
        final File jarFile = File.createTempFile("long-classpath", ".jar");
        try (final ZipOutputStream zip = new ZipOutputStream(new FileOutputStream(jarFile))) {
            zip.putNextEntry(new ZipEntry("META-INF/MANIFEST.MF"));
            try (final PrintWriter pw = new PrintWriter(new OutputStreamWriter(zip, StandardCharsets.UTF_8))) {
                pw.println("Manifest-Version: 1.0");
                final String classPath = CollectionUtils.join(" ", CollectionUtils.collect(files, File::toURI));
                final String classPathEntry = "Class-Path: " + classPath;
                pw.println(CollectionUtils.join("\n ", classPathEntry.split(MATCH_CHUNKS_OF_70_CHARACTERS)));
            }
        }
        return jarFile;
    }
}
```

---

<div class="post-metadata">

**Author:** ![Ned\_Twigg](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/ned_twigg/32/1516_2.png) [@Ned\_Twigg](https://discuss.gradle.org/u/Ned_Twigg)\
**Post date:** [May 4, 2016, 8:12pm UTC](https://discuss.gradle.org/t/javaexec-fails-for-long-classpaths-on-windows/15266/3 "2016-05-04T20:12:06Z")

</div>

How do we make use of this? I can hack something together by with `project.javaExec()`, but is there a way to swap the default implementation with this one?

Btw, for how many posts there are about this, it’s crazy there’s no warning or real fix in gradle core yet.
