Search code examples
javamavenjarapache-commons-cli

Apache CLI, Executable jar, classLoader().getResource()


My goal is to use Apache CLI with an executable jar file to read in a text file, perform string manipulations, and then write to a CSV. You would execute the tool in the terminal like this:

$ java -jar my-tool-with-dependencies.jar -i input.txt -o output.csv

I've written tests for this functionality and those tests are passing. The test input text file is located in src/test/resources/. The following test is passing:

@Test
public void testWordockerWriteCsvFileContents() {
// Make sure the csv file contains contents

Wordocker w = new Wordocker();

String intext = "/textformat/example_format.txt";
String outcsv = "/tmp/foo.csv";

w.writeCsvFile(intext, outcsv);

try {

Reader in = new FileReader(outcsv);
Iterable<CSVRecord> records = CSVFormat.DEFAULT.parse(in);
for (CSVRecord record : records) {
    assertTrue(record.toString().length() > 0);
}
} catch(FileNotFoundException e){
    assertTrue(false);
} catch(IOException e) {
    assertTrue(false);
}

File file = new File(outcsv);
if (file.exists()) {
    file.delete();
}

}

We I compile my jar files with dependencies using mvn clean compile assembly:single then I raise the following FileNotFoundException:

    // Get file from resources folder
    URL resourceURL = ParseDoc.class.getClassLoader().getResource(fileName);

    if (resourceURL == null) {
    throw new FileNotFoundException(fileName + " not found");
    }
    file = new File(resourceURL.getFile());

This leads me to believe that there is an issue with where ParseDoc.class.getClassLoader().getResource(fileName); is looking for the file. I'm aware of related questions which have been asked. Related questions are the following:

None of these questions appear to ask about how to use an executable jar with Apache CLI. I think the basic issue is that the filepath given by my command line argument cannot be found by URL resourceURL = ParseDoc.class.getClassLoader().getResource(fileName);.

Please let me know what you think. Thank you for your time.


Solution

  • I'm posting this as answer as well after discussion via comments:

    Classloader.getResource() is only fetching files that are packaged as part of the Jar-file or located in the classpath-folders.

    For reading a normal file you would use something like your first example, i.e. FileReader or FileInputStream or simply pass a java.io.File depending on what the library that you are trying to use supports.