Spring ClassPathResource - cannot be opened because it does not exist

bscott picture bscott · May 12, 2016 · Viewed 24.7k times · Source

UPDATE: I'll still keep Artem Bilan's answer marked as correct, but I still felt I needed to point this out for any future readers. It seems I was misunderstanding the concept of the 'default value' for the @Value annotation. The functionality I was hoping to achieve by using

@Value("${someProp:defaultFilePath}")
private Resource resourcefilePath;

was that, should the file path someProp defined in application.properties throw an exception (i.e. file not found), it would then attempt to use the defaultFilePath (i.e. the one above). What defining a default value actually does is that, if the property itself (someProp) does not exist (not defined or commented out) in the application.properties file, it then attempts to use the default value instead.


I'm using Spring Integration Sftp for SSH file transfer. Using Spring Boot so no xml files. Before configuring the DefaultSftpSessionFactory object, I define a resource which contains a .txt file that has the private key required for the sFtp authentication.

Previously, I used FileSystemResource like this:

Resource resource = new FileSystemResource("C:/absolute/path/to/my/private/key/privateKey.txt");

This worked just fine. However, this application will eventually be put in a cloud environment, which means absolute paths like that won't work anymore. I'm trying to instead use ClassPathResource but it's not working no matter what I try. So far I've tried the following:

Resource resource = new ClassPathResource("privateKey.txt");
Resource resource = new ClassPathResource("privateKey.txt", SomeClassInClassPath.class);
Resource resource = new ClassPathResource("com/my/package/name/privateKey.txt");

My directory structure looks something like this:

ProjectFolder -> src -> main -> java -> com -> my -> package -> name -> various java classes
                                                                        privateKey.txt
                             -> resources -> etc...

There's more but this is a simplified version of it. Can anyone help figure out how I can get it to recognize the path to my .txt? I keep getting java.io.FileNotFoundException: class path resource [resource] cannot be opened because it does not exist no matter what I try.

EDIT: WAR structure:

ProjectFolder -> META-INF -> maven -> etc..
              -> org -> springframework -> boot -> etc..
              -> WEB-INF -> classes -> com
                                    -> public
                                    -> application.properties
                                    -> privateKey.txt

Answer

Artem Bilan picture Artem Bilan · May 13, 2016

You show src -> main -> etc., but that doesn't matter for runtime.

If you really are going to have that file in the final application (jar? war?), be sure that you pack that file really as a part of the final application.

And share that structure here.

With Spring Java & Annotation Configuration you don't need to worry about ClassPathResource object. There is just enough to declare it like this in the appropriate @Configuration:

@Value("com/my/package/name/privateKey.txt")
private Resource privateKey;