diff --git a/README.md b/README.md index bf8562b8..19ff2775 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,11 @@ Optional system properties: Output directory into where the generated class files are written. Defaults to same as retrolambda.inputDir + retrolambda.classpathFile + File listing the classpath entries. + Alternative to retrolambda.classpath for avoiding the command line + length limit. The file must list one file per line with UTF-8 encoding. + retrolambda.includedFiles List of files to process, instead of processing all files. This is useful for a build tool to support incremental compilation. @@ -217,6 +222,9 @@ Version History ### Upcoming +- Added the `-Dretrolambda.classpathFile` parameter to avoid + the command line length limit + ([Issue #70](https://github.com/orfjackal/retrolambda/issues/70)) - Added the `-Dretrolambda.includedFilesFile` parameter to avoid the command line length limit ([Pull request #74](https://github.com/orfjackal/retrolambda/pull/74)) diff --git a/retrolambda/src/main/java/net/orfjackal/retrolambda/Config.java b/retrolambda/src/main/java/net/orfjackal/retrolambda/Config.java index 883aadc0..50149996 100644 --- a/retrolambda/src/main/java/net/orfjackal/retrolambda/Config.java +++ b/retrolambda/src/main/java/net/orfjackal/retrolambda/Config.java @@ -19,8 +19,9 @@ public class Config { public static final String INPUT_DIR = PREFIX + "inputDir"; public static final String OUTPUT_DIR = PREFIX + "outputDir"; public static final String CLASSPATH = PREFIX + "classpath"; + public static final String CLASSPATH_FILE = CLASSPATH + "File"; public static final String INCLUDED_FILES = PREFIX + "includedFiles"; - public static final String INCLUDED_FILES_FILE = PREFIX + "includedFilesFile"; + public static final String INCLUDED_FILES_FILE = INCLUDED_FILES + "File"; private static final List requiredProperties = new ArrayList<>(); private static final List requiredPropertiesHelp = new ArrayList<>(); @@ -101,7 +102,11 @@ public boolean isDefaultMethodsEnabled() { } public Path getInputDir() { - return Paths.get(getRequiredProperty(INPUT_DIR)); + String inputDir = p.getProperty(INPUT_DIR); + if (inputDir != null) { + return Paths.get(inputDir); + } + throw new IllegalArgumentException("Missing required property: " + INPUT_DIR); } @@ -115,10 +120,10 @@ public Path getInputDir() { public Path getOutputDir() { String outputDir = p.getProperty(OUTPUT_DIR); - if (outputDir == null) { - return getInputDir(); + if (outputDir != null) { + return Paths.get(outputDir); } - return Paths.get(outputDir); + return getInputDir(); } @@ -128,22 +133,32 @@ public Path getOutputDir() { requiredParameterHelp(CLASSPATH, "Classpath containing the original class files and their dependencies.", "Uses ; or : as the path separator, see java.io.File#pathSeparatorChar"); + optionalParameterHelp(CLASSPATH_FILE, + "File listing the classpath entries.", + "Alternative to " + CLASSPATH + " for avoiding the command line", + "length limit. The file must list one file per line with UTF-8 encoding."); } public List getClasspath() { - String classpath = getRequiredProperty(CLASSPATH); - return Stream.of(classpath.split(File.pathSeparator)) - .filter(path -> !path.isEmpty()) - .map(Paths::get) - .collect(Collectors.toList()); - } - - private String getRequiredProperty(String key) { - String value = p.getProperty(key); - if (value == null) { - throw new IllegalArgumentException("Missing required property: " + key); + String classpath = p.getProperty(CLASSPATH); + if (classpath != null) { + return Stream.of(classpath.split(File.pathSeparator)) + .filter(path -> !path.isEmpty()) + .map(Paths::get) + .collect(Collectors.toList()); + } + String classpathFile = p.getProperty(CLASSPATH_FILE); + if (classpathFile != null) { + try { + return Files.readAllLines(Paths.get(classpathFile)).stream() + .filter(line -> !line.isEmpty()) + .map(Paths::get) + .collect(Collectors.toList()); + } catch (IOException e) { + throw new RuntimeException("Failed to read " + CLASSPATH_FILE + " from " + classpathFile, e); + } } - return value; + throw new IllegalArgumentException("Missing required property: " + CLASSPATH); } diff --git a/retrolambda/src/test/java/net/orfjackal/retrolambda/ConfigTest.java b/retrolambda/src/test/java/net/orfjackal/retrolambda/ConfigTest.java index 2f1e1315..1d65db4d 100644 --- a/retrolambda/src/test/java/net/orfjackal/retrolambda/ConfigTest.java +++ b/retrolambda/src/test/java/net/orfjackal/retrolambda/ConfigTest.java @@ -74,9 +74,21 @@ public void classpath() { assertThat("multiple values", config().getClasspath(), is(Arrays.asList(Paths.get("one.jar"), Paths.get("two.jar")))); } - @Ignore // TODO @Test - public void classpath_file() { + public void classpath_file() throws IOException { + Path file = tempDir.newFile("classpath.txt").toPath(); + + Files.write(file, Arrays.asList("", "", "")); // empty lines are ignored + systemProperties.setProperty(Config.CLASSPATH_FILE, file.toString()); + assertThat("zero values", config().getClasspath(), is(empty())); + + Files.write(file, Arrays.asList("one.jar")); + systemProperties.setProperty(Config.CLASSPATH_FILE, file.toString()); + assertThat("one value", config().getClasspath(), is(Arrays.asList(Paths.get("one.jar")))); + + Files.write(file, Arrays.asList("one.jar", "two.jar")); + systemProperties.setProperty(Config.CLASSPATH_FILE, file.toString()); + assertThat("multiple values", config().getClasspath(), is(Arrays.asList(Paths.get("one.jar"), Paths.get("two.jar")))); } @Test @@ -102,19 +114,19 @@ public void included_files() { @Test public void included_files_file() throws IOException { - Path listFile = tempDir.newFile("list.txt").toPath(); + Path file = tempDir.newFile("includedFiles.txt").toPath(); assertThat("not set", config().getIncludedFiles(), is(nullValue())); - Files.write(listFile, Arrays.asList("", "", "")); // empty lines are ignored - systemProperties.setProperty(Config.INCLUDED_FILES_FILE, listFile.toString()); + Files.write(file, Arrays.asList("", "", "")); // empty lines are ignored + systemProperties.setProperty(Config.INCLUDED_FILES_FILE, file.toString()); assertThat("zero values", config().getIncludedFiles(), is(empty())); - Files.write(listFile, Arrays.asList("one.class")); - systemProperties.setProperty(Config.INCLUDED_FILES_FILE, listFile.toString()); + Files.write(file, Arrays.asList("one.class")); + systemProperties.setProperty(Config.INCLUDED_FILES_FILE, file.toString()); assertThat("one value", config().getIncludedFiles(), is(Arrays.asList(Paths.get("one.class")))); - Files.write(listFile, Arrays.asList("one.class", "two.class")); - systemProperties.setProperty(Config.INCLUDED_FILES_FILE, listFile.toString()); + Files.write(file, Arrays.asList("one.class", "two.class")); + systemProperties.setProperty(Config.INCLUDED_FILES_FILE, file.toString()); assertThat("multiple values", config().getIncludedFiles(), is(Arrays.asList(Paths.get("one.class"), Paths.get("two.class")))); } }