Let's say I have a structure
-bin/com/abc/A.class
-src/com/abc/A.java
-config/info.txt
How to address the file info.txt from A class?
Should we use "user.dir" property or "config/info.txt" so that it would work ?
I'll compile this into the jar and after that
the jar will be used from the servlet,
but I don't think that's important
cause this file is written and read from
internal jar's methods only.
Just put it in the runtime classpath and use ClassLoader#getResourceAsStream() to get an InputStream of it. Putting it in the JAR file among the classes, or adding its (JAR-relative) path to the Class-Path entry of the JAR's manifest.mf file is more than sufficient.
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("config/info.txt");
// Do your thing to read it.
Or if you actually want to get it in flavor of a java.io.File, then make use of ClassLoader#getResource(), URL#toURI() and the File constructor taking an URI:
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
URL url = classLoader.getResource("config/info.txt");
File file = new File(url.toURI());
// Do your thing with it.
Do not use relative paths in java.io stuff. It would be dependent on the current working directory which you have no control over at any way. It's simply receipt for portability trouble. Just make use of the classpath.
That said, are you aware of the java.util.Properties API? It namely look like you're trying to achieve the same thing which is more easy to be done with propertiesfiles.
Related
i have following line
File file = ResourceUtils.getFile("classpath:calculation.csv");
and i also tried
File file = ResourceUtils.getFile("classpath:/calculation.csv");
but both will throw an error
java.io.FileNotFoundException: class path resource [calculation.csv] cannot be resolved to absolute file path because it does not exist
but i do have calculation.csv in by resources folder..
why is this?
I need to read file from resources folder, and it should also work in server enviroment
EDIT:
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("calculation.csv").getFile());
works just as fine, so not at all..
EDIT2:
tried with folder.. i have both calculation.csv and csv/calculation.csv in my resources folder now..
none of the above work, with /csv/ added.
what kind of path does this thing want?!
EDIT3:
aaand
File file = new ClassPathResource("calculation.csv").getFile();
is also no go, what even is this..
Loading file (as FILE) wont work. You must use it as resource. Files inside JAR will not work as file anyway. This is also what your "check" code shows.
classLoader.getResource("calculation.csv") works, because you are using classloader to get resource, not filesystem to get file (which is what File api does). It could work, if you would deal with non packed application. Once you pack your app into JAR, file path will be like your/path/to/jar.jar!someResource - note ! mark (and that is what you would see as well). So basicly it will return File instance, you that you wont be able to use anyway, as file system has no access to it.
You could alternatively try to extract it first with ResourceUtiuls#extractJarFileURL(URL jarUrl) and then use extracted file.
I think, that in most cases Class#getResourceAsStream is the way to go and I think that it should fit your needs as well to read content of resource.
I have a maven project with these standard directory structures:
src/main/java
src/main/java/pdf/Pdf.java
src/test/resources
src/test/resources/files/x.pdf
In my Pdf.java,
File file = new File("../../../test/resources/files/x.pdf");
Why does it report "No such file or dirctory"? The relative path should work. Right?
Relative paths work relative to the current working directory. Maven does not set it, so it is inherited from whatever value it had in the Java process your code is executing in.
The only reliable way is to figure it out in your own code. Depending on how you do things, there are several ways to do so. See How to get the real path of Java application at runtime? for suggestions. You are most likely looking at this.getClass().getProtectionDomain().getCodeSource().getLocation() and then you know where the class file is and can navigate relative to that.
Why does it report "No such file or dirctory"? The relative path should work. Right?
wrong.
Your classes are compiled to $PROJECT_ROOT/target/classes
and your resources are copied to the same folder keeping their relative paths below src/main/resources.
The file will be located relative to the classpath of which the root is $PROJECT_ROOT/target/classes. Therefore you have to write in your Pdf.java:
File file = new File("/files/x.pdf");
Your relative path will be evaluated from the projects current working directory which is $PROJECT_ROOT (AFAIR).
But it does not matter because you want that to work in your final application and not only in your build environment. Therefore you should access the file with getClass().getResource("/path/to/file/within/classpath") which searches the file in the class path of which the root is $PROJECT_ROOT/target/classes.
No the way you are referencing the files is according to your file system. Java knows about the classpath not the file system if you want to reference something like that you have to use the fully qualified name of the file.
Also I do not know if File constructor works with the classpath since it's an abstraction to manage the file system it will depend where the application is run from. Say it is run from the target directory at the same level as source in that case you have to go one directory up and then on src then test the resources the files and finally in x.pdf.
Since you are using a resources folder I think you want the file to be on the classpath and then you can load a resource with:
InputStream in = this.getClass().getClassLoader()
.getResourceAsStream("<path in classpath>");
Then you can create a FileInputStream or something to wrap around the file. Otherwise use the fully qualiefied name and put it somewere like /home/{user}/files/x.pdf.
I've created a file inside a project package using this code:
File xmlFile = new File("src/com/company/project/xml/tags.xml");
I am able to read the file while running from eclipse. However, after creating .jar, I'm unable to read the file. So I want to put absolute path while reading the file from the project package. How it can be done? Help and suggestions are appreciated.
In most cases, IDE's will include no Java files in the resulting Jar. Most IDE's will also include the src directory in the classpath when you run/debug the program from within them.
As a general rule of thumb, never include src in any path, src will simply not exist once the program is built.
Instead you need to make use of Class#getResource or Class#getResourceAsStream, depending on your needs. You should remember, you should never treat an "embedded" resource as a File, as in most cases it won't be, it'll be a stream of bytes in a zip file.
Something like...
URL xmlFile = getClass().getResource("/com/company/project/xml/tags.xml");
will return a URL reference to the resource. Remember, if you need a InputStream, you'll have to Class#getResourceAsStream.
If you want the resource to be writable, then you will need to find a different location to store it, as embedded resources are read only
Try with getClass().getResource()
new File(getClass().getResource("src/com/company/project/xml/tags.xml").toURI());
Say I have an exported Jar file on my Desktop, and then a folder I want to access so my jar file can load files from it. How can I access that folder without hard coding the path?
See here: https://stackoverflow.com/a/6849255/514463
Pick one of your classes that you want the directory of, e.g.: Test:
String path = Test.class.getProtectionDomain().getCodeSource().getLocation().getPath();
String decodedPath = URLDecoder.decode(path, "UTF-8");
If I clearly understand, you may use relative path when you try to access folder. For example, if you run your jar as a standalone application, relative path "." will be a folder that contains your jar. So, when you place names.txt file next to your jar, you can get access to it with:
new File("./names.txt");
Hope I understood you right way and this will help.
The following code should provide the directory containing the JAR file:
URL url = getClass().getProtectionDomain().getCodeSource().getLocation();
File directory = new File(url.toURI()).getParentFile();
Hmmm...
I heard this question so often, and it always boils down to this: How to load resources at runtime?
The main reason for this type of question is, that one is developping an application and now wants to create a distributable package. This normally ends in something like that:
... / my-application-folder
| -- lib / *.jar
| -- main.jar
| -- config.properties
There could be several configuration files. A configuration for the application itself, a configuration for a logging framework that is used, etc. It does not matter. If you want to access such resources, you should do it in two steps:
1) Make sure all folders containing your resources (such configuration files are resources) are part of the classpath. If you run your JAR file (here main.jar) with a java -jar main.jar command, this JAR file should contain a manifest file containing the directory . and all needed library JARs in the class-path entry. [Alternative: Maybe all your config files are located in a config/ subfolder. Then this folder must be part of the class-path.]
2) Inside your application you access such resources with a class loader:
ClassLoader loader = Thread.currentThread().getContextClassLoader();
URL url = loader.getResource(neededResource);
// do something with url, e.g. open stream, read from it, and close stream
If you have a user customizable path, there are several possibilities. You could for example pass a system property to the application, as Reddy suggested in his comment. You could also have a property in a configuration file, which you are loading in the beginning part of your application. However, you have the path to this customizable folder in hand (at runtime). Then you do the following:
String customizablePath = getCustomizablePath();
URL customizablePathURL = new File(customizablePath).toURI().toURL();
ClassLoader loader = new URLClassLoader(new URL[] {customizablePathURL});
Then you can continue like above.
File f = new File("Folder")
This File object points to "Folder" directory in the the working directory of the Jar.
This question is asked in numerous places, with myriad small variations. (Such as Java - getClassLoader().getResource() driving me bonkers among others.) I still can't make it work.
Here's a code snippet:
String clipName = "Chook.wav";
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
// URL url = classLoader.getResource(clipName);
URL url = new URL("file:///Users/chap/Documents/workspace/the1620/bin/ibm1620/" + clipName);
ais = AudioSystem.getAudioInputStream(url);
This works -- note that I've hard-coded the path to the directory containing the clip file, which is there, and is in the same directory as my .class file. Alas, the commented-out code just returns a null value for url.
Most other posts seem to deal with getResourceAsStream(). I think I'm supposed to be using getResource(). Is that making the difference?
It just can't be this hard. Any clues?
String clipName = "Chook.wav";
When using getResource, the string you pass in must be either an absolute name or be valid relative to a certain class. Since you're using ClassLoader.getResource() and not Class.getResource(), it must be an absolute path.
Without seeing your actual file hierarchy, I can only guess that "bin" is the root of your compiled classes and resources, and "ibm1260" is a package/folder within that path, and "Chook.wav" exists in that folder. If that's the case, then you need to use /ibm1260/Chook.wav (or potentially ibm1260/Chook.wav, I don't typically use the class loader for resource lookups) as the name of the file that you pass in to getResource().
Either way, you need to make sure that the file is copied into the location of your compiled code and that the root folder is on the classpath.
The getResource and getResourceAsStream methods are for accessing resources on the classpath. You seem to be trying to access some resource that is not on the classpath.
The logic that getResource and getResourceAsStream use to locate resources is essentially the same. The difference between the methods is that one returns a URL, and the other an InputStream.
It just can't be this hard. Any clues?
This is not that hard at all. You just need to understand how classpaths work ... and make sure that you use a resource name that resolves to a resource that you've put in the correct location in one of the directories or JAR files on the classpath.
Or if the resource is not "part of" your application, don't access it this way.