aspose file tools*
The moose likes I/O and Streams and the fly likes Class.getResourceAsStream() is returning null Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » I/O and Streams
Bookmark "Class.getResourceAsStream() is returning null" Watch "Class.getResourceAsStream() is returning null" New topic
Author

Class.getResourceAsStream() is returning null

Layne Lund
Ranch Hand

Joined: Dec 06, 2001
Posts: 3061
I am trying to read a text file as a resource using Class.getResourceAsStream(), but it is returning null. I've checked everything I can think of. Hopefully I can provide enough detail here so you can understand what I'm doing and point out where I'm going wrong.

First of all, I have the following method that is supposed to read the text file and execute the SQL code in it:


Then I have a JUnit test for this method:



When I run this JUnit test, I get the following output:


DatabaseUtil.java:38 is the line after the one indicated that returns null.

I probably need to explain the Standard Output section:



The first line is so I know which test is producing the next few lines of output. The next line shows what the "user.dir" property is set to. The third line shows the parent used for any relative paths sent to Class.getResource() (which I assume is the same parent used for Class.getResourceAsStream() --- maybe this is a bad assumption?).

I've double checked the path for the file to make sure it is there. Under the "/matrim/home/kasamba/projects/moneyca/attendance" directory I have a "sql" directory that contains the "create-tables.sql" file. So as far as I can tell, the file exists. So why does Class.getResourceAsStream() return null? What am I missing here?

I hope I've described my problem well enough so you understand what is happening. If you would like any other information, please let me know. I would REALLY appreciate any suggestions you have.

Thanks,

Layne
[ June 08, 2005: Message edited by: Layne Lund ]

Java API Documentation
The Java Tutorial
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24183
    
  34

Absolute paths passed to Class.getResourceAsStream() are interpreted as paths relative to each "classpath root" in turn, not as absolute paths relative to the filesystem root. If you have an absolute filesystem path, then use FileInputStream! Otherwise, if you want to use a classpath-relative path, then don't include the /home/... part -- include something that can be found in one of the directories or JAR files listed on the classpath.

Or add "/" to your CLASSPATH!

P.S. Two duplicate posts pointing to this post does, indeed, count as crossposting


[Jess in Action][AskingGoodQuestions]
Layne Lund
Ranch Hand

Joined: Dec 06, 2001
Posts: 3061
Originally posted by Ernest Friedman-Hill:
Absolute paths passed to Class.getResourceAsStream() are interpreted as paths relative to each "classpath root" in turn, not as absolute paths relative to the filesystem root. If you have an absolute filesystem path, then use FileInputStream! Otherwise, if you want to use a classpath-relative path, then don't include the /home/... part -- include something that can be found in one of the directories or JAR files listed on the classpath.

Or add "/" to your CLASSPATH!


Doh! I guess the problem runs deeper than I thought. I'm using NetBeans for development, although, that probably doesn't matter. Eventually, this will be a small portion of a larger project that I plan on deploying as an executable JAR file. So when I call executeSQLFromFile() in production code I want to use a path relative to the class path. Most likely there will be a /sql directory in the JAR file where the SQL scripts will reside.

The problem comes when I run my tests. At least when I run them from NetBeans, it calls executeSQLFromFile() in the .class file under the build directory rather than using the JAR file.

What is a good way to be able to run this code from both an executable JAR and a .class file that's sitting directly in my file system?


P.S. Two duplicate posts pointing to this post does, indeed, count as crossposting


So is it crossposting because those two posts are duplicates or because they point to my real question?
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24183
    
  34

Originally posted by Layne Lund:

What is a good way to be able to run this code from both an executable JAR and a .class file that's sitting directly in my file system?


Ideally, just have the filesystem layout be the same as it would be in the jar. If the class is com/foo/Bar and the jar will have a dir named "sql", then yor development environment should have



And then have "/home/layne/project" on your CLASSPATH, and use getResourceAsStream("/sql/myfile.sql"). That should work both in the jar and on disk.


So is it crossposting because those two posts are duplicates or because they point to my real question?


Yes
Layne Lund
Ranch Hand

Joined: Dec 06, 2001
Posts: 3061
Originally posted by Ernest Friedman-Hill:

Ideally, just have the filesystem layout be the same as it would be in the jar. If the class is com/foo/Bar and the jar will have a dir named "sql", then yor development environment should have


And then have "/home/layne/project" on your CLASSPATH, and use getResourceAsStream("/sql/myfile.sql"). That should work both in the jar and on disk.


That's esentially the solution I came up with on my own!

However, once I fixed that I encountered other problems that basically made this whole approach moot anyway. I was trying to read in a SQL file that had mutiple CREATE TABLE commands. Unfortunately, JDBC doesn't like it when you try to run them all at once as a single String. So now I seperated each CREATE TABLE into its own file. I'm storing all of the files in yet another subdirectory (sql/create-tables). Now I want to iterate over all the .sql files in a directory and "execute" them. I know how to do this easily with the File.list() or File.listFiles(). In fact, that's how I've implemented it now. Is there something similar with resources? Or maybe even by accessing the JAR file directly? The later would probably reduce the whole problem with the differences between executing from the JAR and without it.

Layne
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24183
    
  34

There's nothing like a "listResources" method, so reading the jar file directly is probably the only option if you really won't know what files are available. You might consider having another file which lists the available SQL files, though, as this would let you stay "portable" between the development and deployment environments.
Layne Lund
Ranch Hand

Joined: Dec 06, 2001
Posts: 3061
Originally posted by Ernest Friedman-Hill:
There's nothing like a "listResources" method, so reading the jar file directly is probably the only option if you really won't know what files are available. You might consider having another file which lists the available SQL files, though, as this would let you stay "portable" between the development and deployment environments.


That's a good suggestion. If I have time I'll look into it further. For now, my method works at least for the tests in the development environment. I haven't gotten to testing it in a simulated deployment environment yet. I guess we'll see what happens then.

Thanks for your help and suggestions!

Layne
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
 
subject: Class.getResourceAsStream() is returning null