I'm trying to get the jar to read from target/classes outside of the jar so I can configure the data easier than going in the jar. The below is what I'm using to read the file, but it's reading from within the jar. After reading the XML I'm using DocumentBuilder to parse the XML.
ClassLoader classLoader = getClass().getClassLoader();
InputStream configFile = classLoader.getResourceAsStream(file);
The below is what I'm using to read the file, but it's reading from
within the jar.
To read a resource outside the jar that you execute, don't use classloader to find the resource that will looks for in the running jar but use File or better Path that allows to locate/manipulate resources in a filesystem.
You could just do it :
InputStream configFile = Files.newInputStream(Paths.get(file));
Whatever, I am not sure that you use case be valid as reading a file from target/classes makes not really sense as resources located at this place are not designed to be persistent but to be packaged in the built artifact (here a JAR).
Related
I'm trying to read a text file located in src/main/resources/test/file.txt. I'm trying to get the path of the file using String path = getClass().getResource("/text/file.txt").getFile(); but when I try to read it I get a FileNotFoundException. I tried putting many different paths, all of which failed. How can I go about doing this?
The idea of putting something into the src/main/resources tree is that it will be copied into the JAR file that you build from your project. It will then be available to your application via the Class methods getResource(String) and getResourceAsStream(String) methods.
When you are running in your application in the development environment, it is certainly possible to use FileInputStream etcetera to access the resource. But this won't work in production. In production, the resources will then be inside your app's JAR file. FileInputStream cannot open a JAR file and its contents by name.
When you do this:
getClass().getResource("/text/file.txt");
you get a URL for the resource, which will look something like this:
jar:file:/path/to/your.jar!/text/file.txt"
It is not possible to turn that into a pathname the FileInputStream will understand. Whatever you try will give you a FileNotFoundException ... or something that is not the resource you want to read.
So what to do?
You have a few options, depending on your application's requirements.
You can use getResourceAsStream and use the resulting input stream directly.
You can copy the contents of getResourceAsStream to a temporary file, and then use the pathname of the temporary file.
You can create an application specific directory (e.g. in the user's home directory) and extract the file you need from the JAR into the directory. You might do this the first time the application runs.
You could open the JAR file as a JarFile and use that API to open an InputStream for the resource. But this assumes that that the resources are in a JAR ... and on some platforms (e.g. Windows) you may encounter problems with file locking. (And it would be a bad idea to attempt to update the resource in the JAR.)
Try giving complete path of the file from the disk.
C:\Users\MyUser\Desktop\file name with extension
I know this should be simple, but surprisingly I can't google an answer.
I have this structure :
Myproj
|-src
|--com.mypackagename
|---MyClass.java
|-xml
|--book.xml
XMLInputFactory factory = XMLInputFactory.newInstance();
ClassLoader cl = MyClass.class.getClassLoader();
XMLStreamReader reader = factory.createXMLStreamReader(cl.getResourceAsStream("xml/book.xml"));
and it doesn't find my xml. Obviously, the path is wrong. Please, help me - how shall i set it right
The problem is that getResourceAsStream() will only load resources from the classpath. And as per given directory your xml file is not located on classpath. So, place your xml file under WEB-INF/classes/book.xml and access it as:
getResourceAsStream("book.xml")
If you book.xml file is kept in class path then you can simply access it by writing cl.getResourceAsStream("book.xml").
Assuming that the xml directory is not within the classpath context of your application (ie embedded within the application Jar or with the classpath property), then you will need to reference the XML file as a File. The path to which will be relative to the execution location of the program.
If the xml directory is within the classpath context (ie classpath=.\xml;...), then you will need to use a path something like /book.xml.
If the xml directory is relative to the classpath context (ie classpath=.;...), then you will need to use a path something like /xm/book.xml.
If the xml directory is embedded within the application context (packaged within the Jar), then you will need use either /book.xml or /xml/book.xml depending on how the directory is packaged
How can I access the content of the jar file which has been started. I want to create a big jar file which contains everything I need and then during runtime I want to copy some files of my jar into an external folder. Is this possible?
You want this.getClass().getClassLoader().getResourceAsStream. Example:
InputStream config =
this.getClass().getClassLoader().getResourceAsStream("config.txt");
The files in the JAR are not accessible as files, so you must use getResourceAsStream to read them. See access files and folders in executable jars how to access the files within the jar.
Following, you use the inputstream to write the files onto the file system.
See:
Easy way to write contents of a Java InputStream to an OutputStream
http://www.mkyong.com/java/how-to-convert-inputstream-to-file-in-java/
You can access any file via the ClassPath using the classloader. Start with Class.getResourceAsStream
Im trying to get the file path of a document that is packaged as a resource in a jar file so that i can display it in a swing application. The way I have it now works when I run it from eclipse but if I export it to a runnable jar file I can't access the the documents that are packaged in the jar file. How can I get the file path of the document when its inside the jar file?
Here is the line of code showing how I am trying to access the document:
File document = new File(getClass().getResource("/resources/documents/document.pdf").getPath());
The only kind of "file path" that exists for something inside a JAR file is the path relative to the root of the JAR. But in your case it seems that you know it already (it's "/resources/documents/document.pdf"). Files inside a JAR file have no path that you can use to access them directly as they don't exist within the real file system. You need to use either getResource() or getResourceAsStream() to access them. I don't remember right now which classes are used for images in Swing, but look closely at those classes - they should have overloaded methods that accept something like InputStream or URL instead of file path.
I'm trying to have my application load a resource (binary file) transparently:
If the file exists under the current directory, open it.
If not, try looking in the current JAR file if applicable.
If not, try looking in other JAR files. (This is optional and I don't mind explicitly specifying which JAR files.)
So far I know of File which opens a local file and ClassLoader which has getResource* for JAR contents.
Is there a class which combines the two? If not, how should I go about writing it myself? Should I write a ClassLoader which also checks the local filesystem? Using File? (I'm very unfamiliar with Java and don't even know what's a good type to return. InputStream?)
Thanks
P.S. By "file" I mean "path", e.g. "data/texture1.png".
Doing #1 and #3 is pretty easy. Doing #2 (just looking in the current JAR only) is much harder as it requires you figuring out what JAR you
If you wanted to check the filesystem first, otherwise load from classpath, it would be something like:
public java.io.InputStream loadByName(String name) {
java.io.File f = new java.io.File(name);
if (f.isFile()) {
return new FileInputStream(f);
} else {
return getClass().getResource(name);
}
}
If you want to prefer loading from the same JAR file first, you will need to figure out where it is. Check out Determine which JAR file a class is from for more info on figuring out the JAR file you want to load the resource from.
A URLClassLoader should be able to load both and try the file path first if the file path is on the class path ahead of the jar.
Regarding your comments:
I know that relative jar URLs don't
work. That's why the Spring guys came
up with the Resource abstraction.
Read about it here.
You might want to check the answers
to this Question: Loading a file
relative to the executing jar
file. The problem is similar to
yours.
Current jar file and current directory are not concepts in the JVM like they are when you're running a shell script. You would need to specify a directory to be used for loading the files that you're interested in, such as with a system property while executing the JVM:
java -Ddirectory.to.scan=/home/aib
Then retrieve this property:
String dir = System.getProperty("directory.to.scan");
Now when talking about JAR files, all JAR files specified explicitly on the classpath when you start the JVM are loaded by the ClassLoader. You can get the ClassLoader of a specific class by:
InputStream is = <Your class>.class.getClassLoader().getResourceAsStream("binary file");
Note that any jar file loaded by the current class loader is searched.