0

I'm using Vaadin 14 with uploader. When I'm going to save files to /META-INF/resources/audio/MyFolderName/MyFileName.mp3, then I got this exception message:

java.nio.file.AccessDeniedException: /META-INF

Here is my minimal code:

// Write
String audioPath = "/META-INF/resources/audio/" + seletedLanguage.getValue() + "/" + fileName;
Path path = Paths.get(audioPath);
Files.createDirectories(path.getParent()); // <--- Here I got the error
FileOutputStream fos = new FileOutputStream(audioPath);
fos.write(buffer.getInputStream(fileName).readAllBytes());
fos.close();
// Read
String audioPath = "/META-INF/resources/audio/" + seletedLanguage.getValue() + "/" +  foreignSentence + ".mp3";
AbstractStreamResource resource = new StreamResource(foreignSentence, () -> getClass().getResourceAsStream(audioPath));

Where the buffer is from the MultiFileMemoryBuffer class.

Can someone tell me if it's possible to have full access to META-INF folder in Vaadin 14?

My goal is to download files to a folder, where I can use the files later inside my web application.

I'm trying to achieve so I can read and write files from the local drive, e.g projet-folder or something that don't affects the JAR file after I have packed it.

STaefi
  • 4,297
  • 1
  • 25
  • 43
euraad
  • 2,467
  • 5
  • 30
  • 51
  • 4
    It looks like you have an [X-Y problem](https://xyproblem.info/). Please explain what you are actually trying to achieve. `META-INF` is a folder inside JAR files for metadata of that JAR file, and downloaded files do not belong in a `META-INF` folder (nor do resources for that matter). And given the path you use, you are trying to save to `/META-INF` on your local **filesystem**, and your application doesn't have access to `/META-INF` (because it doesn't exist, or your user has no rights to create a folder in `/`). – Mark Rotteveel Nov 14 '20 at 17:51
  • @MarkRotteveel I have explain what I'm trying to achive how. I'm trying to read and write files with Vaadin/Spring Boot. But I have no right to write to `META-INF` so I need to write to another folder. But then, I have problems with reading because of `AbstractStreamResource resource = new StreamResource(foreignSentence, () -> getClass().getResourceAsStream(audioPath));` only allows me to read from `META-INF` folder. – euraad Nov 14 '20 at 17:54
  • 2
    The solution seems pretty obvious: 1) write the file to somewhere on your local filesystem that you have the proper permissions to write to, and 2) change the way you're reading the file after you've written it so that the code works when reading from a specified path on your filesystem. It seems that you are supplying a function that opens the file for reading, `() -> getClass().getResourceAsStream(audioPath)`. Just change that code to read from a filesystem location instead of from the classpath. – CryptoFool Nov 14 '20 at 18:02
  • @Steve Hi! I can write in the project folder. No problem there. But I can't read to the project folder. That's an issue. – euraad Nov 14 '20 at 18:14
  • @Steve The `StreamResource(foreignSentence, () -> getClass().getResourceAsStream(audioPath));` will give `null` if I write to `MyFolder/resources/audio..../myFile.mp3` I don't know why. – euraad Nov 14 '20 at 18:15
  • 2
    `getClass().getResourceAsStream` returns an `InputStream` by finding a file using the current class path. You can replace this call with anything else that returns an `InputStream`. In your case, you don't want to find your file via the class path. Rather, since you already know where the file is, you want to make a call that opens that file given its location. `FileInputStream ` gives you that. So you want something like `() -> new FileInputStream(audioPath)` instead of `() -> getClass().getResourceAsStream(audioPath)`. – CryptoFool Nov 14 '20 at 19:23
  • If you cannot read project dir, how do you run your appp??..... – Antoniossss Nov 14 '20 at 19:27
  • 2
    ...and again, you don't want to write to `/META-INF/...`. You want to pick a location on your system that makes sense and that you have write access to. This is usually a place in your home directory. So here, maybe you want something like `String audioPath = System.getProperty("user.home") + /resources/audio/" + seletedLanguage.getValue() + "/" + fileName;` - Am I on track with my comments in terms of what you want to do, or am I totally missing the boat here? – CryptoFool Nov 14 '20 at 19:36
  • @Steve Do you run Vaadin 14? – euraad Nov 14 '20 at 19:41
  • 2
    No. Never heard of it. I'm just responding to a general issue or two I see in your code. The driving force here is that I believe that you can't or shouldn't write to any path that starts with '/META-INF/', regardless of what library or framework you're using. '/META-INF/' is usually a directory in your app's Jar file. It's meant to be read from but not written to. See: https://stackoverflow.com/questions/70216/whats-the-purpose-of-meta-inf. – CryptoFool Nov 14 '20 at 19:47
  • @Steve `AbstractStreamResource resource = new StreamResource(foreignSentence, () -> getClass().getResourceAsStream(audioPath));` will give null, unless if it's not `META-INF` math. – euraad Nov 14 '20 at 19:50
  • 2
    Is there some reason that you have to use this particular line of code as is? As I've already said, you don't want to use `getClass().getResourceAsStream(audioPath)`. That's, among other things, for reading files out of your jar file that were there before your app launched. It isn't a way to open a file you've just written to your disk. – CryptoFool Nov 14 '20 at 19:52
  • @Steve What function should I use then? – euraad Nov 14 '20 at 20:22
  • 1
    I already told you: `new FileInputStream(audioPath)` – CryptoFool Nov 14 '20 at 20:25
  • You should use the same type of API both for writing and reading. If you write using `Files` (or `File`), then you should also read using `Files` (or `File`). You cannot mix file system locations (e.g. `Files`) and classpath locations (e.g. `Class.getResourceAsStream`). See https://stackoverflow.com/a/31255701/2376954 for ideas on how to choose the location. – Leif Åstrand Nov 16 '20 at 08:44
  • @LeifÅstrand It's working with the suggestion that Steve gave me. – euraad Nov 16 '20 at 09:26

0 Answers0