2

Where can I put XML file to enable the program to access it even when I generate the jar file for it?

When I put the XML file in the project file the program successfully run as the following code:

public class one {

    public final static void main(String[] args) throws Exception {

      FileInputStream file = new java.io.FileInputStream("document.xml");//i put document.xml in project file
      javax.xml.parsers.DocumentBuilderFactory dbf = javax.xml.parsers.DocumentBuilderFactory.newInstance();
      dbf.setCoalescing(true);
      javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder();
      org.w3c.dom.Document doc = db.parse(file);

      one obj = new one ();
      obj.changeValue(doc, "192837465", "192837465");
      obj.save("document.xml",doc);
    }

    public void changeValue(org.w3c.dom.Document doc, String oldValue, String NewValue) throws Exception{
      org.w3c.dom.Element root = doc.getDocumentElement();
      org.w3c.dom.NodeList childNodes = root.getElementsByTagName("Employee");
      for (int i = 0; i < childNodes.getLength(); i++) {
        org.w3c.dom.NodeList subChildNodes = childNodes.item(i).getChildNodes();
        for (int j = 0; j < subChildNodes.getLength(); j++) {
          try {
             if (subChildNodes.item(j).getTextContent().equals(oldValue)) {
                subChildNodes.item(j).setTextContent(NewValue);
             }
          } catch (Exception e) {
              e.printStackTrace();
          }
        }
      }
    }

    public void save(String url ,org.w3c.dom.Document doc) throws Exception {

        javax.xml.transform.TransformerFactory factory1 = javax.xml.transform.TransformerFactory.newInstance();
        javax.xml.transform.Transformer transformer = factory1.newTransformer();
        transformer.setOutputProperty(javax.xml.transform.OutputKeys.INDENT, "yes");
        java.io.StringWriter writer = new java.io.StringWriter();
        javax.xml.transform.stream.StreamResult result = new javax.xml.transform.stream.StreamResult(writer);
        javax.xml.transform.dom.DOMSource source = new javax.xml.transform.dom.DOMSource(doc);
        transformer.transform(source, result);
        String s = writer.toString();
        System.out.println(s);

        java.io.FileWriter fileWriter = new java.io.FileWriter(url);
        java.io.BufferedWriter bufferedWriter = new java.io.BufferedWriter(fileWriter);

        bufferedWriter.write(s);

        bufferedWriter.flush();
        bufferedWriter.close();
    }
}

but when I make the program in jar file using eclipse and run the file from command prompt using this command:

java -jar xml.jar

it gives me this exception:

Exception in thread "main" java.io.FileNotFoundException: document.xml (The system cannot find the file specified)
        at java.io.FileInputStream.open(Native Method)
        at java.io.FileInputStream.<init>(Unknown Source)
        at java.io.FileInputStream.<init>(Unknown Source)
        at one.main(one.java:13)

Why this error and how to correct it?

Wojciech Wirzbicki
  • 3,887
  • 6
  • 36
  • 59
islam darwish
  • 21
  • 1
  • 2

3 Answers3

2

Since you are saving the file back after chaging its content it is more likely that you do not pack it inside the xml.jar but you leave it as separate file on the filesystem. to access the file using FileInputStream file = new java.io.FileInputStream("document.xml"); it musst be in the same working directory for the command java -jar xml.jar.

this will work

- mydir\
    - xml.jar
    - document.xml

this will not

- mydir\
    - xml.jar
    - subdir\
       - document.xml

to avoid all this trouble i would suggest you not to hard code the filename in your java class but to pass it as an argument to your main class

java -jar xml.jar document.xml

or

java -jar xml.jar C:\somedir\somesubdir\document.xml

and access it as follow:

FileInputStream file = new java.io.FileInputStream(args[0]);

EDIT

If you want to pack the xml inside your jar file then the reading is easily done using getResourceAsStream(String) - as mentioned in another post - and the qualified name of the ressource inside the jar as follow:

InputStream is = getResourceAsStream("com/my/pack/age/document.xml");

Writing the file back is possible but complicated and discouraged as it is buggy read more here and here

Community
  • 1
  • 1
A4L
  • 17,353
  • 6
  • 49
  • 70
  • The two ways successfully work but xml file must be in the same directory for the jar file but i want a way to put the xml file inside the jar file. is there a way to make this? thanks in advance – islam darwish Feb 26 '13 at 13:55
  • Ok when i use InputStream is = getResourceAsStream("com/my/pack/age/document.xml"); where i put the document.xml file – islam darwish Feb 26 '13 at 18:47
  • sorry didn't check SO earlier... you have to put `document.xml` in the package `com.my.pack.age` witch means on the filesystem in the directory `com/my/pack/age` having `com` directly in your source folder for example `C:\projects\MyProject\src\com\my\pack\age\document.xml` – A4L Feb 27 '13 at 11:10
0

Use ClassLoader#getResourceAsStream instead of FileInputStream . You can find similar problem in getResourceAsStream() vs FileInputStream

Community
  • 1
  • 1
Arsen Alexanyan
  • 3,061
  • 5
  • 25
  • 45
0

You Must access the file in a relative way
for example try that

InputStream file = Thread.currentThread().getContextClassLoader()
                    .getResourceAsStream("document.xml");

Instead of

String fileLocation = "src/document.xml";
File xmlFile = new File(fileLocation);
FileInputStream file = new java.io.FileInputStream(xmlFile); 

Then
Your application will access the file in both ways

  1. Delopment Environment (From Eclipse) and
  2. Runnable Environment (From Jar)
Ahmed Nabil
  • 17,392
  • 11
  • 61
  • 88