java - reading xml file from jar - java

I am trying to read the an xml configuration from a jar file deployed to dm-server
here is the code
Reader fileReader = null;
try {
fileReader = new FileReader("test.xml");
} catch (FileNotFoundException fnfex) {
fnfex.printStackTrace();
} catch (IOException ioex) {
ioex.printStackTrace();
}
i was able to read it if i just write a junit test w/o the jar and w/o the dm-server.
the test is packed into the jar and is at the root of the jar file.
please help!!!!
thanks,
A

You need to use the Class's getResource or getResourceAsStream methods to read files from within the jar.
This can be done like this:
Reader fileReader = null;
InputStream is = this.getClass().getResourceAsStream("/test.xml");
if (null != is) {
fileReader = new InputStreamReader(is);
}
Note that getResourceAsStream returns null if it can't find the file.
Edit:
Corrected test.xml to /test.xml
Also note that the Class<T> version of getResourceAsStream defers to the ClassLoader's getResourceAsStream or getSystemResourceAsStream as appropriate.

ClassLoader.getResourceAsStream() will allow you to read resources from within a .jar file. If your file is at the root of the .jar file then:
this.getClass().getClassLoader().getResourceAsStream("/test.xml");
will give you an InputStream from that file.

Related

Read file from another package - Java

I'm trying to access a file from another package:
-Using LoadDatabase from Main package to access DB.txt from resources.
Image Here
When I do
File file = new File("/com/Convocatoria/resources/DB.txt");
Scanner sc = new Scanner(file);
It gives me this error
Unhandled exception type FileNotFoundException
Don't Use absolute path use getResourceAsStream method
I dont know which IDE you are using if you specify the path like this it jvm will look for file from the root of your project but your file is precent in your rootproject->src->under some packages so it is best to use getResouceAsStream because when you build it or run it all the .class files and property files will go under the class path so we know that our file will be in classpath So we can easily read the file using getResourceAsStream for eg:-
you are reading the file from MainWindow.java class
use the below code
InputStream is =MainWindow.class.getResourceAsStream("/Convocatoria/resources/DB.txt")
from this inputstream you use FileInputStream or whatever you want to read the file
Since you are loading data from within your classpath, you can use resources instead:
String resourceName = "/com/Convocatoria/resources/DB.txt";
URL res = LoadDatabase.class.getResource(resourceName);
System.out.println("resource found at url="+res);
InputStream is = LoadDatabase.class.getResourceAsStream(resourceName);
Scanner s = new Scanner(is);
//read..
//after using it, close your stream
is.close();
File constructor will throw a FileNotFoundException when it fails to find the file with specific path. You need to surround it with a try-catch block that catches the mentioned exception:
File file = null;
Scanner sc = null;
try{
file = new File("/com/Convocatoria/resources/DB.txt");
sc = new Scanner(file);
// do something with opened file
} catch(FileNotFoundException ex){
ex.printStackTrace();
}

Can't find resources runnable jar

I can't load an resource file after extracting a project as a runnable jar.
It works in Eclipse but after exporting it throws a FileNotFoundException.
I have tried to put the res folder next to the .jar file but nothing helps. I've tried with JarSplice and got it running with all the libraries but it stops with the resource file. The object file is located in a source folder.
What can I do?
Code
FileReader fr = null;
try {
fr = new FileReader(new File("res/" + fileName + ".obj"));
} catch (FileNotFoundException e) {
System.err.println("Couldn't load object file!");
e.printStackTrace();
}
EDIT: By opening the runnable .jar file in 7zip I can see that the whole /res folder has disappeared during the exporting and the files in the directory now lies directly in the root folder of the .jar file.
Based on your code, the res folder should be placed directly off the present working directory, which should be the directory where you are running the Java command from. For an example, see this question on how to determine the current working directory from inside Java.
Use Path instead of new File(string).
FileReader fr = null;
try {
fr = new FileReader(Paths.get("res/" + fileName + ".obj").toFile());
} catch (FileNotFoundException e) {
System.err.println("Couldn't load object file!");
e.printStackTrace();
}

getResource() unable to read contents of a directory inside jar

I just came around this issue that the main class inside jar is unable to read the contents of a folder.
The class contains
String path = "flowers/FL8-4_zpsd8919dcc.jpg";
try {
File file = new File(TestResources.class.getClassLoader()
.getResource(path).getPath());
System.out.println(file.exists());
} catch (Exception e) {
e.printStackTrace();
}
Here sysout returns false.
But when I try something like this it works
String path = "flowers/FL8-4_zpsd8919dcc.jpg";
FileOutputStream out = null;
InputStream is = null;
try {
is = TestResources.class.getClassLoader().getResourceAsStream(path);
byte bytes[] = new byte[is.available()];
is.read(bytes);
out = new FileOutputStream("abc.jpg");
out.write(bytes);
out.close();
} catch (IOException e) {
e.printStackTrace();
}
getResourceAsStream() is able to read the path of the folder inside jar but getResource() is unable to read it,
why is it so and what is the difference between the reading mechanism of these two methods for contents inside jar.
The contents of the simple jar
Both getResource() and getResourceAsStream() are able to find resources in jar, they use the same mechanism to locate resources.
But when you construct a File from an URL which denotes an entry inside a jar, File.exists() will return false. File cannot be used to check if files inside a jar/zip exists.
You can only use File.exists which are on the local file system (or attached to the local file system).
You need to use an absolute path to get the behavior you're expecting, e.g. /flowers/FL8-4_zpsd8919dcc.jpg, as sp00m suggested.

How to use the .txt, .xml and .properties file inside the executable jar?

I have a java project which will read a txt file and process that.
For production purpose, I will need to generate an executable jar which contains this txt file.
I use the code like:
BufferedReader br = new BufferedReader(new FileReader("src/txt_src/sample.txt"));
My jar contains txt_src/sample.txt, but can't use it. Instead, if I put a src directory which has src/txt_src/sample.txt structure, the jar works.
It will be better to generate directly by Eclipse.
Thanks in advance!
Treat the file as a resource and give the path as the package hierarchy.
http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getResourceAsStream%28java.lang.String%29
You can then take the InputStream and wrap it in an InputStreamReader that is wrapped in a BufferedReader. Wrap it in a BufferedInputStream if you need to define the encoding, which you should do.
new BufferedReader(new InputStreamReader(new BufferedInputStream(this.getResourceAsStream("myPackage/myFile.txt")), "UTF-8"));
Put your files in the assets Folder of your Project and use them with:
InputStream stream = null;
try {
stream = getAssets().open("sample.txt");
}
catch (IOException e) {
e.printStackTrace();
}

Get file in the resources folder in Java

I want to read the file in my resource folder in my Java project. I used the following code for that
MyClass.class.getResource("/myFile.xsd").getPath();
And I wanted to check the path of the file. But it gives the following path
file:/home/malintha/.m2/repository/org/wso2/carbon/automation/org.wso2.carbon.automation.engine/4.2.0-SNAPSHOT/org.wso2.carbon.automation.engine-4.2.0-SNAPSHOT.jar!/myFile.xsd
I get the file path in the maven repository dependency and it is not getting the file. How can I do this?
You need to give the path of your res folder.
MyClass.class.getResource("/res/path/to/the/file/myFile.xsd").getPath();
Is your resource directory in the classpath?
You are not including resource directory in your path:
MyClass.class.getResource("/${YOUR_RES_DIR_HERE}/myFile.xsd").getPath();
A reliable way to construct a File instance from the resource folder is it to copy the resource as a stream into a temporary File (temp file will be deleted when the JVM exits):
public static File getResourceAsFile(String resourcePath) {
try {
InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(resourcePath);
if (in == null) {
return null;
}
File tempFile = File.createTempFile(String.valueOf(in.hashCode()), ".tmp");
tempFile.deleteOnExit();
try (FileOutputStream out = new FileOutputStream(tempFile)) {
//copy stream
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
}
return tempFile;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
It is not possible to access resources of other maven modules. So you need to provide your resource myFile.xsd in your src/main/resources or src/test/resources folder.
The path is correct, though not on the file system, but inside the jar. That is, because the jar was running. A resource never is guaranteed to be a File.
However if you do not want to use resources, you can use a zip file system. However Files.copy would suffice to copy the file outside the jar. Modifying the file inside the jar is a bad idea. Better use the resource as "template" to make an initial copy in the user's home (sub-)directory (System.getProperty("user.home")).
In maven project, lets assume that, we have the file whose name is "config.cnf" and it's location is below.
/src
/main
/resources
/conf
config.cnf
In IDE (Eclipse), I access this file by using ClassLoader.getResource(..) method, but if I ran this application by using jar, I always across "File not found" exception. Finally, I wrote a method which accessing the file by looking at where app works.
public static File getResourceFile(String relativePath)
{
File file = null;
URL location = <Class>.class.getProtectionDomain().getCodeSource().getLocation();
String codeLoaction = location.toString();
try{
if (codeLocation.endsWith(".jar"){
//Call from jar
Path path = Paths.get(location.toURI()).resolve("../classes/" + relativePath).normalize();
file = path.toFile();
}else{
//Call from IDE
file = new File(<Class>.class.getClassLoader().getResource(relativePath).getPath());
}
}catch(URISyntaxException ex){
ex.printStackTrace();
}
return file;
}
If you call this method by sending "conf/config.conf" param, you access this file from both jar and IDE.

Categories