3

EDIT: getResourceAsStream() vs FileInputStream

Is the best explanation I have found. Personally after trying all the different subclasses of InputStream I feel the implementation of the InputStream returned by FileInputstream() and the one returned by getResourceAsStream() are subtly different in some way (causing an incompatibility with javax.xml.parsers.. )

I'll leave this open for a while just in case someone happens to have an answer, but I'm done. thanks for all the advice, suggestions and help. Time too move on to the next thing.


I've have a servlet which collects it's initialization data from an XML ini file, it opens it as an InputStream from the servlet session context like this

   HttpSession session = request.getSession(true);
   ServletContext ctx=session.getServletContext();
   InputStream myini = ctx.getResourceAsStream("/WEB-INF/myini.xml");

That works, but later on I'm writing JUnit tests and in the setup function, and I need to access this same ini. I don't have the servlet context in the test environment so I try to create an InputStream using

InputStream testing = new FileInputStream(String pathToFile);

and also

InputStream testing = new FileInputStream(File fileObj); 

The exception thrown from the XML parser (below)

I find it impossible to get an InputStream for my init file and am forced to use File.

I checked the javadoc's, moved the file location in case of security restrictions. Eventually added dual constructors to the classes needing the ini, to accept both File and InputStream to cater for unit testing (where I need the File ref)and runtime (where the InputStream is returned from the servlet session context) ...

But i'm perplexed/pretty frustrated so I have to ask

How come I can return a file object using "File", which can then be successfully parsed by the javax.xml.parsers (see function below)

File myini = new File("C:\\apache-tomcat-7.0.30\\myini\\myini.xml");

But I cannot do the same with this using "InputStream" ?

InputStream myini = new FileInputStream("C:\\apache-tomcat-7.0.30\\myini\\myini.xml");

Using the exactly the same String path (i.e. the file exists)

Respectively each gets passed to either

public xmlNode parse(InputStream is) throws xmlException {
        try {
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            document = dBuilder.parse(is);
            document.getDocumentElement().normalize();

            xmlNode node = new xmlNode(document.getDocumentElement());
            return node;
        } catch (ParserConfigurationException e) {
            throw new xmlException("Error in configuration of XML parser", e);
        } catch (SAXException e) {
            throw new xmlException("Error in parsing XML document", e);
        } catch (IOException e) {
            throw new xmlException("Error in reading InputStream", e);
        }
    }

Or

public xmlNode parse(File file) throws xmlException {
        try {
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            document = dBuilder.parse(file);
            document.getDocumentElement().normalize();

            xmlNode node = new xmlNode(document.getDocumentElement());
            return node;
        } catch (ParserConfigurationException e) {
            throw new xmlException("Error in configuration of XML parser", e);
        } catch (SAXException e) {
            throw new xmlException("Error in parsing XML document", e);
        } catch (IOException e) {
            throw new xmlException("Error in opening file", e);
        }
    }

This Exception gets thrown only when the InputStream method is called (after the appropriate initialization as above)

xml.utils.xmlException: Error in reading InputStream
    at xml.utils.xmlDocument.parse(xmlDocument.java:40)
    at com.jcando.util.XMLini.<init>(XMLini.java:49)

Is there a different way of defining the path as a string for the InputStream ? Is there a security block I'm unaware of?

If someone can explain what I am missing, or where I am being thick as a stump I'd appreciate it.

Community
  • 1
  • 1
Kickaha
  • 3,680
  • 6
  • 38
  • 57
  • What's the error? And what do you do with your file object after creating it? – André Stannek Jul 17 '13 at 16:08
  • what error you are getting with `new FileInputStream` ? – sanbhat Jul 17 '13 at 16:08
  • No Error, just an empty/closed FileInputStream – Kickaha Jul 17 '13 at 16:09
  • how are you making sure that its closed? – sanbhat Jul 17 '13 at 16:10
  • after I create the file object it gets passed to an xml parsing class to extract initialization parameters/database connection information – Kickaha Jul 17 '13 at 16:10
  • How is the path different? ,that smells like the right anwser – Kickaha Jul 17 '13 at 16:12
  • 2
    If `File` works for you, and I'm assuming *"works"* means that you could actually read data when using `File`, have you tried `FileInputStream(File file)`, instead of `FileInputStream(String name)`? – afsantos Jul 17 '13 at 16:21
  • @afsantos, yes that was one of the things I tried. I also moved the file location, from project root, onto a classpath, into a folder and used hard coded absolute String references as above – Kickaha Jul 17 '13 at 16:24
  • @sanbhat, I am using the debugger in eclipse to inspect it. – Kickaha Jul 17 '13 at 16:26
  • Can you add more code showing what you do with the `File` that works, and the `InputStream` that does not? As well as elaborating on what "works" and "does not work" means more specifically. – Trevor Freeman Jul 17 '13 at 17:33
  • 1
    @increment1, I have added the exception detail and the parsing functions which work, and don't work. – Kickaha Jul 17 '13 at 17:43
  • Just a small question: you are not running these two at the same time do you? – anvarik Jul 17 '13 at 17:59
  • Is that the only exception or is it wrapping any other exception? And this InputStream, it is handed off to the parse message in the same thread, not between threads at all? – Trevor Freeman Jul 17 '13 at 18:00
  • @increment1 its caused by an i/o Exception, thrown by the read method of FileInputStream, there is no threading. There are bytes available, I found a good answer which I'm adding to my question, it does not resolve my question but I think its as close as Ill get, see above. – Kickaha Jul 17 '13 at 18:46
  • It would probably help if you posted the wrapped exception as well. – Dolda2000 Jul 17 '13 at 22:44
  • @Dolda2000, its an i/o Exception, thrown by the read method of FileInputStream. Caused by: java.io.IOException: Read error at java.io.FileInputStream.read(Native Method) – Kickaha Jul 17 '13 at 23:30
  • Yes, I figured as much, but the complete stacktrace and message just might be useful. ;) – Dolda2000 Jul 17 '13 at 23:36

3 Answers3

2

You can always write File f = new File("anyName"): it will never throw an exception even if the file does not exist.

Yet, writing InputStream myini = new FileInputStream("anyName") will throw a FileNotFoundException exception if the file does not exist as you can see in the documentation.

Jean Logeart
  • 52,687
  • 11
  • 83
  • 118
  • The file exists, File works, InputStream does not. your not really answering my question I'm not trying to raise an exception. – Kickaha Jul 17 '13 at 16:16
  • Check that your file actually exists for the program using ``myini.exists();`` – Jean Logeart Jul 18 '13 at 07:26
  • the file exists (as shown by the absolute path code working when using File, and no Exception being thrown by File and no FileInputStream), sorry but you are again not addressing the issue. No worries it's not an easy issue and as I said in my update above I've moved on. I have no idea why your answer was up-voted as it is completely off the mark. – Kickaha Jul 22 '13 at 08:09
1

I suspect that you may have a character encoding error or an error related to resolving relative urls within your document (although I am not sure if that would cause an exception).

I think that you may want to look at trying something like:

InputSource source = new InputSource(is);
source.setEncoding(... your character encoding ...);
source.setSystemId(systemId);
dBuilder.parse(inputSource);

Where systemId is determined as file.toURI().toASCIIString().

Trevor Freeman
  • 7,112
  • 2
  • 21
  • 40
0

getResourceAsStream() vs FileInputStream

Is the best explanation I have found. Personally after trying all the different subclasses of InputStream I feel the implementation of the InputStream returned by FileInputstream() and the one returned by getResourceAsStream() are subtly different in some way (causing an incompatibility with javax.xml.parsers.. )

Community
  • 1
  • 1
Kickaha
  • 3,680
  • 6
  • 38
  • 57