0

I am trying to use file, when running application as JAR. When I run application through Intelij, everything is fine. However when I try to run it via jar, I cannot access the file. I tried to read few topics containing similar matter, but non of them help (like Reading a resource file from within jar or How do I read a resource file from a Java jar file? ) Here is my target tree, and resources:enter image description here enter image description here

When I use

String path = String
        .join("", "classpath:static\assets\config\", fileName);
File file = ResourceUtils.getFile(path); 
InputStream targetStream = new FileInputStream(file)

During intelij run, everything works.

In the case of jar, I tried:

String path = String
        .join("", "static\assets\config\", fileName).replace("\\","/")).toExternalForm();
String path2 = String
        .join("", "static\assets\config\", fileName).replace("\\","/")).getFile();
String path3 = String
        .join("", "static\assets\config\", fileName).replace("\\","/")).getPath();

and many other. They result in correct path, for example:

  • file:/D:/Projects/myProject/target/classes/static/assets/config/fileName (in case of toExternalForm)

  • /D:/Projects/myProject/target/classes/static/assets/config/fileName (in case of getFile)

    However all of them results in null InputStream, when I try:

 InputStream in = getClass().getResourceAsStream(everyPath);

I get an error: java.io.FileNotFoundException: D:\Projects\myProject\target\project-app-1.0.jar\BOOT-INF\classes\static\assets\config\fileName (The system cannot find the path specified) When the path in the project-app-1.0.jar when I open it by 7zip is exactly: D:\Projects\myProject\target\project-app-1.0.jar\BOOT-INF\classes\static\assets\config\fileName

This is how my resource handler looks like:

  private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
      "classpath:/resources/", "classpath:/static/"};
  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/**").addResourceLocations(
        CLASSPATH_RESOURCE_LOCATIONS);
  }
Community
  • 1
  • 1
Thamiar
  • 600
  • 7
  • 22
  • Resources in a Jar are no longer files, so using 'file like' paths or URLs based on files will not work. Tips for the `String` used in `getResource`: 1) Always use `/` rather than back slash. 2) Prefix the string with `/` to make it start relative to the root of the class-path rather than the package of the calling class. 3) Proceed with the package at the root of the class-path. .. **So** I would expect the `String` to `getResource` would start `"/static/assets/config/(.. etc ..)"`. As an aside, apparently the rules for `getResource` and `getResourceAsStream` are slightly different, .. – Andrew Thompson Apr 04 '20 at 06:57
  • .. so I (know &) always use the former to get an `URL`. A stream can be easily obtained once there is a `URL`. – Andrew Thompson Apr 04 '20 at 06:57

1 Answers1

0

forget about "files" when you want to use something inside your jar, its just a simple "Resource" that your have to use with getResource.

If you use a standard packaging system, everything inside "resources" folder are put at the root of your JAR, so if you want to read your "foo.txt" file inside "static\assets\config\" folder you have to do use method:

InputStream in = ClassLoader.getSystemResourceAsStream("static/assets/config/foo.txt");