Mario
Mario

Reputation: 23

I cant write(and possibly read) file with objects when i export project to jar

I have developed a small app and i exported him, but i cant write files and possible read, but this i cant check it because i only read if the file exist when the app start.

The project folder is this:

Project folder.

-------->bin

-------->src(contain tienda/gui and tienda/funcionalidad)

-------->config(the file must save here)

...

I have a class that communicate the GUI with others class where i have a File declaration.

package tienda.funcionalidad;

import java.io.File;
import java.util.ArrayList;

import tienda.funcionalidad.excepciones.NombreNoValidoException;
import tienda.funcionalidad.excepciones.PrecioNoValidoException;
import tienda.funcionalidad.excepciones.ProductoYaExisteException;

public class GestionTienda {

    private static ArrayList<Product> products = new ArrayList<Product>();
    public static File file = new File("config\\data.obj");
    private static int idProducts = 1;

    public static void increaseIdProducts(){
        idProducts++;   
    }

    public static void setIdProducts(int idProductos) {
        GestionTienda.idProducts = idProductos;
    }

    public static int getIdProducts() {
        return idProducts;
    }

    public static void setProducts(ArrayList<Product> products){
        GestionTienda.products=products;
    }

    public static void addProduct(String name, double priceSerodys, double priceRamirez, double priceEntrada, double priceMercasur) throws ProductoYaExisteException, NombreNoValidoException, PrecioNoValidoException{
        if(products.contains(new Product(0, name)))
            throw new ProductoYaExisteException();
        products.add(new Product(idProducts,name, priceSerodys, priceRamirez, priceEntrada,priceMercasur));
        increaseIdProducts();
    }   

    public static ArrayList<Product> getProducts() {
        return products;
    }



}

And i have a class for read and write.

package tienda.funcionalidad;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;


public class Files {

    public static void write(ArrayList<Product> product ,
            File file) throws IOException {
        try(ObjectOutputStream salida = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)))) {
            salida.writeObject(product);
            salida.writeInt(GestionTienda.getIdProducts());
        } 
    }

    public static void read(File file) throws ClassNotFoundException, IOException {
        try(ObjectInputStream entrada= new ObjectInputStream(new BufferedInputStream(new FileInputStream(file)))) {         
            GestionTienda.setProducts((ArrayList<Product>) entrada.readObject());
            GestionTienda.setIdProducts(entrada.readInt());
        }
    }

}

When the main class start, if the file not exists, i create it.

private void loadFile() {
    try {
        if (GestionTienda.file.exists())
            Files.read(GestionTienda.file);
        else
            Files.write(GestionTienda.getProducts(), GestionTienda.file);
    } catch (ClassNotFoundException e) {
        JOptionPane.showMessageDialog(frame, "Error Load",
                "Error class", JOptionPane.ERROR_MESSAGE);
    } catch (IOException e) {
        JOptionPane.showMessageDialog(frame, "Error Load",
                "Error IO", JOptionPane.ERROR_MESSAGE);
    }
}

private void saveExit() {
    try {
        Files.write(GestionTienda.getProducts(), GestionTienda.file);
    } catch (IOException e) {
        JOptionPane.showMessageDialog(frame, "Error Load",
                "Error IO exit", JOptionPane.ERROR_MESSAGE);
    } finally {
        System.exit(0);
    }
}

In Eclipse, i can read and write, but I export the project to jar, and i create a setup with Inno Setup, the IOException has throwed when i start and exit the app. The final folder with Inno Setup is this:

appfolder

I suppose that problen can be tha path. I have read something about the method getClass().getResourceAsStream, but i dont know how use this because i cant understand the problem completely.

Can you help me?

Upvotes: 0

Views: 93

Answers (2)

Mario
Mario

Reputation: 23

Finally my problem is solved. When I created the folders where the config must be saved dont put the correct permissions. Sorry if you spent your time with me.

Upvotes: 1

paulsm4
paulsm4

Reputation: 121749

There are a couple of problems here:

  1. As you already know, File file = new File("config\\data.obj"); won't work if your config directory happens to be in a .jar file.

  2. Putting your configuration in a .jar file is acceptable.

    But you should consider a .jar "read-only". You shouldn't expect to be able to modify the configuration that's stored in your .jar.

  3. That leaves you two choices:

    a) You can deploy any configuration you expect to change separately from the .jar.

    b) Your app can check if the configuration file exists and, if not, read it from the .jar the first time it tries to access it (and read it from disk all subsequent times).

  4. In either case, you'll need to decide exactly where you want to store the on-disk configuration. For example, you might wish to keep it in the same directory as your .jar.

    You can determine where your .jar's file path like this:

final File f = new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().getURI().getPath());

  1. Look here for more info:

    Reading/Writing to Properties Files inside the jar file

    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.

Upvotes: 1

Related Questions