0

Please note that I am very new to Ubuntu server and linux in general.

I have a java script that downloads an xml file from a url and imports it into my database. It works fine on my local machine, but after uploading it to my vps (which uses ubuntu 18.04 and Tomcat), I get the following error when running the script:

java.nio.file.AccessDeniedException: f1e4485c8f9fed7e4af0672c5f8bd0d0.xml
    at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:90) ~[na:na]
    at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111) ~[na:na]
    at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:116) ~[na:na]
    at java.base/sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:219) ~[na:na]
    at java.base/java.nio.file.spi.FileSystemProvider.newOutputStream(FileSystemProvider.java:478) ~[na:na]
    at java.base/java.nio.file.Files.newOutputStream(Files.java:219) ~[na:na]
    at java.base/java.nio.file.Files.copy(Files.java:3066) ~[na:na]
    at com.keuzestress.api.keuzestressapi.resource.xml.CoolblueImport.doImport(CoolblueImport.java:53) ~[classes/:0.0.1-SNAPSHOT]
    at com.keuzestress.api.keuzestressapi.resource.xml.CoolblueImport$$FastClassBySpringCGLIB$$de9a1a6.invoke(<generated>) ~[classes/:0.0.1-SNAPSHOT]
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
...

It is clear to me that there is some kind of permissions issue. What I don't know is where the file is saved. I tried checking the tomcat subfolders but I couldn't find out what folder I should give the appropriate permissions.

The java import script:

@Component
public class CoolblueImport implements importInterface{
    public List<CoolblueProduct> coolblueProductList = new ArrayList<>();
    public List<Product> productList = new ArrayList<>();
    String url = "http://feeds.performancehorizon.com/.../f1e4485c8f9fed7e4af0672c5f8bd0d0.xml";

    Logger logger = LoggerFactory.getLogger(CoolblueImport.class);

    @Autowired
    ProductRepository productRepository;

    @Transactional
    public List<Product> doImport() throws ParserConfigurationException, IOException, SAXException {
        coolblueProductList.clear();

        InputStream in = new URL(url).openStream();
        Files.copy(in, Paths.get("f1e4485c8f9fed7e4af0672c5f8bd0d0.xml"), StandardCopyOption.REPLACE_EXISTING);

        File file = new File("f1e4485c8f9fed7e4af0672c5f8bd0d0.xml");
...

Thanks in advance! Any help is welcome :)

  • 1
    See also [How to allow Tomcat war app to write in folder](https://stackoverflow.com/a/56835997/13447) for information to read/write arbitrary folders, not just `java.io.tmpdir`, in a Debian installation – Olaf Kock Jan 06 '20 at 08:38

1 Answers1

1

Ultimately your Tomcat process doesn't have the correct permission to write your .xml file to the current working directory in which Tomcat is running. When you try to run:

Files.copy(in, Paths.get("f1e4485c8f9fed7e4af0672c5f8bd0d0.xml"), StandardCopyOption.REPLACE_EXISTING); 

the Tomcat process isn't allowed to create the file.

One possibility is to create the file in a temporary directory. And one way to do that would be to change the code to be:

Files.copy(in,
    Paths.get(System.getProperty("java.io.tmpdir") + 
    System.getProperty("file.separator") + 
    "f1e4485c8f9fed7e4af0672c5f8bd0d0.xml"), StandardCopyOption.REPLACE_EXISTING);

This looks big but what it is doing is creating a file path, in an O/S independent way, to the Java temporary directory. This is a directory that virtually all processes should be able to write to in both Windows and Unix. There are other ways to do the same thing such as Files.createTempFile() that would work in a conceptually similar way.

Remember that if you use the file name again such as you have in the next line of code that you'll need to use the same path. You don't state what it is you want to do with the output file but please realize that the temporary directory is just that. In Unix a machine reboot clears it all out so if you need to keep the file you'll want a more permanent place.

user207421
  • 305,947
  • 44
  • 307
  • 483
stdunbar
  • 16,263
  • 11
  • 31
  • 53