0

I want to save data with jackson to existing file (update it) but it won't work when I run my project from jar.

I need to use json as "database" (I know it's pretty stupid but that's for a school project) and to do it I load and save all the data when I do any of CRUD operations. It's working fine when I run it with IDE but when I tried as a jar it had a problem with reading file from ClassPathResource.

So I have this method to save changes to file:

private List<Item> items;
private ObjectMapper mapper;
private ObjectWriter writer;

public void saveData() {
        mapper = new ObjectMapper();
        writer = mapper.writer(new DefaultPrettyPrinter());
        try {
            writer.writeValue(new ClassPathResource("items.json").getFile(), items);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

And it works just fine when i run this through IntelliJ but it won't work when I run it as a jar. I found a solution to loading the data by using InputStream from this question and method looks like this:

public void loadData() {
        mapper = new ObjectMapper();
        try {
            ClassPathResource classPathResource = new ClassPathResource("items.json");

            InputStream inputStream = classPathResource.getInputStream();
            File tempFile = File.createTempFile("test", ".json");

                FileUtils.copyInputStreamToFile(inputStream, tempFile);

            System.out.println(tempFile);
            System.out.println(ItemDao.class.getProtectionDomain().getCodeSource().getLocation().getPath().toString());
            items = mapper.readValue(tempFile, new TypeReference<List<Item>>() {
            });
        } catch (IOException e) {
            items = null;
            e.printStackTrace();
        }
    }

But I still have no idea how to actually save changes. I was thinking about making use of FileOutputStreambut I achieved nothing.

So I want to get this working in jar file and be able to save changes to the same file, thanks for help in advance!

Filip Perz
  • 155
  • 1
  • 1
  • 6
  • where did you keep items.json file? is it in resource directory (inside project) or somewhere on the disk? – Naveen May 20 '19 at 22:26
  • @Naveen i keep it in resource directory from standard spring boot template – Filip Perz May 20 '19 at 22:27
  • when you want to do read/write operations, it is better keep the file outside of the project. when running the jar, pass file name with path as an argument. like -DfileName=/Users/chappa/Documents/items.json etc. This way, you have absolute path, and you can perform read/write operations on it – Naveen May 20 '19 at 22:31
  • So then I can, for example, have folder with JSON and jar inside and add relative path to edit it? – Filip Perz May 20 '19 at 22:35
  • yes thats what I meant to say – Naveen May 20 '19 at 22:43

1 Answers1

1

when you want to do read/write operations, it is better keep the file outside of the project. when running the jar, pass file name with path as an argument. like -DfileName=/Users/chappa/Documents/items.json etc. This way, you have absolute path, and you can perform read/write operations on it

if you are using java 1.7 or above, use below approach to write data. To read data, you can use jackson api to load the json file as is.

Path wipPath = Paths.get("/Users/chappa/Documents/items.json");
try (BufferedWriter writer = Files.newBufferedWriter(wipPath)) {
            for (String record : nosRecords) {
                writer.write(record);
            }
        }

Just in case if you want to read json using IO streams, you can use below code

        Path wipPath = Paths.get("/Users/chappa/Documents/items.json");
        try (BufferedReader reader = Files.newBufferedReader(wipPath)) {
            String line=null;
            while((line = reader.readLine()) != null) {
                    System.out.println(line);
            }
        }
Naveen
  • 907
  • 2
  • 15
  • 25