tags:

views:

37

answers:

3

Hi,

The title might not be entirely clear, but I'll try to explain.

I'm trying to access a file with a path like /net/blm50+hmm/synlist/, which works fine when I don't export to a jar file and just run it from within my IDE (eclipse). However, if I try to run it when I have exported it, I get a null pointer exception. It runs without a problem if I rename the path to not have the plus sign in it. Can I escape the plus sign or something like that?

You might ask why I don't just rename the folder, and the reason for this is laziness. There is ALOT of folders to rename and I'd rather avoid it.

I hope You can help,

shalmon

EDIT:

I have a class FileUtils I use for accessing resources in the application jar:

public class FileUtils {

public static InputStream getInputStreamForResource(String resourcePath) throws IOException {
    // Try to get the file from the application jar first.
    InputStream result = FileUtils.class.getResourceAsStream(resourcePath);

    return result;
}

public static Scanner getScanner(String resourcePath) throws IOException {
    return new Scanner(getInputStreamForResource(resourcePath));
}

}

If I call getScanner("/net/blm50+hmm/synlist/"); I get the null pointer exception.

The stacktrace is (the call to getScanner happens in NetworkCollection.fromSynapseList):

java.lang.NullPointerException
    at java.io.Reader.<init>(Reader.java:61)
    at java.io.InputStreamReader.<init>(InputStreamReader.java:55)
    at java.util.Scanner.<init>(Scanner.java:590)
    at persistence.FileUtils.getScanner(FileUtils.java:34)
    at calculation.NetworkCollection.fromSynapseList(NetworkCollection.java:89)
    at processes.JobDispatcher.doInBackground(JobDispatcher.java:136)
    at processes.JobDispatcher.doInBackground(JobDispatcher.java:1)
    at javax.swing.SwingWorker$1.call(SwingWorker.java:277)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at javax.swing.SwingWorker.run(SwingWorker.java:316)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:619)
A: 

For that code to work, the jar file must be available to the ClassLoader that loaded FileUtils (or simply, it should be on the classpath).

Mark Peters
@Mark, how do you think he got the exception in first place?
OscarRyz
@Mark: It is. I use FileUtils several times throughout the project and it is only when there is a "+" present in the path that I get the null pointer exception.
shalmon
@Oscar: What do you mean? The resource could easily be in a jar that doesn't contain the code being run.
Mark Peters
A: 

I once had a problem that could be somehow related: I got an exception when I tried to access a resource inside a jar file. Some code that worked with Java 1.4.2 but not with Java 1.6. At least I found a workaround...

Bet it's not a solution but maybe it's close enough to provide some help on your problem.

Andreas_D
A: 

Try the following in your machine.

That is, create a file insulating the code that is failing and test it with a small subset of the input ( that is just one file, one with the + and one without it )

#create two folders: code and code+plus containing one file each
$ls -l code code+plus/ 
code:
total 8
-rw-r--r--  1 oscarreyes  staff  2 Jul  5 18:19 x

code+plus/:
total 8
-rw-r--r--  1 oscarreyes  staff  2 Jul  5 18:18 x

# create a sample with the code in question
$cat FileUtils.java 
import java.io.*;
import java.util.*;

public class FileUtils {

    public static InputStream getInputStreamForResource(String resourcePath) throws IOException {
        // Try to get the file from the application jar first.
        InputStream result = FileUtils.class.getResourceAsStream(resourcePath);
        return result;
    }

    public static Scanner getScanner(String resourcePath) throws IOException {
        return new Scanner(getInputStreamForResource(resourcePath));
    }
    public static void main( String [] args )  throws IOException {
        Scanner scanner = getScanner( args[0] );
        System.out.println( args[0] + " : OK");
    }

} 
#compile it
$javac FileUtils.java 

# package it with the subfodlers
$jar -cmf mf f.jar FileUtils.class  code+plus/ code 

# execute it without "+"
$java -jar f.jar /code/x 
/code/x : OK

#execute it with "+"
$java -jar f.jar /code+plus/x 
/code+plus/x : OK

#To get Npe, use a non existing file
$java -jar f.jar /code+plus/y 

Let me know if you still having the problem.

I'm pretty sure now your problem is while creating the jar file, you're now including the "+" file you think you're including.

To verify, run jar -tf your.jar and see if the file with + is listed.

OscarRyz
I don't understand...you criticize my answer and then post the exact same thing 15 minutes later?
Mark Peters
@Mark jejeje probably I didn't understand it, or you didn't write it well. You said: *"...the jar file must be available to the ClassLoader that loaded FileUtils"* Since the NullPointer was thrown from the FileUtil class and the FileUtil class **is** inside the jar file, then, the jar file is already available to the FileUtils classloader ( otherwise how could it be loaded in first place ) Perhaps we are saying the same thing but I didn't quite get your answer :)
OscarRyz
@OscarRyz: My point was that there could be two jar files. Just because (the jar that contained) FileUtils.class was on the classpath, doesn't mean that the jar containing the resource was also on the classpath.
Mark Peters
@Mark, now **that** makes sense. I didn't understand it that way from your answer. :)
OscarRyz
The folders are added to the classpath. I get no exceptions if I remove the "+" from the file path and I can access files in the same parent folder (`/net`) with no problems.
shalmon
@Oscar: Yeah we have two different interpretations of @shalmon's problem. I assumed the resource was packaged in the jar, you assumed FileUtils was packaged in the jar. Be nice to get that part confirmed by the OP.
Mark Peters
Both the resource and FileUtils are packaged in the jar.
shalmon
Mhh that's strange. Must be bug in your platform, or simply, the file you think exist in the jar doesn't exist. See my update.
OscarRyz
I have checked the jar file and the folder that has the "+" sign is included. I have now renamed all of the folders, but would still like to know why this happens. :)
shalmon
Did you run the sample code I provided? What's your JVM version?
OscarRyz