Add docx file in resources and create executable jar - java

I want to add
docx files in resources folder, use those files in code written in class located at another package of same application.
And then I want to make an executable jar out of it which will be working on windows.
I read its not easy to make such jar :( and there is no fool prroof way...
I have tried searching for it on net and found I will have to create URL and then file and then use it...
however, when I use below code, I am not able to get URL itself...
URL urlOfDraftInSamePackage = CreateDraft.class.getResource("Draft_in_same_package.docx");
System.out.println("urlOfDraftInSamePackage is "+urlOfDraftInSamePackage.toString());
//This prints : urlOfDraftInSamePackage is file:/D:/aditya_workspace/SampleDraftMaker/bin/draftProcessing/Draft_in_same_package.docx
URL urlOfDraftInResourceFolder = CreateDraft.class.getResource("resouces/Draft_Apartment.docx");
System.out.println("urlOfDraftInResourceFolder is "+urlOfDraftInResourceFolder.toString());
//this gives null pointer exception
URI uri = null;
try {
uri = urlOfDraftInSamePackage.toURI();
File file = new File(uri);
System.out.println("file made");
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
below is my folder structure:
can anyone pls help me in creating such executable jar using eclipse?
Thanks In Advance!!!

Following code works for me:
public static void testResource() throws IOException {
InputStream stream = Deserializace.class.getResourceAsStream("resources/ser.log");
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
String s;
while ( (s = reader.readLine()) != null) {
System.out.println(s);
}
}
Build directory structure:
Test.class
resources/ser.log
You must ensure that your resource directory is copied to correct place.

Related

Access src/main/resources/ dynamically from source code

My files are located under projectRoot/src/main/resources/levels/
If I call Utils.getFileNamesInDirectory("src/main/resources/levels"), it works.
But when project is packaged, levels directory is placed under root of .jar.
How can I made this dynamic in static class? i.e src/main/resources/
So that code will run within eclipse and as standalone jar.
Code to list files in directory ..
public class Utils {
public static List<String> getFileNamesInDirectory(String directory){
List<String> results = new ArrayList<String>();
File[] files = new File(directory).listFiles(new FilenameFilter() {
public boolean accept(File dir, String filename) {
return filename.endsWith(".json");
}
});
for (File file : files) {
if (file.isFile()) {
results.add(file.getName());
}
}
Collections.sort(results);
return results;
}
}
Updated
I've moved to using getResourceAsStream (as getResource was causing IllegalArgumentException: URI is not hierarchical) and I'm able to list files in a directory within Eclipse.
public static List<String> getFileNamesInDirectory(String directory){
List<String> results = new ArrayList<String>();
InputStream in = Utils.class.getResourceAsStream("/" + directory);
BufferedReader rdr = new BufferedReader(new InputStreamReader(in));
String line;
try {
while ((line = rdr.readLine()) != null) {
System.out.println("file: " + line);
results.add(new File(line).getName());
}
rdr.close();
} catch (IOException e1) {
e1.printStackTrace();
}
Collections.sort(results);
return results;
}
But when I run it as standalone .jar I get the following error on this line: while ((line = rdr.readLine()) != null) {
Why does it not work outside Eclipse?
Exception in thread "main" java.lang.NullPointerException
at java.io.FilterInputStream.read(FilterInputStream.java:133)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:322)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:364)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:210)
at java.io.InputStreamReader.read(InputStreamReader.java:205)
at java.io.BufferedReader.fill(BufferedReader.java:165)
at java.io.BufferedReader.readLine(BufferedReader.java:328)
at java.io.BufferedReader.readLine(BufferedReader.java:393)
at com.app.tools.Utils.getFileNamesInDirectory(Utils.java:31)
The reason your code works in Eclipse is that Eclipse launches the java process from the project directory and we can assume the path provided in
Utils.getFileNamesInDirectory("src/main/resources/levels")
is relative to the current working directory (the project directory). Since the file system location <project-directory>/src/main/resources/levels exists, it can be found and returned to you.
src/main/resources is a Maven convention meant to hold resources that will eventually end up in the classpath when the project is compiled/built/deployed. To retrieve resources from the classpath you use Class#getResource(String), ClassLoader#getResource(String) and/or ClassLoader#getSystemResource(String).
Now, although there are ways to list resources in the classpath, you should not typically do this. If you need a resource, you know it by name and can therefore use one of the methods listed above to get it.

Opening a PDF file that is packaged in a JAR

I am trying to open a PDF file that is packaged into the jar file during runtime. The basic idea is that the user clicks the help option and then it displays a help file that is a PDF. Right now I have this in LineFit.class in the linefit package to try and open the help PDF:
try {
File test = new File(LineFit.class.getClass().getResource("/linefit/helpTest.pdf").toURI());
try {
Desktop.getDesktop().open(test);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
} catch (URISyntaxException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
It works in eclipse when I run it but if I try to export it to a runnable JAR file it does not open the PDF file and when I look into the JAR, the PDF is in the same folder as when it was in eclipse.
new File(URI) only works for file: URIs. When a classloader finds a resource in a jar, it returns a jar URI, for example jar:file:/C:/Program%20Files/test.jar!/foo/bar.
Fundamentally, the File class is for files on the filesystem. You can't use it to represent a file within a JAR or another archive. You're going to have to copy the file out of the jar and into a regular file, then create a File referencing this new file. To read the file from the jar, you could use JarURLConnection.getInputStream with the URL you have, or you could call ClassLoader.getResourceAsStream.
Try this:
Make sure the path of pdf file is relative path when you use MethodHandles.lookup().lookupClass().getClassLoader()
InputStream is = MethodHandles.lookup().lookupClass().getClassLoader().getResourceAsStream("doc/example.pdf");
BufferedReader br = new BufferedReader(new InputStreamReader(is));
while ((thisLine = br.readLine()) != null) {
System.out.println(thisLine);
}

unable to read file using getResourceAsStream

I have a folder structure like
Project
src
--TestMain.java
bin
--TestMain.class
resources
--test.txt
As the whole project will be packaged into a jar file, I have to read a file from resources using getResourceAsStream. Although I have read through all questions about getResourceAsStream, I still can't get this working. Could anyone help? Thank you!
public class TestMain {
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
InputStream stream = TestMain.class.getResourceAsStream("\resources\test.txt");
System.out.println(stream);
BufferedReader bufRead = new BufferedReader(new InputStreamReader(stream));
StringBuilder builder = new StringBuilder();
String line=null;
while((line=bufRead.readLine())!=null){
builder.append(line).append("\n");
}
System.out.println(builder.toString());
}
}
Basically, there are 2 different methods: ClassLoader.getResourceAsStream() and Class.getResourceAsStream(). These two methods will locate the resource differently.
In Class.getResourceAsStream(path), the path is interpreted as a path local to the package of the class you are calling it from. For example calling, String.getResourceAsStream("file.txt") will look for a file in your classpath at the following location: "java/lang/file.txt". If your path starts with a /, then it will be considered an absolute path, and will start searching from the root of the classpath. So calling String.getResourceAsStream("/myfile.txt") will look at the following location in your class path ./file.txt.
ClassLoader.getResourceAsStream(path) will consider all paths to be absolute paths. So calling String.getClassLoader().getResourceAsString("myfile.txt") and String.getClassLoader().getResourceAsString("/file.txt") will both look for a file in your classpath at the following location: ./file.txt.
Every time the location, it could be a location in your filesystem itself, or inside the corresponding jar file, depending on the Class and/or ClassLoader you are loading the resource from.
IF you are loading the class from an Application Server, so your should use Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName) instead of this.getClass().getClassLoader().getResourceAsStream(fileName). this.getClass().getResourceAsStream() will also work.
It seems the folder 'resources' is in your classpath, it is not need while getting resources under it,try below
InputStream stream = TestMain.class.getResourceAsStream("test.txt");
Is your test.txt in your classpath? I think that your test.txt is not inside your classpath.
you have many solutions for to do that.
one could be give the fullpath of your file (c:/......)
verify when you generate .jar file your txt is inside .jar. if not include your resource folder inside your java project. when you include made a path directly for
getResourceAsStream ("test.txt")
For disacoplated resource of your java project use a first option but if it not make sense use the second option .
Assume that you are using a httpclient:
HttpClient httpClient = new HttpClient();
httpClient.getHostConfiguration().setProxy(proxyHost, proxyPort);//your proxyHost & your proxyPort,
GetMethod getMethod = new GetMethod(url);//your url,
try {
httpClient.executeMethod(getMethod);
//strData = getMethod.getResponseBodyAsString();
InputStream resStream = getMethod.getResponseBodyAsStream();
BufferedReader br = new BufferedReader(new InputStreamReader(resStream));
StringBuffer resBuffer = new StringBuffer();
String resTemp = "";
while((resTemp = br.readLine()) != null){
resBuffer.append(resTemp);
}
String response = resBuffer.toString();
} catch (Exception e) {
System.out.println("HttpProxyManager.getResponse returns NULL");
e.printStackTrace();
} finally {
getMethod.releaseConnection();
}
the string response should be what you want to get.

How can I access a folder inside of a resource folder from inside my jar File?

I have a resources folder/package in the root of my project, I "don't" want to load a certain File. If I wanted to load a certain File, I would use class.getResourceAsStream and I would be fine!! What I actually want to do is to load a "Folder" within the resources folder, loop on the Files inside that Folder and get a Stream to each file and read in the content... Assume that the File names are not determined before runtime... What should I do? Is there a way to get a list of the files inside a Folder in your jar File?
Notice that the Jar file with the resources is the same jar file from which the code is being run...
Finally, I found the solution:
final String path = "sample/folder";
final File jarFile = new File(getClass().getProtectionDomain().getCodeSource().getLocation().getPath());
if(jarFile.isFile()) { // Run with JAR file
final JarFile jar = new JarFile(jarFile);
final Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar
while(entries.hasMoreElements()) {
final String name = entries.nextElement().getName();
if (name.startsWith(path + "/")) { //filter according to the path
System.out.println(name);
}
}
jar.close();
} else { // Run with IDE
final URL url = Launcher.class.getResource("/" + path);
if (url != null) {
try {
final File apps = new File(url.toURI());
for (File app : apps.listFiles()) {
System.out.println(app);
}
} catch (URISyntaxException ex) {
// never happens
}
}
}
The second block just work when you run the application on IDE (not with jar file), You can remove it if you don't like that.
Try the following.
Make the resource path "<PathRelativeToThisClassFile>/<ResourceDirectory>" E.g. if your class path is com.abc.package.MyClass and your resoure files are within src/com/abc/package/resources/:
URL url = MyClass.class.getResource("resources/");
if (url == null) {
// error - missing folder
} else {
File dir = new File(url.toURI());
for (File nextFile : dir.listFiles()) {
// Do something with nextFile
}
}
You can also use
URL url = MyClass.class.getResource("/com/abc/package/resources/");
The following code returns the wanted "folder" as Path regardless of if it is inside a jar or not.
private Path getFolderPath() throws URISyntaxException, IOException {
URI uri = getClass().getClassLoader().getResource("folder").toURI();
if ("jar".equals(uri.getScheme())) {
FileSystem fileSystem = FileSystems.newFileSystem(uri, Collections.emptyMap(), null);
return fileSystem.getPath("path/to/folder/inside/jar");
} else {
return Paths.get(uri);
}
}
Requires java 7+.
I know this is many years ago . But just for other people come across this topic.
What you could do is to use getResourceAsStream() method with the directory path, and the input Stream will have all the files name from that dir. After that you can concat the dir path with each file name and call getResourceAsStream for each file in a loop.
I had the same problem at hands while i was attempting to load some hadoop configurations from resources packed in the jar... on both the IDE and on jar (release version).
I found java.nio.file.DirectoryStream to work the best to iterate over directory contents over both local filesystem and jar.
String fooFolder = "/foo/folder";
....
ClassLoader classLoader = foofClass.class.getClassLoader();
try {
uri = classLoader.getResource(fooFolder).toURI();
} catch (URISyntaxException e) {
throw new FooException(e.getMessage());
} catch (NullPointerException e){
throw new FooException(e.getMessage());
}
if(uri == null){
throw new FooException("something is wrong directory or files missing");
}
/** i want to know if i am inside the jar or working on the IDE*/
if(uri.getScheme().contains("jar")){
/** jar case */
try{
URL jar = FooClass.class.getProtectionDomain().getCodeSource().getLocation();
//jar.toString() begins with file:
//i want to trim it out...
Path jarFile = Paths.get(jar.toString().substring("file:".length()));
FileSystem fs = FileSystems.newFileSystem(jarFile, null);
DirectoryStream<Path> directoryStream = Files.newDirectoryStream(fs.getPath(fooFolder));
for(Path p: directoryStream){
InputStream is = FooClass.class.getResourceAsStream(p.toString()) ;
performFooOverInputStream(is);
/** your logic here **/
}
}catch(IOException e) {
throw new FooException(e.getMessage());
}
}
else{
/** IDE case */
Path path = Paths.get(uri);
try {
DirectoryStream<Path> directoryStream = Files.newDirectoryStream(path);
for(Path p : directoryStream){
InputStream is = new FileInputStream(p.toFile());
performFooOverInputStream(is);
}
} catch (IOException _e) {
throw new FooException(_e.getMessage());
}
}
Another solution, you can do it using ResourceLoader like this:
import org.springframework.core.io.Resource;
import org.apache.commons.io.FileUtils;
#Autowire
private ResourceLoader resourceLoader;
...
Resource resource = resourceLoader.getResource("classpath:/path/to/you/dir");
File file = resource.getFile();
Iterator<File> fi = FileUtils.iterateFiles(file, null, true);
while(fi.hasNext()) {
load(fi.next())
}
If you are using Spring you can use org.springframework.core.io.support.PathMatchingResourcePatternResolver and deal with Resource objects rather than files. This works when running inside and outside of a Jar file.
PathMatchingResourcePatternResolver r = new PathMatchingResourcePatternResolver();
Resource[] resources = r.getResources("/myfolder/*");
Then you can access the data using getInputStream and the filename from getFilename.
Note that it will still fail if you try to use the getFile while running from a Jar.
As the other answers point out, once the resources are inside a jar file, things get really ugly. In our case, this solution:
https://stackoverflow.com/a/13227570/516188
works very well in the tests (since when the tests are run the code is not packed in a jar file), but doesn't work when the app actually runs normally. So what I've done is... I hardcode the list of the files in the app, but I have a test which reads the actual list from disk (can do it since that works in tests) and fails if the actual list doesn't match with the list the app returns.
That way I have simple code in my app (no tricks), and I'm sure I didn't forget to add a new entry in the list thanks to the test.
Below code gets .yaml files from a custom resource directory.
ClassLoader classLoader = this.getClass().getClassLoader();
URI uri = classLoader.getResource(directoryPath).toURI();
if("jar".equalsIgnoreCase(uri.getScheme())){
Pattern pattern = Pattern.compile("^.+" +"/classes/" + directoryPath + "/.+.yaml$");
log.debug("pattern {} ", pattern.pattern());
ApplicationHome home = new ApplicationHome(SomeApplication.class);
JarFile file = new JarFile(home.getSource());
Enumeration<JarEntry> jarEntries = file.entries() ;
while(jarEntries.hasMoreElements()){
JarEntry entry = jarEntries.nextElement();
Matcher matcher = pattern.matcher(entry.getName());
if(matcher.find()){
InputStream in =
file.getInputStream(entry);
//work on the stream
}
}
}else{
//When Spring boot application executed through Non-Jar strategy like through IDE or as a War.
String path = uri.getPath();
File[] files = new File(path).listFiles();
for(File file: files){
if(file != null){
try {
InputStream is = new FileInputStream(file);
//work on stream
} catch (Exception e) {
log.error("Exception while parsing file yaml file {} : {} " , file.getAbsolutePath(), e.getMessage());
}
}else{
log.warn("File Object is null while parsing yaml file");
}
}
}
Took me 2-3 days to get this working, in order to have the same url that work for both Jar or in local, the url (or path) needs to be a relative path from the repository root.
..meaning, the location of your file or folder from your src folder.
could be "/main/resources/your-folder/" or "/client/notes/somefile.md"
Whatever it is, in order for your JAR file to find it, the url must be a relative path from the repository root.
it must be "src/main/resources/your-folder/" or "src/client/notes/somefile.md"
Now you get the drill, and luckily for Intellij Idea users, you can get the correct path with a right-click on the folder or file -> copy Path/Reference.. -> Path From Repository Root (this is it)
Last, paste it and do your thing.
Simple ... use OSGi. In OSGi you can iterate over your Bundle's entries with findEntries and findPaths.
Inside my jar file I had a folder called Upload, this folder had three other text files inside it and I needed to have an exactly the same folder and files outside of the jar file, I used the code below:
URL inputUrl = getClass().getResource("/upload/blabla1.txt");
File dest1 = new File("upload/blabla1.txt");
FileUtils.copyURLToFile(inputUrl, dest1);
URL inputUrl2 = getClass().getResource("/upload/blabla2.txt");
File dest2 = new File("upload/blabla2.txt");
FileUtils.copyURLToFile(inputUrl2, dest2);
URL inputUrl3 = getClass().getResource("/upload/blabla3.txt");
File dest3 = new File("upload/Bblabla3.txt");
FileUtils.copyURLToFile(inputUrl3, dest3);

How to get a path to a resource in a Java JAR file

I am trying to get a path to a Resource but I have had no luck.
This works (both in IDE and with the JAR) but this way I can't get a path to a file, only the file contents:
ClassLoader classLoader = getClass().getClassLoader();
PrintInputStream(classLoader.getResourceAsStream("config/netclient.p"));
If I do this:
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("config/netclient.p").getFile());
The result is:
java.io.FileNotFoundException: file:/path/to/jarfile/bot.jar!/config/netclient.p (No such file or directory)
Is there a way to get a path to a resource file?
This is deliberate. The contents of the "file" may not be available as a file. Remember you are dealing with classes and resources that may be part of a JAR file or other kind of resource. The classloader does not have to provide a file handle to the resource, for example the jar file may not have been expanded into individual files in the file system.
Anything you can do by getting a java.io.File could be done by copying the stream out into a temporary file and doing the same, if a java.io.File is absolutely necessary.
When loading a resource make sure you notice the difference between:
getClass().getClassLoader().getResource("com/myorg/foo.jpg") //relative path
and
getClass().getResource("/com/myorg/foo.jpg")); //note the slash at the beginning
I guess, this confusion is causing most of problems when loading a resource.
Also, when you're loading an image it's easier to use getResourceAsStream():
BufferedImage image = ImageIO.read(getClass().getResourceAsStream("/com/myorg/foo.jpg"));
When you really have to load a (non-image) file from a JAR archive, you might try this:
File file = null;
String resource = "/com/myorg/foo.xml";
URL res = getClass().getResource(resource);
if (res.getProtocol().equals("jar")) {
try {
InputStream input = getClass().getResourceAsStream(resource);
file = File.createTempFile("tempfile", ".tmp");
OutputStream out = new FileOutputStream(file);
int read;
byte[] bytes = new byte[1024];
while ((read = input.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.close();
file.deleteOnExit();
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
} else {
//this will probably work in your IDE, but not from a JAR
file = new File(res.getFile());
}
if (file != null && !file.exists()) {
throw new RuntimeException("Error: File " + file + " not found!");
}
The one line answer is -
String path = this.getClass().getClassLoader().getResource(<resourceFileName>).toExternalForm()
Basically getResource method gives the URL. From this URL you can extract the path by calling toExternalForm().
I spent a while messing around with this problem, because no solution I found actually worked, strangely enough! The working directory is frequently not the directory of the JAR, especially if a JAR (or any program, for that matter) is run from the Start Menu under Windows. So here is what I did, and it works for .class files run from outside a JAR just as well as it works for a JAR. (I only tested it under Windows 7.)
try {
//Attempt to get the path of the actual JAR file, because the working directory is frequently not where the file is.
//Example: file:/D:/all/Java/TitanWaterworks/TitanWaterworks-en.jar!/TitanWaterworks.class
//Another example: /D:/all/Java/TitanWaterworks/TitanWaterworks.class
PROGRAM_DIRECTORY = getClass().getClassLoader().getResource("TitanWaterworks.class").getPath(); // Gets the path of the class or jar.
//Find the last ! and cut it off at that location. If this isn't being run from a jar, there is no !, so it'll cause an exception, which is fine.
try {
PROGRAM_DIRECTORY = PROGRAM_DIRECTORY.substring(0, PROGRAM_DIRECTORY.lastIndexOf('!'));
} catch (Exception e) { }
//Find the last / and cut it off at that location.
PROGRAM_DIRECTORY = PROGRAM_DIRECTORY.substring(0, PROGRAM_DIRECTORY.lastIndexOf('/') + 1);
//If it starts with /, cut it off.
if (PROGRAM_DIRECTORY.startsWith("/")) PROGRAM_DIRECTORY = PROGRAM_DIRECTORY.substring(1, PROGRAM_DIRECTORY.length());
//If it starts with file:/, cut that off, too.
if (PROGRAM_DIRECTORY.startsWith("file:/")) PROGRAM_DIRECTORY = PROGRAM_DIRECTORY.substring(6, PROGRAM_DIRECTORY.length());
} catch (Exception e) {
PROGRAM_DIRECTORY = ""; //Current working directory instead.
}
This is same code from user Tombart with stream flush and close to avoid incomplete temporary file content copy from jar resource and to have unique temp file names.
File file = null;
String resource = "/view/Trial_main.html" ;
URL res = getClass().getResource(resource);
if (res.toString().startsWith("jar:")) {
try {
InputStream input = getClass().getResourceAsStream(resource);
file = File.createTempFile(new Date().getTime()+"", ".html");
OutputStream out = new FileOutputStream(file);
int read;
byte[] bytes = new byte[1024];
while ((read = input.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.flush();
out.close();
input.close();
file.deleteOnExit();
} catch (IOException ex) {
ex.printStackTrace();
}
} else {
//this will probably work in your IDE, but not from a JAR
file = new File(res.getFile());
}
if netclient.p is inside a JAR file, it won't have a path because that file is located inside other file. in that case, the best path you can have is really file:/path/to/jarfile/bot.jar!/config/netclient.p.
You need to understand the path within the jar file.
Simply refer to it relative. So if you have a file (myfile.txt), located in foo.jar under the \src\main\resources directory (maven style). You would refer to it like:
src/main/resources/myfile.txt
If you dump your jar using jar -tvf myjar.jar you will see the output and the relative path within the jar file, and use the FORWARD SLASHES.
In my case, I have used a URL object instead Path.
File
File file = new File("my_path");
URL url = file.toURI().toURL();
Resource in classpath using classloader
URL url = MyClass.class.getClassLoader().getResource("resource_name")
When I need to read the content, I can use the following code:
InputStream stream = url.openStream();
And you can access the content using an InputStream.
follow code!
/src/main/resources/file
streamToFile(getClass().getClassLoader().getResourceAsStream("file"))
public static File streamToFile(InputStream in) {
if (in == null) {
return null;
}
try {
File f = File.createTempFile(String.valueOf(in.hashCode()), ".tmp");
f.deleteOnExit();
FileOutputStream out = new FileOutputStream(f);
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
return f;
} catch (IOException e) {
LOGGER.error(e.getMessage(), e);
return null;
}
}
A File is an abstraction for a file in a filesystem, and the filesystems don't know anything about what are the contents of a JAR.
Try with an URI, I think there's a jar:// protocol that might be useful for your purpouses.
The following path worked for me: classpath:/path/to/resource/in/jar
private static final String FILE_LOCATION = "com/input/file/somefile.txt";
//Method Body
InputStream invalidCharacterInputStream = URLClassLoader.getSystemResourceAsStream(FILE_LOCATION);
Getting this from getSystemResourceAsStream is the best option. By getting the inputstream rather than the file or the URL, works in a JAR file and as stand alone.
It may be a little late but you may use my library KResourceLoader to get a resource from your jar:
File resource = getResource("file.txt")
Inside your ressources folder (java/main/resources) of your jar add your file (we assume that you have added an xml file named imports.xml), after that you inject ResourceLoader if you use spring like bellow
#Autowired
private ResourceLoader resourceLoader;
inside tour function write the bellow code in order to load file:
Resource resource = resourceLoader.getResource("classpath:imports.xml");
try{
File file;
file = resource.getFile();//will load the file
...
}catch(IOException e){e.printStackTrace();}
Maybe this method can be used for quick solution.
public class TestUtility
{
public static File getInternalResource(String relativePath)
{
File resourceFile = null;
URL location = TestUtility.class.getProtectionDomain().getCodeSource().getLocation();
String codeLocation = location.toString();
try{
if (codeLocation.endsWith(".jar"){
//Call from jar
Path path = Paths.get(location.toURI()).resolve("../classes/" + relativePath).normalize();
resourceFile = path.toFile();
}else{
//Call from IDE
resourceFile = new File(TestUtility.class.getClassLoader().getResource(relativePath).getPath());
}
}catch(URISyntaxException ex){
ex.printStackTrace();
}
return resourceFile;
}
}
When in a jar file, the resource is located absolutely in the package hierarchy (not file system hierarchy). So if you have class com.example.Sweet loading a resource named ./default.conf then the resource's name is specified as /com/example/default.conf.
But if it's in a jar then it's not a File ...
This Class function can get absolute file path by relative file path in .jar file.
public class Utility {
public static void main(String[] args) throws Exception {
Utility utility = new Utility();
String absolutePath = utility.getAbsolutePath("./absolute/path/to/file");
}
public String getAbsolutePath(String relativeFilePath) throws IOException {
URL url = this.getClass().getResource(relativeFilePath);
return url.getPath();
}
}
If target file is same directory with Utility.java, your input will be ./file.txt.
When you input only / on getAbsolutePath(), it returns /Users/user/PROJECT_NAME/target/classes/. This means you can select the file like this /com/example/file.txt.

Categories

Resources