1

My files are located under projectRoot/src/main/resources/levels/

enter image description here

If I call Utils.getFileNamesInDirectory("src/main/resources/levels"), it works.
But when project is packaged, levels directory is placed under root of .jar.
How can I made this dynamic in static class? i.e src/main/resources/
So that code will run within eclipse and as standalone jar.

Code to list files in directory ..

public class Utils {
    public static List<String> getFileNamesInDirectory(String directory){

        List<String> results = new ArrayList<String>();

        File[] files = new File(directory).listFiles(new FilenameFilter() {
            public boolean accept(File dir, String filename) {
                return filename.endsWith(".json");
            }
        });

        for (File file : files) {
            if (file.isFile()) {
                results.add(file.getName());
            }
        }

        Collections.sort(results);

        return results;
    }
}

Updated

I've moved to using getResourceAsStream (as getResource was causing IllegalArgumentException: URI is not hierarchical) and I'm able to list files in a directory within Eclipse.

public static List<String> getFileNamesInDirectory(String directory){

        List<String> results = new ArrayList<String>();
        InputStream in = Utils.class.getResourceAsStream("/" + directory);
        BufferedReader rdr = new BufferedReader(new InputStreamReader(in));
        String line;

        try {

            while ((line = rdr.readLine()) != null) {
                System.out.println("file: " + line);
                results.add(new File(line).getName());
            }

            rdr.close();
        } catch (IOException e1) {
            e1.printStackTrace();
        }

        Collections.sort(results);

        return results;
    }

But when I run it as standalone .jar I get the following error on this line: while ((line = rdr.readLine()) != null) {
Why does it not work outside Eclipse?

Exception in thread "main" java.lang.NullPointerException
    at java.io.FilterInputStream.read(FilterInputStream.java:133)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:322)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:364)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:210)
    at java.io.InputStreamReader.read(InputStreamReader.java:205)
    at java.io.BufferedReader.fill(BufferedReader.java:165)
    at java.io.BufferedReader.readLine(BufferedReader.java:328)
    at java.io.BufferedReader.readLine(BufferedReader.java:393)
    at com.app.tools.Utils.getFileNamesInDirectory(Utils.java:31)
4
  • 1
    You don't. /src/main/resources is a project directory convention used by Maven to contain resources that will end up at the root of a generated archive/classpath. Commented Aug 31, 2014 at 18:55
  • In, eclipse you should also use the classpath rather than the file system. Commented Aug 31, 2014 at 18:56
  • I'm aware src/main/resources is a directory convention for Maven. Do you have example of classpath use over filesystem? Commented Aug 31, 2014 at 19:02
  • See docs.oracle.com/javase/7/docs/api/java/lang/…. Commented Aug 31, 2014 at 19:03

1 Answer 1

3

The reason your code works in Eclipse is that Eclipse launches the java process from the project directory and we can assume the path provided in

Utils.getFileNamesInDirectory("src/main/resources/levels")

is relative to the current working directory (the project directory). Since the file system location <project-directory>/src/main/resources/levels exists, it can be found and returned to you.

src/main/resources is a Maven convention meant to hold resources that will eventually end up in the classpath when the project is compiled/built/deployed. To retrieve resources from the classpath you use Class#getResource(String), ClassLoader#getResource(String) and/or ClassLoader#getSystemResource(String).

Now, although there are ways to list resources in the classpath, you should not typically do this. If you need a resource, you know it by name and can therefore use one of the methods listed above to get it.

Sign up to request clarification or add additional context in comments.

8 Comments

I'm no longer using file system approach, instead using getResourceAsStream but still having issues, any ideas? updated question
@bobbyrne01 getResourceAsStream returns null if no matching resource can be found. Does your .jar contain the resource at the right (specified) path?
The .jar has folder at /levels i.e the root of .jar. I'm passing /levels to getResourceAsStream
@bobbyrne01 A directory does not constitute a resource. Is /levels a directory or a file entry in the .jar?
/levels is a directory contains 3 files i.e level1.json, level2.json and level3.json .. all of which are in the .jar
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.