Reading a resource file from within jar










156















I would like to read a resource from within my jar like so:



File file;
file = new File(getClass().getResource("/file.txt").toURI());
BufferredReader reader = new BufferedReader(new FileReader(file));

//Read the file


and it works fine when running it in Eclipse, but if I export it to a jar the run it there is an IllegalArgumentException:



Exception in thread "Thread-2"
java.lang.IllegalArgumentException: URI is not hierarchical


and I really don't know why but with some testing I found if I change



file = new File(getClass().getResource("/file.txt").toURI());


to



file = new File(getClass().getResource("/folder/file.txt").toURI());


then it works the opposite (it works in jar but not eclipse).



I'm using Eclipse and the folder with my file is in a class folder.










share|improve this question
























  • If you want to read files from a directory in jar with any numbers for files, see Stackoverflow-Link

    – Michael Hegner
    Oct 2 '16 at 16:01











  • I'm not sure that the original question was involving Spring. The link in the previous comment refers to a Spring specific answer from a different question. I believe getResourceAsStream is still a simpler and more portable solution to the problem.

    – Drew MacInnis
    Dec 15 '16 at 3:56















156















I would like to read a resource from within my jar like so:



File file;
file = new File(getClass().getResource("/file.txt").toURI());
BufferredReader reader = new BufferedReader(new FileReader(file));

//Read the file


and it works fine when running it in Eclipse, but if I export it to a jar the run it there is an IllegalArgumentException:



Exception in thread "Thread-2"
java.lang.IllegalArgumentException: URI is not hierarchical


and I really don't know why but with some testing I found if I change



file = new File(getClass().getResource("/file.txt").toURI());


to



file = new File(getClass().getResource("/folder/file.txt").toURI());


then it works the opposite (it works in jar but not eclipse).



I'm using Eclipse and the folder with my file is in a class folder.










share|improve this question
























  • If you want to read files from a directory in jar with any numbers for files, see Stackoverflow-Link

    – Michael Hegner
    Oct 2 '16 at 16:01











  • I'm not sure that the original question was involving Spring. The link in the previous comment refers to a Spring specific answer from a different question. I believe getResourceAsStream is still a simpler and more portable solution to the problem.

    – Drew MacInnis
    Dec 15 '16 at 3:56













156












156








156


63






I would like to read a resource from within my jar like so:



File file;
file = new File(getClass().getResource("/file.txt").toURI());
BufferredReader reader = new BufferedReader(new FileReader(file));

//Read the file


and it works fine when running it in Eclipse, but if I export it to a jar the run it there is an IllegalArgumentException:



Exception in thread "Thread-2"
java.lang.IllegalArgumentException: URI is not hierarchical


and I really don't know why but with some testing I found if I change



file = new File(getClass().getResource("/file.txt").toURI());


to



file = new File(getClass().getResource("/folder/file.txt").toURI());


then it works the opposite (it works in jar but not eclipse).



I'm using Eclipse and the folder with my file is in a class folder.










share|improve this question
















I would like to read a resource from within my jar like so:



File file;
file = new File(getClass().getResource("/file.txt").toURI());
BufferredReader reader = new BufferedReader(new FileReader(file));

//Read the file


and it works fine when running it in Eclipse, but if I export it to a jar the run it there is an IllegalArgumentException:



Exception in thread "Thread-2"
java.lang.IllegalArgumentException: URI is not hierarchical


and I really don't know why but with some testing I found if I change



file = new File(getClass().getResource("/file.txt").toURI());


to



file = new File(getClass().getResource("/folder/file.txt").toURI());


then it works the opposite (it works in jar but not eclipse).



I'm using Eclipse and the folder with my file is in a class folder.







java file jar resources embedded-resource






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Oct 7 '18 at 13:47









Drew MacInnis

4,95111315




4,95111315










asked Dec 5 '13 at 0:48









PrinceCJCPrinceCJC

783265




783265












  • If you want to read files from a directory in jar with any numbers for files, see Stackoverflow-Link

    – Michael Hegner
    Oct 2 '16 at 16:01











  • I'm not sure that the original question was involving Spring. The link in the previous comment refers to a Spring specific answer from a different question. I believe getResourceAsStream is still a simpler and more portable solution to the problem.

    – Drew MacInnis
    Dec 15 '16 at 3:56

















  • If you want to read files from a directory in jar with any numbers for files, see Stackoverflow-Link

    – Michael Hegner
    Oct 2 '16 at 16:01











  • I'm not sure that the original question was involving Spring. The link in the previous comment refers to a Spring specific answer from a different question. I believe getResourceAsStream is still a simpler and more portable solution to the problem.

    – Drew MacInnis
    Dec 15 '16 at 3:56
















If you want to read files from a directory in jar with any numbers for files, see Stackoverflow-Link

– Michael Hegner
Oct 2 '16 at 16:01





If you want to read files from a directory in jar with any numbers for files, see Stackoverflow-Link

– Michael Hegner
Oct 2 '16 at 16:01













I'm not sure that the original question was involving Spring. The link in the previous comment refers to a Spring specific answer from a different question. I believe getResourceAsStream is still a simpler and more portable solution to the problem.

– Drew MacInnis
Dec 15 '16 at 3:56





I'm not sure that the original question was involving Spring. The link in the previous comment refers to a Spring specific answer from a different question. I believe getResourceAsStream is still a simpler and more portable solution to the problem.

– Drew MacInnis
Dec 15 '16 at 3:56












11 Answers
11






active

oldest

votes


















270














Rather than trying to address the resource as a File just ask the ClassLoader to return an InputStream for the resource instead via getResourceAsStream:



InputStream in = getClass().getResourceAsStream("/file.txt"); 
BufferedReader reader = new BufferedReader(new InputStreamReader(in));


As long as the file.txt resource is available on the classpath then this approach will work the same way regardless of whether the file.txt resource is in a classes/ directory or inside a jar.



The URI is not hierarchical occurs because the URI for a resource within a jar file is going to look something like this: file:/example.jar!/file.txt. You cannot read the entries within a jar (a zip file) like it was a plain old File.



This is explained well by the answers to:



  • How do I read a resource file from a Java jar file?

  • Java Jar file: use resource errors: URI is not hierarchical





share|improve this answer




















  • 3





    Thank you, this was very helpful and the code works perfectly, but I do have one problem, I need to determine whether the InputStream exists (like File.exists()) so my game can tell whether to use the default file or not. Thanks.

    – PrinceCJC
    Dec 5 '13 at 15:23






  • 1





    Oh and BTW the reason getClass().getResource("**/folder**/file.txt") made it work is because I had that folder in the same directory as my jar :).

    – PrinceCJC
    Dec 5 '13 at 15:33







  • 3





    getResourceAsStream returns null if the resource does not exist so that can be your "exists" test.

    – Drew MacInnis
    Dec 5 '13 at 19:05







  • 1





    BTW, you have a typo: it should be BufferedReader, not BufferredReader (notice the extra 'r' in the later)

    – mailmindlin
    Sep 6 '14 at 5:56






  • 1





    And of course... don't forget to close the inputStream and BufferedReader

    – Noremac
    May 15 '15 at 13:38


















13














To access a file in a jar you have two options:



  • Place the file in directory structure matching your package name (after extracting .jar file, it should be in the same directory as .class file), then access it using getClass().getResourceAsStream("file.txt")


  • Place the file at the root (after extracting .jar file, it should be in the root), then access it using Thread.currentThread().getContextClassLoader().getResourceAsStream("file.txt")


The first option may not work when jar is used as a plugin.






share|improve this answer






























    6














    If you wanna read as a file, I believe there still is a similar solution:



     ClassLoader classLoader = getClass().getClassLoader();
    File file = new File(classLoader.getResource("file/test.xml").getFile());





    share|improve this answer


















    • 3





      URL.getFile() does not convert a URL to a file name. It returns the portion of the URL after the host, with all percent-encodings intact, so if the path contains any non-ASCII characters or any ASCII characters not allowed in URLs (including spaces), the result will not be an existing file name, even if the URL is a file: URL.

      – VGR
      Mar 5 '16 at 18:07






    • 15





      this does not work inside once the program is build to a jar

      – Akshay Kasar
      Sep 20 '17 at 12:42











    • Doesn't work from jar unless you convert to string and save it locally first.

      – smoosh911
      Aug 9 '18 at 16:55


















    2














    I had this problem before and I made fallback way for loading. Basically first way work within .jar file and second way works within eclipse or other IDE.



    public class MyClass 

    public static InputStream accessFile()
    String resource = "my-file-located-in-resources.txt";

    // this is the path within the jar file
    InputStream input = MyClass.class.getResourceAsStream("/resources/" + resource);
    if (input == null)
    // this is how we load file within editor (eg eclipse)
    input = MyClass.class.getClassLoader().getResourceAsStream(resource);


    return input;







    share|improve this answer






























      1














      Make sure that you work with the correct separator. I replaced all / in a relative path with a File.separator. This worked fine in the IDE, however did not work in the build JAR.






      share|improve this answer






























        1














        Up until now (December 2017), this is the only solution I found which works both inside and outside the IDE.



        Use PathMatchingResourcePatternResolver



        Note: it works also in spring-boot



        In this example I'm reading some files located in src/main/resources/my_folder:



        try 
        // Get all the files under this inner resource folder: my_folder
        String scannedPackage = "my_folder/*";
        PathMatchingResourcePatternResolver scanner = new PathMatchingResourcePatternResolver();
        Resource resources = scanner.getResources(scannedPackage);

        if (resources == null catch (Exception e)
        throw new Exception("Failed to read the resources folder: " + e.getMessage(), e);






        share|improve this answer






























          0














          You could also just use java.nio. Here is an example to slurp in text from a file at resourcePath in classpath:



          new String(Files.readAllBytes(Paths.get(getClass().getResource(resourcePath).toURI())))





          share|improve this answer




















          • 6





            A URI referring to a resource inside a .jar file is not a file: URI, so your call to Paths.get will fail.

            – VGR
            Mar 5 '16 at 18:08






          • 13





            This indeed will fail if the resource is located inside a jar file.I am curious if anyone is aware of a proper way to read from a jar using the Files class as illustrated in this example, i.e. not using a inputstream.

            – George Curington
            May 5 '16 at 0:44



















          0














          After a lot of digging around in Java, the only solution that seems to work for me is to manually read the jar file itself unless you're in a development environment(IDE):



          /** @return The root folder or jar file that the class loader loaded from */
          public static final File getClasspathFile()
          return new File(YourMainClass.class.getProtectionDomain().getCodeSource().getLocation().getFile());


          /** @param resource The path to the resource
          * @return An InputStream containing the resource's contents, or
          * <b><code>null</code></b> if the resource does not exist */
          public static final InputStream getResourceAsStream(String resource)
          resource = resource.startsWith("/") ? resource : "/" + resource;
          if(getClasspathFile().isDirectory()) //Development environment:
          return YourMainClass.class.getResourceAsStream(resource);

          final String res = resource;//Jar or exe:
          return AccessController.doPrivileged(new PrivilegedAction<InputStream>()
          @SuppressWarnings("resource")
          @Override
          public InputStream run()
          try
          final JarFile jar = new JarFile(getClasspathFile());
          String resource = res.startsWith("/") ? res.substring(1) : res;
          if(resource.endsWith("/")) //Directory; list direct contents:(Mimics normal getResourceAsStream("someFolder/") behaviour)
          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          Enumeration<JarEntry> entries = jar.entries();
          while(entries.hasMoreElements())
          JarEntry entry = entries.nextElement();
          if(entry.getName().startsWith(resource) && entry.getName().length() > resource.length())
          String name = entry.getName().substring(resource.length());
          if(name.contains("/") ? (name.endsWith("/") && (name.indexOf("/") == name.lastIndexOf("/"))) : true) //If it's a folder, we don't want the children's folders, only the parent folder's children!
          name = name.endsWith("/") ? name.substring(0, name.length() - 1) : name;
          baos.write(name.getBytes(StandardCharsets.UTF_8));
          baos.write('r');
          baos.write('n');



          jar.close();
          return new ByteArrayInputStream(baos.toByteArray());

          JarEntry entry = jar.getJarEntry(resource);
          InputStream in = entry != null ? jar.getInputStream(entry) : null;
          if(in == null)
          jar.close();
          return in;

          final InputStream stream = in;//Don't manage 'jar' with try-with-resources or close jar until the
          return new InputStream() //returned stream is closed(closing the jar closes all associated InputStreams):
          @Override
          public int read() throws IOException
          return stream.read();


          @Override
          public int read(byte b) throws IOException
          return stream.read(b);


          @Override
          public int read(byte b, int off, int len) throws IOException
          return stream.read(b, off, len);


          @Override
          public long skip(long n) throws IOException
          return stream.skip(n);


          @Override
          public int available() throws IOException
          return stream.available();


          @Override
          public void close() throws IOException
          try
          jar.close();
          catch(IOException ignored)

          stream.close();


          @Override
          public synchronized void mark(int readlimit)
          stream.mark(readlimit);


          @Override
          public synchronized void reset() throws IOException
          stream.reset();


          @Override
          public boolean markSupported()
          return stream.markSupported();

          ;
          catch(Throwable e)
          e.printStackTrace();
          return null;


          );



          Note: The above code only seems to work correctly for jar files if it is in the main class. I'm not sure why.






          share|improve this answer
































            0














            I think this should be works in java as well. The following code I use is using kotlin.



            val resource = Thread.currentThread().contextClassLoader.getResource('resources.txt')





            share|improve this answer






























              -1














              You can use class loader which will read from classpath as ROOT path (without "/" in the beginning)



              InputStream in = getClass().getClassLoader().getResourceAsStream("file.txt"); 
              BufferedReader reader = new BufferedReader(new InputStreamReader(in));





              share|improve this answer






























                -1














                If you are using spring, then you can use the the following method to read file from src/main/resources:



                import java.io.BufferedReader;
                import java.io.IOException;
                import java.io.InputStream;
                import java.io.InputStreamReader;
                import org.springframework.core.io.ClassPathResource;

                public String readFileToString(String path) throws IOException

                StringBuilder resultBuilder = new StringBuilder("");
                ClassPathResource resource = new ClassPathResource(path);

                try (
                InputStream inputStream = resource.getInputStream();
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)))

                String line;

                while ((line = bufferedReader.readLine()) != null)
                resultBuilder.append(line);




                return resultBuilder.toString();






                share|improve this answer




















                • 1





                  Welcome to SO. This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post. Also check this what can I do instead.

                  – thewaywewere
                  May 3 '17 at 15:36











                • Well, yes it does, even before my edit.

                  – Tristan
                  Nov 27 '18 at 12:37











                Your Answer






                StackExchange.ifUsing("editor", function ()
                StackExchange.using("externalEditor", function ()
                StackExchange.using("snippets", function ()
                StackExchange.snippets.init();
                );
                );
                , "code-snippets");

                StackExchange.ready(function()
                var channelOptions =
                tags: "".split(" "),
                id: "1"
                ;
                initTagRenderer("".split(" "), "".split(" "), channelOptions);

                StackExchange.using("externalEditor", function()
                // Have to fire editor after snippets, if snippets enabled
                if (StackExchange.settings.snippets.snippetsEnabled)
                StackExchange.using("snippets", function()
                createEditor();
                );

                else
                createEditor();

                );

                function createEditor()
                StackExchange.prepareEditor(
                heartbeatType: 'answer',
                autoActivateHeartbeat: false,
                convertImagesToLinks: true,
                noModals: true,
                showLowRepImageUploadWarning: true,
                reputationToPostImages: 10,
                bindNavPrevention: true,
                postfix: "",
                imageUploader:
                brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                allowUrls: true
                ,
                onDemand: true,
                discardSelector: ".discard-answer"
                ,immediatelyShowMarkdownHelp:true
                );



                );













                draft saved

                draft discarded


















                StackExchange.ready(
                function ()
                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f20389255%2freading-a-resource-file-from-within-jar%23new-answer', 'question_page');

                );

                Post as a guest















                Required, but never shown

























                11 Answers
                11






                active

                oldest

                votes








                11 Answers
                11






                active

                oldest

                votes









                active

                oldest

                votes






                active

                oldest

                votes









                270














                Rather than trying to address the resource as a File just ask the ClassLoader to return an InputStream for the resource instead via getResourceAsStream:



                InputStream in = getClass().getResourceAsStream("/file.txt"); 
                BufferedReader reader = new BufferedReader(new InputStreamReader(in));


                As long as the file.txt resource is available on the classpath then this approach will work the same way regardless of whether the file.txt resource is in a classes/ directory or inside a jar.



                The URI is not hierarchical occurs because the URI for a resource within a jar file is going to look something like this: file:/example.jar!/file.txt. You cannot read the entries within a jar (a zip file) like it was a plain old File.



                This is explained well by the answers to:



                • How do I read a resource file from a Java jar file?

                • Java Jar file: use resource errors: URI is not hierarchical





                share|improve this answer




















                • 3





                  Thank you, this was very helpful and the code works perfectly, but I do have one problem, I need to determine whether the InputStream exists (like File.exists()) so my game can tell whether to use the default file or not. Thanks.

                  – PrinceCJC
                  Dec 5 '13 at 15:23






                • 1





                  Oh and BTW the reason getClass().getResource("**/folder**/file.txt") made it work is because I had that folder in the same directory as my jar :).

                  – PrinceCJC
                  Dec 5 '13 at 15:33







                • 3





                  getResourceAsStream returns null if the resource does not exist so that can be your "exists" test.

                  – Drew MacInnis
                  Dec 5 '13 at 19:05







                • 1





                  BTW, you have a typo: it should be BufferedReader, not BufferredReader (notice the extra 'r' in the later)

                  – mailmindlin
                  Sep 6 '14 at 5:56






                • 1





                  And of course... don't forget to close the inputStream and BufferedReader

                  – Noremac
                  May 15 '15 at 13:38















                270














                Rather than trying to address the resource as a File just ask the ClassLoader to return an InputStream for the resource instead via getResourceAsStream:



                InputStream in = getClass().getResourceAsStream("/file.txt"); 
                BufferedReader reader = new BufferedReader(new InputStreamReader(in));


                As long as the file.txt resource is available on the classpath then this approach will work the same way regardless of whether the file.txt resource is in a classes/ directory or inside a jar.



                The URI is not hierarchical occurs because the URI for a resource within a jar file is going to look something like this: file:/example.jar!/file.txt. You cannot read the entries within a jar (a zip file) like it was a plain old File.



                This is explained well by the answers to:



                • How do I read a resource file from a Java jar file?

                • Java Jar file: use resource errors: URI is not hierarchical





                share|improve this answer




















                • 3





                  Thank you, this was very helpful and the code works perfectly, but I do have one problem, I need to determine whether the InputStream exists (like File.exists()) so my game can tell whether to use the default file or not. Thanks.

                  – PrinceCJC
                  Dec 5 '13 at 15:23






                • 1





                  Oh and BTW the reason getClass().getResource("**/folder**/file.txt") made it work is because I had that folder in the same directory as my jar :).

                  – PrinceCJC
                  Dec 5 '13 at 15:33







                • 3





                  getResourceAsStream returns null if the resource does not exist so that can be your "exists" test.

                  – Drew MacInnis
                  Dec 5 '13 at 19:05







                • 1





                  BTW, you have a typo: it should be BufferedReader, not BufferredReader (notice the extra 'r' in the later)

                  – mailmindlin
                  Sep 6 '14 at 5:56






                • 1





                  And of course... don't forget to close the inputStream and BufferedReader

                  – Noremac
                  May 15 '15 at 13:38













                270












                270








                270







                Rather than trying to address the resource as a File just ask the ClassLoader to return an InputStream for the resource instead via getResourceAsStream:



                InputStream in = getClass().getResourceAsStream("/file.txt"); 
                BufferedReader reader = new BufferedReader(new InputStreamReader(in));


                As long as the file.txt resource is available on the classpath then this approach will work the same way regardless of whether the file.txt resource is in a classes/ directory or inside a jar.



                The URI is not hierarchical occurs because the URI for a resource within a jar file is going to look something like this: file:/example.jar!/file.txt. You cannot read the entries within a jar (a zip file) like it was a plain old File.



                This is explained well by the answers to:



                • How do I read a resource file from a Java jar file?

                • Java Jar file: use resource errors: URI is not hierarchical





                share|improve this answer















                Rather than trying to address the resource as a File just ask the ClassLoader to return an InputStream for the resource instead via getResourceAsStream:



                InputStream in = getClass().getResourceAsStream("/file.txt"); 
                BufferedReader reader = new BufferedReader(new InputStreamReader(in));


                As long as the file.txt resource is available on the classpath then this approach will work the same way regardless of whether the file.txt resource is in a classes/ directory or inside a jar.



                The URI is not hierarchical occurs because the URI for a resource within a jar file is going to look something like this: file:/example.jar!/file.txt. You cannot read the entries within a jar (a zip file) like it was a plain old File.



                This is explained well by the answers to:



                • How do I read a resource file from a Java jar file?

                • Java Jar file: use resource errors: URI is not hierarchical






                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Jun 13 '18 at 0:26

























                answered Dec 5 '13 at 1:05









                Drew MacInnisDrew MacInnis

                4,95111315




                4,95111315







                • 3





                  Thank you, this was very helpful and the code works perfectly, but I do have one problem, I need to determine whether the InputStream exists (like File.exists()) so my game can tell whether to use the default file or not. Thanks.

                  – PrinceCJC
                  Dec 5 '13 at 15:23






                • 1





                  Oh and BTW the reason getClass().getResource("**/folder**/file.txt") made it work is because I had that folder in the same directory as my jar :).

                  – PrinceCJC
                  Dec 5 '13 at 15:33







                • 3





                  getResourceAsStream returns null if the resource does not exist so that can be your "exists" test.

                  – Drew MacInnis
                  Dec 5 '13 at 19:05







                • 1





                  BTW, you have a typo: it should be BufferedReader, not BufferredReader (notice the extra 'r' in the later)

                  – mailmindlin
                  Sep 6 '14 at 5:56






                • 1





                  And of course... don't forget to close the inputStream and BufferedReader

                  – Noremac
                  May 15 '15 at 13:38












                • 3





                  Thank you, this was very helpful and the code works perfectly, but I do have one problem, I need to determine whether the InputStream exists (like File.exists()) so my game can tell whether to use the default file or not. Thanks.

                  – PrinceCJC
                  Dec 5 '13 at 15:23






                • 1





                  Oh and BTW the reason getClass().getResource("**/folder**/file.txt") made it work is because I had that folder in the same directory as my jar :).

                  – PrinceCJC
                  Dec 5 '13 at 15:33







                • 3





                  getResourceAsStream returns null if the resource does not exist so that can be your "exists" test.

                  – Drew MacInnis
                  Dec 5 '13 at 19:05







                • 1





                  BTW, you have a typo: it should be BufferedReader, not BufferredReader (notice the extra 'r' in the later)

                  – mailmindlin
                  Sep 6 '14 at 5:56






                • 1





                  And of course... don't forget to close the inputStream and BufferedReader

                  – Noremac
                  May 15 '15 at 13:38







                3




                3





                Thank you, this was very helpful and the code works perfectly, but I do have one problem, I need to determine whether the InputStream exists (like File.exists()) so my game can tell whether to use the default file or not. Thanks.

                – PrinceCJC
                Dec 5 '13 at 15:23





                Thank you, this was very helpful and the code works perfectly, but I do have one problem, I need to determine whether the InputStream exists (like File.exists()) so my game can tell whether to use the default file or not. Thanks.

                – PrinceCJC
                Dec 5 '13 at 15:23




                1




                1





                Oh and BTW the reason getClass().getResource("**/folder**/file.txt") made it work is because I had that folder in the same directory as my jar :).

                – PrinceCJC
                Dec 5 '13 at 15:33






                Oh and BTW the reason getClass().getResource("**/folder**/file.txt") made it work is because I had that folder in the same directory as my jar :).

                – PrinceCJC
                Dec 5 '13 at 15:33





                3




                3





                getResourceAsStream returns null if the resource does not exist so that can be your "exists" test.

                – Drew MacInnis
                Dec 5 '13 at 19:05






                getResourceAsStream returns null if the resource does not exist so that can be your "exists" test.

                – Drew MacInnis
                Dec 5 '13 at 19:05





                1




                1





                BTW, you have a typo: it should be BufferedReader, not BufferredReader (notice the extra 'r' in the later)

                – mailmindlin
                Sep 6 '14 at 5:56





                BTW, you have a typo: it should be BufferedReader, not BufferredReader (notice the extra 'r' in the later)

                – mailmindlin
                Sep 6 '14 at 5:56




                1




                1





                And of course... don't forget to close the inputStream and BufferedReader

                – Noremac
                May 15 '15 at 13:38





                And of course... don't forget to close the inputStream and BufferedReader

                – Noremac
                May 15 '15 at 13:38













                13














                To access a file in a jar you have two options:



                • Place the file in directory structure matching your package name (after extracting .jar file, it should be in the same directory as .class file), then access it using getClass().getResourceAsStream("file.txt")


                • Place the file at the root (after extracting .jar file, it should be in the root), then access it using Thread.currentThread().getContextClassLoader().getResourceAsStream("file.txt")


                The first option may not work when jar is used as a plugin.






                share|improve this answer



























                  13














                  To access a file in a jar you have two options:



                  • Place the file in directory structure matching your package name (after extracting .jar file, it should be in the same directory as .class file), then access it using getClass().getResourceAsStream("file.txt")


                  • Place the file at the root (after extracting .jar file, it should be in the root), then access it using Thread.currentThread().getContextClassLoader().getResourceAsStream("file.txt")


                  The first option may not work when jar is used as a plugin.






                  share|improve this answer

























                    13












                    13








                    13







                    To access a file in a jar you have two options:



                    • Place the file in directory structure matching your package name (after extracting .jar file, it should be in the same directory as .class file), then access it using getClass().getResourceAsStream("file.txt")


                    • Place the file at the root (after extracting .jar file, it should be in the root), then access it using Thread.currentThread().getContextClassLoader().getResourceAsStream("file.txt")


                    The first option may not work when jar is used as a plugin.






                    share|improve this answer













                    To access a file in a jar you have two options:



                    • Place the file in directory structure matching your package name (after extracting .jar file, it should be in the same directory as .class file), then access it using getClass().getResourceAsStream("file.txt")


                    • Place the file at the root (after extracting .jar file, it should be in the root), then access it using Thread.currentThread().getContextClassLoader().getResourceAsStream("file.txt")


                    The first option may not work when jar is used as a plugin.







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Sep 17 '16 at 8:55









                    Juozas KontvainisJuozas Kontvainis

                    6,12864463




                    6,12864463





















                        6














                        If you wanna read as a file, I believe there still is a similar solution:



                         ClassLoader classLoader = getClass().getClassLoader();
                        File file = new File(classLoader.getResource("file/test.xml").getFile());





                        share|improve this answer


















                        • 3





                          URL.getFile() does not convert a URL to a file name. It returns the portion of the URL after the host, with all percent-encodings intact, so if the path contains any non-ASCII characters or any ASCII characters not allowed in URLs (including spaces), the result will not be an existing file name, even if the URL is a file: URL.

                          – VGR
                          Mar 5 '16 at 18:07






                        • 15





                          this does not work inside once the program is build to a jar

                          – Akshay Kasar
                          Sep 20 '17 at 12:42











                        • Doesn't work from jar unless you convert to string and save it locally first.

                          – smoosh911
                          Aug 9 '18 at 16:55















                        6














                        If you wanna read as a file, I believe there still is a similar solution:



                         ClassLoader classLoader = getClass().getClassLoader();
                        File file = new File(classLoader.getResource("file/test.xml").getFile());





                        share|improve this answer


















                        • 3





                          URL.getFile() does not convert a URL to a file name. It returns the portion of the URL after the host, with all percent-encodings intact, so if the path contains any non-ASCII characters or any ASCII characters not allowed in URLs (including spaces), the result will not be an existing file name, even if the URL is a file: URL.

                          – VGR
                          Mar 5 '16 at 18:07






                        • 15





                          this does not work inside once the program is build to a jar

                          – Akshay Kasar
                          Sep 20 '17 at 12:42











                        • Doesn't work from jar unless you convert to string and save it locally first.

                          – smoosh911
                          Aug 9 '18 at 16:55













                        6












                        6








                        6







                        If you wanna read as a file, I believe there still is a similar solution:



                         ClassLoader classLoader = getClass().getClassLoader();
                        File file = new File(classLoader.getResource("file/test.xml").getFile());





                        share|improve this answer













                        If you wanna read as a file, I believe there still is a similar solution:



                         ClassLoader classLoader = getClass().getClassLoader();
                        File file = new File(classLoader.getResource("file/test.xml").getFile());






                        share|improve this answer












                        share|improve this answer



                        share|improve this answer










                        answered Nov 16 '14 at 21:04









                        pablo.vixpablo.vix

                        1,13911011




                        1,13911011







                        • 3





                          URL.getFile() does not convert a URL to a file name. It returns the portion of the URL after the host, with all percent-encodings intact, so if the path contains any non-ASCII characters or any ASCII characters not allowed in URLs (including spaces), the result will not be an existing file name, even if the URL is a file: URL.

                          – VGR
                          Mar 5 '16 at 18:07






                        • 15





                          this does not work inside once the program is build to a jar

                          – Akshay Kasar
                          Sep 20 '17 at 12:42











                        • Doesn't work from jar unless you convert to string and save it locally first.

                          – smoosh911
                          Aug 9 '18 at 16:55












                        • 3





                          URL.getFile() does not convert a URL to a file name. It returns the portion of the URL after the host, with all percent-encodings intact, so if the path contains any non-ASCII characters or any ASCII characters not allowed in URLs (including spaces), the result will not be an existing file name, even if the URL is a file: URL.

                          – VGR
                          Mar 5 '16 at 18:07






                        • 15





                          this does not work inside once the program is build to a jar

                          – Akshay Kasar
                          Sep 20 '17 at 12:42











                        • Doesn't work from jar unless you convert to string and save it locally first.

                          – smoosh911
                          Aug 9 '18 at 16:55







                        3




                        3





                        URL.getFile() does not convert a URL to a file name. It returns the portion of the URL after the host, with all percent-encodings intact, so if the path contains any non-ASCII characters or any ASCII characters not allowed in URLs (including spaces), the result will not be an existing file name, even if the URL is a file: URL.

                        – VGR
                        Mar 5 '16 at 18:07





                        URL.getFile() does not convert a URL to a file name. It returns the portion of the URL after the host, with all percent-encodings intact, so if the path contains any non-ASCII characters or any ASCII characters not allowed in URLs (including spaces), the result will not be an existing file name, even if the URL is a file: URL.

                        – VGR
                        Mar 5 '16 at 18:07




                        15




                        15





                        this does not work inside once the program is build to a jar

                        – Akshay Kasar
                        Sep 20 '17 at 12:42





                        this does not work inside once the program is build to a jar

                        – Akshay Kasar
                        Sep 20 '17 at 12:42













                        Doesn't work from jar unless you convert to string and save it locally first.

                        – smoosh911
                        Aug 9 '18 at 16:55





                        Doesn't work from jar unless you convert to string and save it locally first.

                        – smoosh911
                        Aug 9 '18 at 16:55











                        2














                        I had this problem before and I made fallback way for loading. Basically first way work within .jar file and second way works within eclipse or other IDE.



                        public class MyClass 

                        public static InputStream accessFile()
                        String resource = "my-file-located-in-resources.txt";

                        // this is the path within the jar file
                        InputStream input = MyClass.class.getResourceAsStream("/resources/" + resource);
                        if (input == null)
                        // this is how we load file within editor (eg eclipse)
                        input = MyClass.class.getClassLoader().getResourceAsStream(resource);


                        return input;







                        share|improve this answer



























                          2














                          I had this problem before and I made fallback way for loading. Basically first way work within .jar file and second way works within eclipse or other IDE.



                          public class MyClass 

                          public static InputStream accessFile()
                          String resource = "my-file-located-in-resources.txt";

                          // this is the path within the jar file
                          InputStream input = MyClass.class.getResourceAsStream("/resources/" + resource);
                          if (input == null)
                          // this is how we load file within editor (eg eclipse)
                          input = MyClass.class.getClassLoader().getResourceAsStream(resource);


                          return input;







                          share|improve this answer

























                            2












                            2








                            2







                            I had this problem before and I made fallback way for loading. Basically first way work within .jar file and second way works within eclipse or other IDE.



                            public class MyClass 

                            public static InputStream accessFile()
                            String resource = "my-file-located-in-resources.txt";

                            // this is the path within the jar file
                            InputStream input = MyClass.class.getResourceAsStream("/resources/" + resource);
                            if (input == null)
                            // this is how we load file within editor (eg eclipse)
                            input = MyClass.class.getClassLoader().getResourceAsStream(resource);


                            return input;







                            share|improve this answer













                            I had this problem before and I made fallback way for loading. Basically first way work within .jar file and second way works within eclipse or other IDE.



                            public class MyClass 

                            public static InputStream accessFile()
                            String resource = "my-file-located-in-resources.txt";

                            // this is the path within the jar file
                            InputStream input = MyClass.class.getResourceAsStream("/resources/" + resource);
                            if (input == null)
                            // this is how we load file within editor (eg eclipse)
                            input = MyClass.class.getClassLoader().getResourceAsStream(resource);


                            return input;








                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Jun 27 '17 at 15:31









                            MFormMForm

                            1293




                            1293





















                                1














                                Make sure that you work with the correct separator. I replaced all / in a relative path with a File.separator. This worked fine in the IDE, however did not work in the build JAR.






                                share|improve this answer



























                                  1














                                  Make sure that you work with the correct separator. I replaced all / in a relative path with a File.separator. This worked fine in the IDE, however did not work in the build JAR.






                                  share|improve this answer

























                                    1












                                    1








                                    1







                                    Make sure that you work with the correct separator. I replaced all / in a relative path with a File.separator. This worked fine in the IDE, however did not work in the build JAR.






                                    share|improve this answer













                                    Make sure that you work with the correct separator. I replaced all / in a relative path with a File.separator. This worked fine in the IDE, however did not work in the build JAR.







                                    share|improve this answer












                                    share|improve this answer



                                    share|improve this answer










                                    answered Feb 17 '17 at 13:29









                                    PettersonPetterson

                                    472314




                                    472314





















                                        1














                                        Up until now (December 2017), this is the only solution I found which works both inside and outside the IDE.



                                        Use PathMatchingResourcePatternResolver



                                        Note: it works also in spring-boot



                                        In this example I'm reading some files located in src/main/resources/my_folder:



                                        try 
                                        // Get all the files under this inner resource folder: my_folder
                                        String scannedPackage = "my_folder/*";
                                        PathMatchingResourcePatternResolver scanner = new PathMatchingResourcePatternResolver();
                                        Resource resources = scanner.getResources(scannedPackage);

                                        if (resources == null catch (Exception e)
                                        throw new Exception("Failed to read the resources folder: " + e.getMessage(), e);






                                        share|improve this answer



























                                          1














                                          Up until now (December 2017), this is the only solution I found which works both inside and outside the IDE.



                                          Use PathMatchingResourcePatternResolver



                                          Note: it works also in spring-boot



                                          In this example I'm reading some files located in src/main/resources/my_folder:



                                          try 
                                          // Get all the files under this inner resource folder: my_folder
                                          String scannedPackage = "my_folder/*";
                                          PathMatchingResourcePatternResolver scanner = new PathMatchingResourcePatternResolver();
                                          Resource resources = scanner.getResources(scannedPackage);

                                          if (resources == null catch (Exception e)
                                          throw new Exception("Failed to read the resources folder: " + e.getMessage(), e);






                                          share|improve this answer

























                                            1












                                            1








                                            1







                                            Up until now (December 2017), this is the only solution I found which works both inside and outside the IDE.



                                            Use PathMatchingResourcePatternResolver



                                            Note: it works also in spring-boot



                                            In this example I'm reading some files located in src/main/resources/my_folder:



                                            try 
                                            // Get all the files under this inner resource folder: my_folder
                                            String scannedPackage = "my_folder/*";
                                            PathMatchingResourcePatternResolver scanner = new PathMatchingResourcePatternResolver();
                                            Resource resources = scanner.getResources(scannedPackage);

                                            if (resources == null catch (Exception e)
                                            throw new Exception("Failed to read the resources folder: " + e.getMessage(), e);






                                            share|improve this answer













                                            Up until now (December 2017), this is the only solution I found which works both inside and outside the IDE.



                                            Use PathMatchingResourcePatternResolver



                                            Note: it works also in spring-boot



                                            In this example I'm reading some files located in src/main/resources/my_folder:



                                            try 
                                            // Get all the files under this inner resource folder: my_folder
                                            String scannedPackage = "my_folder/*";
                                            PathMatchingResourcePatternResolver scanner = new PathMatchingResourcePatternResolver();
                                            Resource resources = scanner.getResources(scannedPackage);

                                            if (resources == null catch (Exception e)
                                            throw new Exception("Failed to read the resources folder: " + e.getMessage(), e);







                                            share|improve this answer












                                            share|improve this answer



                                            share|improve this answer










                                            answered Dec 20 '17 at 10:42









                                            Naor BarNaor Bar

                                            60456




                                            60456





















                                                0














                                                You could also just use java.nio. Here is an example to slurp in text from a file at resourcePath in classpath:



                                                new String(Files.readAllBytes(Paths.get(getClass().getResource(resourcePath).toURI())))





                                                share|improve this answer




















                                                • 6





                                                  A URI referring to a resource inside a .jar file is not a file: URI, so your call to Paths.get will fail.

                                                  – VGR
                                                  Mar 5 '16 at 18:08






                                                • 13





                                                  This indeed will fail if the resource is located inside a jar file.I am curious if anyone is aware of a proper way to read from a jar using the Files class as illustrated in this example, i.e. not using a inputstream.

                                                  – George Curington
                                                  May 5 '16 at 0:44
















                                                0














                                                You could also just use java.nio. Here is an example to slurp in text from a file at resourcePath in classpath:



                                                new String(Files.readAllBytes(Paths.get(getClass().getResource(resourcePath).toURI())))





                                                share|improve this answer




















                                                • 6





                                                  A URI referring to a resource inside a .jar file is not a file: URI, so your call to Paths.get will fail.

                                                  – VGR
                                                  Mar 5 '16 at 18:08






                                                • 13





                                                  This indeed will fail if the resource is located inside a jar file.I am curious if anyone is aware of a proper way to read from a jar using the Files class as illustrated in this example, i.e. not using a inputstream.

                                                  – George Curington
                                                  May 5 '16 at 0:44














                                                0












                                                0








                                                0







                                                You could also just use java.nio. Here is an example to slurp in text from a file at resourcePath in classpath:



                                                new String(Files.readAllBytes(Paths.get(getClass().getResource(resourcePath).toURI())))





                                                share|improve this answer















                                                You could also just use java.nio. Here is an example to slurp in text from a file at resourcePath in classpath:



                                                new String(Files.readAllBytes(Paths.get(getClass().getResource(resourcePath).toURI())))






                                                share|improve this answer














                                                share|improve this answer



                                                share|improve this answer








                                                edited Aug 10 '15 at 23:16









                                                Community

                                                11




                                                11










                                                answered Jul 1 '15 at 19:40









                                                Ayush GuptaAyush Gupta

                                                3,87511616




                                                3,87511616







                                                • 6





                                                  A URI referring to a resource inside a .jar file is not a file: URI, so your call to Paths.get will fail.

                                                  – VGR
                                                  Mar 5 '16 at 18:08






                                                • 13





                                                  This indeed will fail if the resource is located inside a jar file.I am curious if anyone is aware of a proper way to read from a jar using the Files class as illustrated in this example, i.e. not using a inputstream.

                                                  – George Curington
                                                  May 5 '16 at 0:44













                                                • 6





                                                  A URI referring to a resource inside a .jar file is not a file: URI, so your call to Paths.get will fail.

                                                  – VGR
                                                  Mar 5 '16 at 18:08






                                                • 13





                                                  This indeed will fail if the resource is located inside a jar file.I am curious if anyone is aware of a proper way to read from a jar using the Files class as illustrated in this example, i.e. not using a inputstream.

                                                  – George Curington
                                                  May 5 '16 at 0:44








                                                6




                                                6





                                                A URI referring to a resource inside a .jar file is not a file: URI, so your call to Paths.get will fail.

                                                – VGR
                                                Mar 5 '16 at 18:08





                                                A URI referring to a resource inside a .jar file is not a file: URI, so your call to Paths.get will fail.

                                                – VGR
                                                Mar 5 '16 at 18:08




                                                13




                                                13





                                                This indeed will fail if the resource is located inside a jar file.I am curious if anyone is aware of a proper way to read from a jar using the Files class as illustrated in this example, i.e. not using a inputstream.

                                                – George Curington
                                                May 5 '16 at 0:44






                                                This indeed will fail if the resource is located inside a jar file.I am curious if anyone is aware of a proper way to read from a jar using the Files class as illustrated in this example, i.e. not using a inputstream.

                                                – George Curington
                                                May 5 '16 at 0:44












                                                0














                                                After a lot of digging around in Java, the only solution that seems to work for me is to manually read the jar file itself unless you're in a development environment(IDE):



                                                /** @return The root folder or jar file that the class loader loaded from */
                                                public static final File getClasspathFile()
                                                return new File(YourMainClass.class.getProtectionDomain().getCodeSource().getLocation().getFile());


                                                /** @param resource The path to the resource
                                                * @return An InputStream containing the resource's contents, or
                                                * <b><code>null</code></b> if the resource does not exist */
                                                public static final InputStream getResourceAsStream(String resource)
                                                resource = resource.startsWith("/") ? resource : "/" + resource;
                                                if(getClasspathFile().isDirectory()) //Development environment:
                                                return YourMainClass.class.getResourceAsStream(resource);

                                                final String res = resource;//Jar or exe:
                                                return AccessController.doPrivileged(new PrivilegedAction<InputStream>()
                                                @SuppressWarnings("resource")
                                                @Override
                                                public InputStream run()
                                                try
                                                final JarFile jar = new JarFile(getClasspathFile());
                                                String resource = res.startsWith("/") ? res.substring(1) : res;
                                                if(resource.endsWith("/")) //Directory; list direct contents:(Mimics normal getResourceAsStream("someFolder/") behaviour)
                                                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                                                Enumeration<JarEntry> entries = jar.entries();
                                                while(entries.hasMoreElements())
                                                JarEntry entry = entries.nextElement();
                                                if(entry.getName().startsWith(resource) && entry.getName().length() > resource.length())
                                                String name = entry.getName().substring(resource.length());
                                                if(name.contains("/") ? (name.endsWith("/") && (name.indexOf("/") == name.lastIndexOf("/"))) : true) //If it's a folder, we don't want the children's folders, only the parent folder's children!
                                                name = name.endsWith("/") ? name.substring(0, name.length() - 1) : name;
                                                baos.write(name.getBytes(StandardCharsets.UTF_8));
                                                baos.write('r');
                                                baos.write('n');



                                                jar.close();
                                                return new ByteArrayInputStream(baos.toByteArray());

                                                JarEntry entry = jar.getJarEntry(resource);
                                                InputStream in = entry != null ? jar.getInputStream(entry) : null;
                                                if(in == null)
                                                jar.close();
                                                return in;

                                                final InputStream stream = in;//Don't manage 'jar' with try-with-resources or close jar until the
                                                return new InputStream() //returned stream is closed(closing the jar closes all associated InputStreams):
                                                @Override
                                                public int read() throws IOException
                                                return stream.read();


                                                @Override
                                                public int read(byte b) throws IOException
                                                return stream.read(b);


                                                @Override
                                                public int read(byte b, int off, int len) throws IOException
                                                return stream.read(b, off, len);


                                                @Override
                                                public long skip(long n) throws IOException
                                                return stream.skip(n);


                                                @Override
                                                public int available() throws IOException
                                                return stream.available();


                                                @Override
                                                public void close() throws IOException
                                                try
                                                jar.close();
                                                catch(IOException ignored)

                                                stream.close();


                                                @Override
                                                public synchronized void mark(int readlimit)
                                                stream.mark(readlimit);


                                                @Override
                                                public synchronized void reset() throws IOException
                                                stream.reset();


                                                @Override
                                                public boolean markSupported()
                                                return stream.markSupported();

                                                ;
                                                catch(Throwable e)
                                                e.printStackTrace();
                                                return null;


                                                );



                                                Note: The above code only seems to work correctly for jar files if it is in the main class. I'm not sure why.






                                                share|improve this answer





























                                                  0














                                                  After a lot of digging around in Java, the only solution that seems to work for me is to manually read the jar file itself unless you're in a development environment(IDE):



                                                  /** @return The root folder or jar file that the class loader loaded from */
                                                  public static final File getClasspathFile()
                                                  return new File(YourMainClass.class.getProtectionDomain().getCodeSource().getLocation().getFile());


                                                  /** @param resource The path to the resource
                                                  * @return An InputStream containing the resource's contents, or
                                                  * <b><code>null</code></b> if the resource does not exist */
                                                  public static final InputStream getResourceAsStream(String resource)
                                                  resource = resource.startsWith("/") ? resource : "/" + resource;
                                                  if(getClasspathFile().isDirectory()) //Development environment:
                                                  return YourMainClass.class.getResourceAsStream(resource);

                                                  final String res = resource;//Jar or exe:
                                                  return AccessController.doPrivileged(new PrivilegedAction<InputStream>()
                                                  @SuppressWarnings("resource")
                                                  @Override
                                                  public InputStream run()
                                                  try
                                                  final JarFile jar = new JarFile(getClasspathFile());
                                                  String resource = res.startsWith("/") ? res.substring(1) : res;
                                                  if(resource.endsWith("/")) //Directory; list direct contents:(Mimics normal getResourceAsStream("someFolder/") behaviour)
                                                  ByteArrayOutputStream baos = new ByteArrayOutputStream();
                                                  Enumeration<JarEntry> entries = jar.entries();
                                                  while(entries.hasMoreElements())
                                                  JarEntry entry = entries.nextElement();
                                                  if(entry.getName().startsWith(resource) && entry.getName().length() > resource.length())
                                                  String name = entry.getName().substring(resource.length());
                                                  if(name.contains("/") ? (name.endsWith("/") && (name.indexOf("/") == name.lastIndexOf("/"))) : true) //If it's a folder, we don't want the children's folders, only the parent folder's children!
                                                  name = name.endsWith("/") ? name.substring(0, name.length() - 1) : name;
                                                  baos.write(name.getBytes(StandardCharsets.UTF_8));
                                                  baos.write('r');
                                                  baos.write('n');



                                                  jar.close();
                                                  return new ByteArrayInputStream(baos.toByteArray());

                                                  JarEntry entry = jar.getJarEntry(resource);
                                                  InputStream in = entry != null ? jar.getInputStream(entry) : null;
                                                  if(in == null)
                                                  jar.close();
                                                  return in;

                                                  final InputStream stream = in;//Don't manage 'jar' with try-with-resources or close jar until the
                                                  return new InputStream() //returned stream is closed(closing the jar closes all associated InputStreams):
                                                  @Override
                                                  public int read() throws IOException
                                                  return stream.read();


                                                  @Override
                                                  public int read(byte b) throws IOException
                                                  return stream.read(b);


                                                  @Override
                                                  public int read(byte b, int off, int len) throws IOException
                                                  return stream.read(b, off, len);


                                                  @Override
                                                  public long skip(long n) throws IOException
                                                  return stream.skip(n);


                                                  @Override
                                                  public int available() throws IOException
                                                  return stream.available();


                                                  @Override
                                                  public void close() throws IOException
                                                  try
                                                  jar.close();
                                                  catch(IOException ignored)

                                                  stream.close();


                                                  @Override
                                                  public synchronized void mark(int readlimit)
                                                  stream.mark(readlimit);


                                                  @Override
                                                  public synchronized void reset() throws IOException
                                                  stream.reset();


                                                  @Override
                                                  public boolean markSupported()
                                                  return stream.markSupported();

                                                  ;
                                                  catch(Throwable e)
                                                  e.printStackTrace();
                                                  return null;


                                                  );



                                                  Note: The above code only seems to work correctly for jar files if it is in the main class. I'm not sure why.






                                                  share|improve this answer



























                                                    0












                                                    0








                                                    0







                                                    After a lot of digging around in Java, the only solution that seems to work for me is to manually read the jar file itself unless you're in a development environment(IDE):



                                                    /** @return The root folder or jar file that the class loader loaded from */
                                                    public static final File getClasspathFile()
                                                    return new File(YourMainClass.class.getProtectionDomain().getCodeSource().getLocation().getFile());


                                                    /** @param resource The path to the resource
                                                    * @return An InputStream containing the resource's contents, or
                                                    * <b><code>null</code></b> if the resource does not exist */
                                                    public static final InputStream getResourceAsStream(String resource)
                                                    resource = resource.startsWith("/") ? resource : "/" + resource;
                                                    if(getClasspathFile().isDirectory()) //Development environment:
                                                    return YourMainClass.class.getResourceAsStream(resource);

                                                    final String res = resource;//Jar or exe:
                                                    return AccessController.doPrivileged(new PrivilegedAction<InputStream>()
                                                    @SuppressWarnings("resource")
                                                    @Override
                                                    public InputStream run()
                                                    try
                                                    final JarFile jar = new JarFile(getClasspathFile());
                                                    String resource = res.startsWith("/") ? res.substring(1) : res;
                                                    if(resource.endsWith("/")) //Directory; list direct contents:(Mimics normal getResourceAsStream("someFolder/") behaviour)
                                                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                                                    Enumeration<JarEntry> entries = jar.entries();
                                                    while(entries.hasMoreElements())
                                                    JarEntry entry = entries.nextElement();
                                                    if(entry.getName().startsWith(resource) && entry.getName().length() > resource.length())
                                                    String name = entry.getName().substring(resource.length());
                                                    if(name.contains("/") ? (name.endsWith("/") && (name.indexOf("/") == name.lastIndexOf("/"))) : true) //If it's a folder, we don't want the children's folders, only the parent folder's children!
                                                    name = name.endsWith("/") ? name.substring(0, name.length() - 1) : name;
                                                    baos.write(name.getBytes(StandardCharsets.UTF_8));
                                                    baos.write('r');
                                                    baos.write('n');



                                                    jar.close();
                                                    return new ByteArrayInputStream(baos.toByteArray());

                                                    JarEntry entry = jar.getJarEntry(resource);
                                                    InputStream in = entry != null ? jar.getInputStream(entry) : null;
                                                    if(in == null)
                                                    jar.close();
                                                    return in;

                                                    final InputStream stream = in;//Don't manage 'jar' with try-with-resources or close jar until the
                                                    return new InputStream() //returned stream is closed(closing the jar closes all associated InputStreams):
                                                    @Override
                                                    public int read() throws IOException
                                                    return stream.read();


                                                    @Override
                                                    public int read(byte b) throws IOException
                                                    return stream.read(b);


                                                    @Override
                                                    public int read(byte b, int off, int len) throws IOException
                                                    return stream.read(b, off, len);


                                                    @Override
                                                    public long skip(long n) throws IOException
                                                    return stream.skip(n);


                                                    @Override
                                                    public int available() throws IOException
                                                    return stream.available();


                                                    @Override
                                                    public void close() throws IOException
                                                    try
                                                    jar.close();
                                                    catch(IOException ignored)

                                                    stream.close();


                                                    @Override
                                                    public synchronized void mark(int readlimit)
                                                    stream.mark(readlimit);


                                                    @Override
                                                    public synchronized void reset() throws IOException
                                                    stream.reset();


                                                    @Override
                                                    public boolean markSupported()
                                                    return stream.markSupported();

                                                    ;
                                                    catch(Throwable e)
                                                    e.printStackTrace();
                                                    return null;


                                                    );



                                                    Note: The above code only seems to work correctly for jar files if it is in the main class. I'm not sure why.






                                                    share|improve this answer















                                                    After a lot of digging around in Java, the only solution that seems to work for me is to manually read the jar file itself unless you're in a development environment(IDE):



                                                    /** @return The root folder or jar file that the class loader loaded from */
                                                    public static final File getClasspathFile()
                                                    return new File(YourMainClass.class.getProtectionDomain().getCodeSource().getLocation().getFile());


                                                    /** @param resource The path to the resource
                                                    * @return An InputStream containing the resource's contents, or
                                                    * <b><code>null</code></b> if the resource does not exist */
                                                    public static final InputStream getResourceAsStream(String resource)
                                                    resource = resource.startsWith("/") ? resource : "/" + resource;
                                                    if(getClasspathFile().isDirectory()) //Development environment:
                                                    return YourMainClass.class.getResourceAsStream(resource);

                                                    final String res = resource;//Jar or exe:
                                                    return AccessController.doPrivileged(new PrivilegedAction<InputStream>()
                                                    @SuppressWarnings("resource")
                                                    @Override
                                                    public InputStream run()
                                                    try
                                                    final JarFile jar = new JarFile(getClasspathFile());
                                                    String resource = res.startsWith("/") ? res.substring(1) : res;
                                                    if(resource.endsWith("/")) //Directory; list direct contents:(Mimics normal getResourceAsStream("someFolder/") behaviour)
                                                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                                                    Enumeration<JarEntry> entries = jar.entries();
                                                    while(entries.hasMoreElements())
                                                    JarEntry entry = entries.nextElement();
                                                    if(entry.getName().startsWith(resource) && entry.getName().length() > resource.length())
                                                    String name = entry.getName().substring(resource.length());
                                                    if(name.contains("/") ? (name.endsWith("/") && (name.indexOf("/") == name.lastIndexOf("/"))) : true) //If it's a folder, we don't want the children's folders, only the parent folder's children!
                                                    name = name.endsWith("/") ? name.substring(0, name.length() - 1) : name;
                                                    baos.write(name.getBytes(StandardCharsets.UTF_8));
                                                    baos.write('r');
                                                    baos.write('n');



                                                    jar.close();
                                                    return new ByteArrayInputStream(baos.toByteArray());

                                                    JarEntry entry = jar.getJarEntry(resource);
                                                    InputStream in = entry != null ? jar.getInputStream(entry) : null;
                                                    if(in == null)
                                                    jar.close();
                                                    return in;

                                                    final InputStream stream = in;//Don't manage 'jar' with try-with-resources or close jar until the
                                                    return new InputStream() //returned stream is closed(closing the jar closes all associated InputStreams):
                                                    @Override
                                                    public int read() throws IOException
                                                    return stream.read();


                                                    @Override
                                                    public int read(byte b) throws IOException
                                                    return stream.read(b);


                                                    @Override
                                                    public int read(byte b, int off, int len) throws IOException
                                                    return stream.read(b, off, len);


                                                    @Override
                                                    public long skip(long n) throws IOException
                                                    return stream.skip(n);


                                                    @Override
                                                    public int available() throws IOException
                                                    return stream.available();


                                                    @Override
                                                    public void close() throws IOException
                                                    try
                                                    jar.close();
                                                    catch(IOException ignored)

                                                    stream.close();


                                                    @Override
                                                    public synchronized void mark(int readlimit)
                                                    stream.mark(readlimit);


                                                    @Override
                                                    public synchronized void reset() throws IOException
                                                    stream.reset();


                                                    @Override
                                                    public boolean markSupported()
                                                    return stream.markSupported();

                                                    ;
                                                    catch(Throwable e)
                                                    e.printStackTrace();
                                                    return null;


                                                    );



                                                    Note: The above code only seems to work correctly for jar files if it is in the main class. I'm not sure why.







                                                    share|improve this answer














                                                    share|improve this answer



                                                    share|improve this answer








                                                    edited Mar 21 '18 at 20:38

























                                                    answered Mar 21 '18 at 19:21









                                                    Brian_EnteiBrian_Entei

                                                    3131411




                                                    3131411





















                                                        0














                                                        I think this should be works in java as well. The following code I use is using kotlin.



                                                        val resource = Thread.currentThread().contextClassLoader.getResource('resources.txt')





                                                        share|improve this answer



























                                                          0














                                                          I think this should be works in java as well. The following code I use is using kotlin.



                                                          val resource = Thread.currentThread().contextClassLoader.getResource('resources.txt')





                                                          share|improve this answer

























                                                            0












                                                            0








                                                            0







                                                            I think this should be works in java as well. The following code I use is using kotlin.



                                                            val resource = Thread.currentThread().contextClassLoader.getResource('resources.txt')





                                                            share|improve this answer













                                                            I think this should be works in java as well. The following code I use is using kotlin.



                                                            val resource = Thread.currentThread().contextClassLoader.getResource('resources.txt')






                                                            share|improve this answer












                                                            share|improve this answer



                                                            share|improve this answer










                                                            answered Nov 14 '18 at 7:15









                                                            Irvi Firqotul AiniIrvi Firqotul Aini

                                                            11917




                                                            11917





















                                                                -1














                                                                You can use class loader which will read from classpath as ROOT path (without "/" in the beginning)



                                                                InputStream in = getClass().getClassLoader().getResourceAsStream("file.txt"); 
                                                                BufferedReader reader = new BufferedReader(new InputStreamReader(in));





                                                                share|improve this answer



























                                                                  -1














                                                                  You can use class loader which will read from classpath as ROOT path (without "/" in the beginning)



                                                                  InputStream in = getClass().getClassLoader().getResourceAsStream("file.txt"); 
                                                                  BufferedReader reader = new BufferedReader(new InputStreamReader(in));





                                                                  share|improve this answer

























                                                                    -1












                                                                    -1








                                                                    -1







                                                                    You can use class loader which will read from classpath as ROOT path (without "/" in the beginning)



                                                                    InputStream in = getClass().getClassLoader().getResourceAsStream("file.txt"); 
                                                                    BufferedReader reader = new BufferedReader(new InputStreamReader(in));





                                                                    share|improve this answer













                                                                    You can use class loader which will read from classpath as ROOT path (without "/" in the beginning)



                                                                    InputStream in = getClass().getClassLoader().getResourceAsStream("file.txt"); 
                                                                    BufferedReader reader = new BufferedReader(new InputStreamReader(in));






                                                                    share|improve this answer












                                                                    share|improve this answer



                                                                    share|improve this answer










                                                                    answered Sep 14 '18 at 6:57









                                                                    sendon1982sendon1982

                                                                    3,4141921




                                                                    3,4141921





















                                                                        -1














                                                                        If you are using spring, then you can use the the following method to read file from src/main/resources:



                                                                        import java.io.BufferedReader;
                                                                        import java.io.IOException;
                                                                        import java.io.InputStream;
                                                                        import java.io.InputStreamReader;
                                                                        import org.springframework.core.io.ClassPathResource;

                                                                        public String readFileToString(String path) throws IOException

                                                                        StringBuilder resultBuilder = new StringBuilder("");
                                                                        ClassPathResource resource = new ClassPathResource(path);

                                                                        try (
                                                                        InputStream inputStream = resource.getInputStream();
                                                                        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)))

                                                                        String line;

                                                                        while ((line = bufferedReader.readLine()) != null)
                                                                        resultBuilder.append(line);




                                                                        return resultBuilder.toString();






                                                                        share|improve this answer




















                                                                        • 1





                                                                          Welcome to SO. This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post. Also check this what can I do instead.

                                                                          – thewaywewere
                                                                          May 3 '17 at 15:36











                                                                        • Well, yes it does, even before my edit.

                                                                          – Tristan
                                                                          Nov 27 '18 at 12:37
















                                                                        -1














                                                                        If you are using spring, then you can use the the following method to read file from src/main/resources:



                                                                        import java.io.BufferedReader;
                                                                        import java.io.IOException;
                                                                        import java.io.InputStream;
                                                                        import java.io.InputStreamReader;
                                                                        import org.springframework.core.io.ClassPathResource;

                                                                        public String readFileToString(String path) throws IOException

                                                                        StringBuilder resultBuilder = new StringBuilder("");
                                                                        ClassPathResource resource = new ClassPathResource(path);

                                                                        try (
                                                                        InputStream inputStream = resource.getInputStream();
                                                                        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)))

                                                                        String line;

                                                                        while ((line = bufferedReader.readLine()) != null)
                                                                        resultBuilder.append(line);




                                                                        return resultBuilder.toString();






                                                                        share|improve this answer




















                                                                        • 1





                                                                          Welcome to SO. This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post. Also check this what can I do instead.

                                                                          – thewaywewere
                                                                          May 3 '17 at 15:36











                                                                        • Well, yes it does, even before my edit.

                                                                          – Tristan
                                                                          Nov 27 '18 at 12:37














                                                                        -1












                                                                        -1








                                                                        -1







                                                                        If you are using spring, then you can use the the following method to read file from src/main/resources:



                                                                        import java.io.BufferedReader;
                                                                        import java.io.IOException;
                                                                        import java.io.InputStream;
                                                                        import java.io.InputStreamReader;
                                                                        import org.springframework.core.io.ClassPathResource;

                                                                        public String readFileToString(String path) throws IOException

                                                                        StringBuilder resultBuilder = new StringBuilder("");
                                                                        ClassPathResource resource = new ClassPathResource(path);

                                                                        try (
                                                                        InputStream inputStream = resource.getInputStream();
                                                                        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)))

                                                                        String line;

                                                                        while ((line = bufferedReader.readLine()) != null)
                                                                        resultBuilder.append(line);




                                                                        return resultBuilder.toString();






                                                                        share|improve this answer















                                                                        If you are using spring, then you can use the the following method to read file from src/main/resources:



                                                                        import java.io.BufferedReader;
                                                                        import java.io.IOException;
                                                                        import java.io.InputStream;
                                                                        import java.io.InputStreamReader;
                                                                        import org.springframework.core.io.ClassPathResource;

                                                                        public String readFileToString(String path) throws IOException

                                                                        StringBuilder resultBuilder = new StringBuilder("");
                                                                        ClassPathResource resource = new ClassPathResource(path);

                                                                        try (
                                                                        InputStream inputStream = resource.getInputStream();
                                                                        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)))

                                                                        String line;

                                                                        while ((line = bufferedReader.readLine()) != null)
                                                                        resultBuilder.append(line);




                                                                        return resultBuilder.toString();







                                                                        share|improve this answer














                                                                        share|improve this answer



                                                                        share|improve this answer








                                                                        edited Nov 27 '18 at 12:39









                                                                        Tristan

                                                                        5,34222757




                                                                        5,34222757










                                                                        answered May 3 '17 at 14:53









                                                                        Sujan M.Sujan M.

                                                                        9




                                                                        9







                                                                        • 1





                                                                          Welcome to SO. This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post. Also check this what can I do instead.

                                                                          – thewaywewere
                                                                          May 3 '17 at 15:36











                                                                        • Well, yes it does, even before my edit.

                                                                          – Tristan
                                                                          Nov 27 '18 at 12:37













                                                                        • 1





                                                                          Welcome to SO. This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post. Also check this what can I do instead.

                                                                          – thewaywewere
                                                                          May 3 '17 at 15:36











                                                                        • Well, yes it does, even before my edit.

                                                                          – Tristan
                                                                          Nov 27 '18 at 12:37








                                                                        1




                                                                        1





                                                                        Welcome to SO. This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post. Also check this what can I do instead.

                                                                        – thewaywewere
                                                                        May 3 '17 at 15:36





                                                                        Welcome to SO. This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post. Also check this what can I do instead.

                                                                        – thewaywewere
                                                                        May 3 '17 at 15:36













                                                                        Well, yes it does, even before my edit.

                                                                        – Tristan
                                                                        Nov 27 '18 at 12:37






                                                                        Well, yes it does, even before my edit.

                                                                        – Tristan
                                                                        Nov 27 '18 at 12:37


















                                                                        draft saved

                                                                        draft discarded
















































                                                                        Thanks for contributing an answer to Stack Overflow!


                                                                        • Please be sure to answer the question. Provide details and share your research!

                                                                        But avoid


                                                                        • Asking for help, clarification, or responding to other answers.

                                                                        • Making statements based on opinion; back them up with references or personal experience.

                                                                        To learn more, see our tips on writing great answers.




                                                                        draft saved


                                                                        draft discarded














                                                                        StackExchange.ready(
                                                                        function ()
                                                                        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f20389255%2freading-a-resource-file-from-within-jar%23new-answer', 'question_page');

                                                                        );

                                                                        Post as a guest















                                                                        Required, but never shown





















































                                                                        Required, but never shown














                                                                        Required, but never shown












                                                                        Required, but never shown







                                                                        Required, but never shown

































                                                                        Required, but never shown














                                                                        Required, but never shown












                                                                        Required, but never shown







                                                                        Required, but never shown







                                                                        Popular posts from this blog

                                                                        Top Tejano songwriter Luis Silva dead of heart attack at 64

                                                                        政党

                                                                        天津地下鉄3号線