Undesired Behavior When Attempting To Find Which Directory Jar Is Located In

Started by
5 comments, last by TheChubu 9 years, 5 months ago

I have been writing a program that ( so far ) sorts out all the sub directories inside of the same directory were the .jar file is executed .

Unexpected behavior has popped up unfortunately.

These undesired behaviors are as follows:

1: When testing this in Eclipse I get a list of the files inside of the package

2: After compiling the .jar file, I get null pointers errors when executing the program .

What am I doing wrong here, and how to correct it ?


public class Files {
    File rawFiles;
    List <File> fileList;
    List <File> dirList;
    List <File> outGoing;
    String temp[];
    Scanner scan;
    
    public Files() throws Exception{
        
        
        String x = Files.class.getProtectionDomain().getCodeSource().getLocation().getPath(); // get path were .jar is
        String path = URLDecoder.decode(x, "UTF-8");
        scan = new Scanner(System.in);
        rawFiles = new File(path);
        fileList = new ArrayList<File>( );
        dirList = new ArrayList<File>();
        outGoing = new ArrayList<File>();
        fileList = (Arrays.asList(rawFiles.listFiles() ) );
        
        for ( int i = 0; i != fileList.size(); i ++ ){ // build list of all directories
            if (fileList.get(i).isDirectory() ){
                dirList.add(fileList.get(i) );
            }
        } // End of for
        
        for ( int i = 0; i != dirList.size(); i ++){ // filter out empty directories
            temp = dirList.get(i).list(); // dirList.get(i).length DOES NOT WORK !!!

            if ( temp.length > 0){
                System.out.println("Added directory to processing list: " + dirList.get(i).getName() );
                outGoing.add(dirList.get(i));
            }
            else{
                System.out.println("Removed empty directory from list: " + dirList.get(i).getName() );
            }
        } // End of for
        scan.nextLine(); // pause execution before closing
        
    }
}

I cannot remember the books I've read any more than the meals I have eaten; even so, they have made me.

~ Ralph Waldo Emerson

Advertisement

I don't really understand what you're trying to do. Unfortunately "sorts out" is a very vague term, and "directories inside of the file WERE the .jar file is executed" is confusing.

Is it that you have some resource files in the Jar, and you want to enumerate them? Or do you have a set of files that are deployed with the Jar? Or are you talking about the working directory of execution?

If you're getting NullPointerExceptions, then presumably you have a stack trace? Why didn't you post it? Can you catch the exception in a debugger to discover which (sub) expression is null?


are you talking about the working directory of execution?

.

As stated in in the post, no errors happen when tested in Eclipse ( except for undesired behavior ) .

Stack trace is worthless in this case - however it indirectly points to the string "path" being null, which points to string "x" being null.

C:\Users\RICK\Desktop>java -jar test.jar
Exception in thread "main" java.lang.NullPointerException
at java.util.Arrays$ArrayList.<init>(Unknown Source)
at java.util.Arrays.asList(Unknown Source)
at me.RLS0812.Testing.Files.<init>(Files.java:29)
at me.RLS0812.Testing.Main.main(Main.java:7)

I cannot remember the books I've read any more than the meals I have eaten; even so, they have made me.

~ Ralph Waldo Emerson

Without understanding the desired behaviour, it is difficult to help you.

The stacktrace is not worthless. It points to inside Arrays.asList, therefore "rawFiles" must be non-null, but rawFiles.listFiles() must be returning null. In the Java documentation:


Returns:

An array of abstract pathnames denoting the files and directories in the directory denoted by this abstract pathname. The array will be empty if the directory is empty. Returns null if this abstract pathname does not denote a directory, or if an I/O error occurs.

Note that the documentation also states that the File(String) constructor throws a NullPointerExeption when passed null, which indicates that "path" is not null, which strongly indicates that "x" is not null. You could trivially prove this using the debugger or print statements at various points to show these intermediate values.

Took me way too long to spot the problem.

I was passing in the complete path to the .jar file, instead of the path to directory were the .jar was located.

Here is the corrected code ( with some redundant features removed )


public class Files {
    File rawFiles;
    List <File> fileList;
    List <File> outGoing;
    String temp[];
    Scanner scan;
    
    public Files() throws Exception{
        
        scan = new Scanner(System.in);
        rawFiles = new File(System.getProperty("user.dir")); // get jar location
        fileList = new ArrayList<File>( );
        outGoing = new ArrayList<File>();
        fileList = (Arrays.asList(rawFiles.listFiles() ) ); // dump files to list

        
        for ( int i = 0; i != fileList.size(); i ++ ){ // build list of all directories
            if (fileList.get(i).isDirectory() ){
                temp = fileList.get(i).list();
                
                if ( temp.length > 0){ // filter out empty directories
                    System.out.println("Added directory to processing list: " + fileList.get(i).getName() );
                    outGoing.add(fileList.get(i));
                     }
                }
        } // End of for
        
        
        System.out.print("\nPress Enter: ");
        scan.nextLine(); // pause execution before closing
        }
    }

I cannot remember the books I've read any more than the meals I have eaten; even so, they have made me.

~ Ralph Waldo Emerson

Note that there is no guarantee the Jar is located in "user.dir". The working directory may be different, by executing the program something like so:

$ pwd
/home/someUser
$ cat Help.java
public class Help {
    public static void main(String [] args) {
        System.out.println(System.getProperty("user.dir"));
    }
}
$ javac *.java && jar cevf Help Help.jar Help.class
added manifest
adding: Help.class(in = 478) (out= 309)(deflated 35%)
$ java -jar Help.jar
/home/someUser
$ cd someDirectory
$ java -jar ../Help.jar
/home/someUser/someDirectory

btw, you're creating a fileList


 fileList = new ArrayList<File>( );

Then, immediately after, you create a new one:


 fileList = (Arrays.asList(rawFiles.listFiles() ) );

Just do the second line, no need to create the first fileList.

If you have access to Java 8, you can also do something like:


List<File> outGoing = fileList.stream().filter( (f) -> f.isDirectory() && f.list().length > 0 ).collect ( Collectors.toList() );

"I AM ZE EMPRAH OPENGL 3.3 THE CORE, I DEMAND FROM THEE ZE SHADERZ AND MATRIXEZ"

My journals: dustArtemis ECS framework and Making a Terrain Generator

This topic is closed to new replies.

Advertisement