0

New to Java. I am building a Java HTTP server (no special libraries allowed). There are certain files I need to serve (templates is what I call them) and I was serving them up using this piece of code:

this.getClass().getResourceAsStream("/http/templates/404.html")

And including them in my .jar. This was working. (I realize I was reading them as an input stream.)

Now I want to store all of my files (as File type) for templates, regular files, redirects in a hashmap that looks like this: url -> file. The I have a Response class that serves up the files.

This works for everything except my templates. If I try to insert the getResource code in the hashmap, I get an error in my Response class.

This is my code that I am using to build my hashmap:

new File(this.getClass().getResource("/http/templates/404.html").getFile())

This is the error I'm getting:

Exception in thread "main" java.io.FileNotFoundException: file:/Users/Kelly/Desktop/Java_HTTP_Server/build/jar/server.jar!/http/templates/404.html (No such file or directory)

I ran this command and can see the templates in my jar:

jar tf server.jar

Where is my thinking going wrong? I think I'm missing a piece to the puzzle.

UPDATE: Here's a slice of what I get when I run the last command above...so I think I have the path to the file correctly?

http/server/serverSocket/SystemServerSocket.class
http/server/serverSocket/WebServerSocket.class
http/server/ServerTest.class
http/templates/
http/templates/404.html
http/templates/file_directory.html
http/templates/form.html
Kelly
  • 619
  • 8
  • 18
  • 1
    Try using getPath() instead of getFile(). Also, make sure that is a valid path. – Josh M Aug 14 '13 at 15:04
  • Thanks, Josh! Didn't work though. I get the same exact error. Also, I updated my question to show what is in my server.jar. – Kelly Aug 14 '13 at 15:08
  • 1
    The message text from the exception should give you a clue: it is some reference into a jar file, which might be opened as `Stream`, but is not a proper `File` location. Why do you need a `File` object here? – Gyro Gearless Aug 14 '13 at 15:13
  • Thanks for the help, Gyro. All of my other values (for each key/value pair) in the hashmap are files. So seems like it would take some recoding for the templates to not be files and the rest to be files? – Kelly Aug 14 '13 at 15:18

1 Answers1

1

The FileNotFoundException error you are getting is not from this line:

new File(this.getClass().getResource("/http/templates/404.html").getFile())

It appears that after you are storing these File objects in hash map, you are trying to read the file (or serve the file by reading using FileInputStream or related APIs). It would have been more useful if you had given the stack trace and the code which is actually throwing this exception.

But the point is that files present within the JAR files are not the same as files on disk. In particular, a File object represents an abstract path name on disk and all standard libraries using File object assume that it is accessible. So /a/path/like/this is a valid abstract path name, but file:/Users/Kelly/Desktop/Java_HTTP_Server/build/jar/server.jar!/http/templates/404.html is not. This is exactly what you get when you call getResource("/http/templates/404.html").getFile(). It just returns a string representing something that doesn't exist as a file on disk.

There are two ways you can serve resources from class path directly:

  • Directly return the stream as a response to the request. this.getClass().getResourceAsStream() will return you the InputStream object which you can then return to the caller. This will require you to store an InputStream object in your hash map instead of a file. You can have two hash maps one for files from class path and one for files on disk.
  • Extract all the templates (possibly on first access) to a temporary location say /tmp and then store the File object representing the newly extracted file.
Venkat
  • 462
  • 1
  • 5
  • 10
  • Sorry for the delay. You were totally right about this. To get around it, I simply grabbed the resource (using an inputstream) and made a temp file with it. Thanks for the help! – Kelly Aug 22 '13 at 01:18