3

So i am getting back into writing Java after 4 years so please forgive any "rookie" mistakes.

I need to have a properties file where i can store some simple data for my application. The app data itself won't reside here but i will be storing info such as the file path to the last used data store, other settings, etc.

I managed to connect to the properties file which exists inside the same package as the class file attempting to connect to it and i can read the file but i am having trouble writing back to the file. I am pretty sure that my code works (at least it's not throwing any errors) but the change isn't reflected in the file itself after the app is run in Netbeans.

enter image description here

In the above image you can see the mainProperties.properties file in question and the class attempting to call it (prefManagement.java). So with that in mind here is my code to load the file:

Properties mainFile = new Properties();
try {

    mainFile.load(prefManagement.class.getClass().getResourceAsStream("/numberAdditionUI/mainProperties.properties"));


} catch (IOException a) {

    System.out.println("Couldn't find/load file!");

}

This works and i can check and confirm the one existing key (defaultXMLPath).

My code to add to this file is:

String confirmKey = "defaultXMLPath2";

String propKey = mainFile.getProperty(confirmKey);

if (propKey == null) {

    // Key is not present so enter the key into the properties file
    mainFile.setProperty(confirmKey, "testtest");


    try{

        FileOutputStream fos = new FileOutputStream("mainProperties.properties");
        mainFile.store(fos, "testtest3");
        fos.flush();

    }catch(FileNotFoundException e ){
        System.out.println("Couldn't find/load file3!");
    }catch(IOException b){
        System.out.println("Couldn't find/load file4!");
    }



} else {

    // Throw error saying key already exists
    System.out.println("Key " + confirmKey + " already exists.");

}

As i mentioned above, everything runs without any errors and i can play around with trying to add the existing key and it throws the expected error. But when trying to add a new key/value pair it doesn't show up in the properties file afterwords. Why?

3 Answers 3

3

You should not be trying to write to "files" that exist inside of the jar file. Actually, technically, jar files don't hold files but rather they hold "resources", and for practical purposes, they are read-only. If you need to read and write to a properties file, it should be outside of the jar.

4
  • Thanks for the quick response! So "best practice" wise, what's the best way to store "history" type items and settings so that the user doesn't have to re-connect all their data and preference files every time they start the application? So for instance, where SHOULD i store the file path to the main properties file? Hard coding it seems like it would lead to problems if the user's file path isn't set up in a "standard" manner
    – BenW301
    Commented Jul 14, 2014 at 1:53
  • @BenW301: Is your code to write out to the properties file creating a file outside of the jar file? It looks like it should be doing that. Commented Jul 14, 2014 at 2:12
  • 2
    @BenW301 There are a number of options available to you, check this out for a short explanation of some. Typically, you would want to store these settings in the user.home directory, the exact location would be depended on the platform, for example, under linux it might be {user.home}/.YouAppName/..., under Windows it might be {user.home}/AppData/Roaming/YouAppName/... Commented Jul 14, 2014 at 2:13
  • @Hovercraft it wasn't supposed to be, although after trying to implement 20+ code blocks i found online it's probably pretty messed up. In the end, my application is going to be storing data in XML files located somewhere on the users computer, I just want a way to store those file paths so the user doesn't have to enter them every time. So all that being said, this might not even be the best way.
    – BenW301
    Commented Jul 14, 2014 at 2:14
2

Your code writes to a local file mainProperties.properties the properties.

After you run your part of code, there you will find that a file mainProperties.properties has been created locally.

FileOutputStream fos = new FileOutputStream("mainProperties.properties");

Could order not to confuse the two files you specify the local file to another name. e.g. mainAppProp.properties .

  • Read the complete contents of the resource mainProperties.properties.
  • Write all the necessary properties to the local file mainAppProp.properties.

 FileOutputStream fos = new FileOutputStream("mainAppProp.properties");

switch if file exists to your local file , if not create the file mainAppProp.properties and write all properties to it.

  • Test if file mainAppProp.properties exists locally.
  • Read the properties into a new "probs" variable.
  • Use only this file from now on.

Under no circumstances you can write the properties back into the .jar file.

Test it like

    [...]
    if (propKey == null) {
    // Key is not present so enter the key into the properties file
    mainFile.setProperty(confirmKey, "testtest");


    [...]
    Reader reader = null;
    try
    {
    reader = new FileReader( "mainAppProp.properties" );
    Properties prop2 = new Properties();
    prop2.load( reader );
    prop2.list( System.out );
    }
    catch ( IOException e )
    {
    e.printStackTrace();
    }
    finally
    {
    if (reader != null) {
    reader.close(); 
    }
    }
    }
    [...]
   }

output : with prop2.list( System.out );

-- listing properties --
defaultXMLPath2=testtest

content of the file mainAppProp.properties

#testtest3
#Mon Jul 14 14:33:20 BRT 2014
defaultXMLPath2=testtest

2
  • thanks moskito-x, i think through all this i found out that preferences was what i was looking for and need to use. I appreciate the help though
    – BenW301
    Commented Jul 16, 2014 at 2:45
  • @BenW301 : I'm glad you found your way. :-) . You are welcome.
    – moskito-x
    Commented Jul 16, 2014 at 12:49
1

Challenge: Read the Property file location in jar file Read the Property file Write the variable as system variables

public static void loadJarCongFile(Class Utilclass )
    {
       try{         
             String path= Utilclass.getResource("").getPath();
             path=path.substring(6,path.length()-1);
             path=path.split("!")[0];
             System.out.println(path);
             JarFile jarFile = new JarFile(path);

               final Enumeration<JarEntry> entries = jarFile.entries();
               while (entries.hasMoreElements()) {
                   final JarEntry entry = entries.nextElement();
                   if (entry.getName().contains(".properties")) {
                       System.out.println("Jar File Property File: " + entry.getName());
                       JarEntry fileEntry = jarFile.getJarEntry(entry.getName());
                       InputStream input = jarFile.getInputStream(fileEntry);
                       setSystemvariable(input);      
                       InputStreamReader isr = new InputStreamReader(input); 
                       BufferedReader reader = new BufferedReader(isr);
                       String line;

                       while ((line = reader.readLine()) != null) {
                           System.out.println("Jar file"+line);
                       }
                       reader.close();
                   }
               }
       }
       catch (Exception e)
       {
          System.out.println("Jar file reading Error");
       }
    }
    public static void setSystemvariable(InputStream input)
    {
    Properties tmp1 = new Properties();
       try {
             tmp1.load(input);

       for (Object element : tmp1.keySet()) {
             System.setProperty(element.toString().trim(),
                           tmp1.getProperty(element.toString().trim()).trim());
             }      
       } catch (IOException e) {
             System.out.println("setSystemvariable method failure");
       }
    }

Not the answer you're looking for? Browse other questions tagged or ask your own question.