Android - reading txt files from external jar - java

I have a jar compiled with core jdk.
It contains a java class which reads a txt file.
It has a test which proves that this class works correctly.
If I include this jar in my android project and then call the java class that reads the txt file. It fails reporting: java.io.FileNotFoundException and adding a '/' to the path of the txt file which I wanted to load.
Is Android's security model stopping the txt file from being read?
My Project structure:
Android Module:
src/Loader.java [calls GetName.java]
Java Module:
test/TestGetName.java [calls GetName.java]
src/GetName.java
resources/names.txt
Summary:
TestGetName.java works
Loader.java fails. A FileNotFoundException is thrown inside GetName

Figured it out in the end. I need a condition to see if I am loading the file locally or as a resource. There is probably a neater way to do this without using a conditional.
String source = "resources/inputfile.txt";
BufferedReader fin;
InputStream inputStream = getClass().getResourceAsStream(source.substring(source.lastIndexOf("/")));
if (inputStream != null) {
fin = new BufferedReader(new InputStreamReader(inputStream));
} else {
fin = new BufferedReader(new FileReader(new File(source)));
}
Thanks for the hints about reading as a resource user77777777

It doesnt seem like the Android stopping it from accessing the file because the exception is FileNotFoundException. You should check the detailed message to confirm that. Catch the Exception and print the detailed message. That will give you a better idea. Also recheck the file path.
EDIT:
Try passing the resource name only.
getClassLoader().getResource("names.txt");

I don't know why but accepted answer didn't work for me.
Build System : Gradle
Working environment : Android Studio
I also included resources from external jar. But in order to use them I had to include full path also.
this.getClass().getResourceAsStream("/template/login.xml")
Hope this helps someone and prevents him from spending 3 hours banging his head against the wall to find an answer.

Related

FileInputStream Javafx in .jar files

I am creating a Javafx application in Intelij and FileInputStream works perfectly. However, when I create a .jar file from the project and try to run it the code fails to run as it is unable to locate the file in the file input stream.
Here is my code:
ObjectInputStream os = new ObjectInputStream(new FileInputStream("src/settingStorage.bin"));
Am I doing something wrong?
There is always some issue accessing a file outside a jar, depending on where the file location is. You can check this SO question/answer to have an idea on accessing your file.
Read properties file outside JAR file
Try this:
EDIT: Look at this again, I left part out.
ObjectInputStream os = new ObjectInputStream(new FileInputStream(SomeClass.class.getResourceAsStream(“settingStorage.bin")));
This usually works for me. When I run this, it operates fine, in AND out of the development area. Don’t include /src, as when you call getResourceAsStream off a class, it already checks inside the jar.
Cheers!

How to delete a file inside zip file in android

I want to delete a file from a zip file without extracting it in android. I first did it with java using the following code
Path zipFilePath = Paths.get(filePaths); //gave the path of the zip with zip file name
try( FileSystem fs = FileSystems.newFileSystem(zipFilePath, null) ){
Path pathInZipfile = fs.getPath(reVsl3); //reVsl3 String which holds the name of the file to be deleted in the zip file
zipDelLoc=reVsl3; //just assigning it for future use
System.out.println("About to delete an entry from ZIP File" + pathInZipfile.toUri() );
// Execute Delete
Files.delete(pathInZipfile);
System.out.println("File successfully deleted");
}
catch (IOException e) {
System.out.println(e+"Error here?");
}
This is working perfectly in netbeans, but its not working in ADT, the error occured in logcat
java.lang.NoClassDefFoundError: java.nio.file.Paths
Isearched for a resolution in and got a hint that android does not have ' java.nio.file.Paths' this thing,
I am looking for an alternate solution can zip4j or TrueZip will do the trick here,
i tried with truezip, but with this code
TFile archive = new TFile("archive.zip");
for (String member : archive.list())
System.out.println(member);
but archive.list() is returning null, but archive.length is returning its correct file size.
I dont know what i am doing wrong in here, i downloaded truezip 7.7 all in one jar. but i am getting an error when i give this import de.schlichtherle.io.File
please help
What version of Java are you using?
Double-check your import. It should be something something like de.schlichtherle.truezip.nio.file.TPath; When working with TrueZip, you need to import java.nio.paths even if you aren't using it and instead using truezip's flavor of paths.
Make sure you're including all the proper dependencies. I'm assuming you're using Gradle, so the dependency would look something like this:
'de.schlichtherle.truezip:truezip-file:7.7.9'
I handled a similar error with importing dependencies in a Java project using Maven. Try these things and provide your Java version.

Open resource within a jar: URI is not hierarchical

I'm trying to write a converter for specific file formats. The converted files should be filtered using a configuration file. Everything works great so far, but I have a problem concerning the reading of a file in a packaged jar.
I have the following structure for my files (Windows):
converter/src/main/resources/files/AStoXES.properties (there are 3 more property files)
If I'm executing this code in Netbeans everything works fine and the file will be read:
this.fileConfig = new PropertiesConfiguration(new File(testing.class.getClassLoader().getResource("files/AStoXES.properties").toURI()));
But if I'm packaging the jar with Apache Maven doing a clean install and run the whole program I'll get a java.lang.IllegalArgumentException: URI is not hierarchical.
After hours of spending time with Google I have found many threads with the same problem and tested lots of things but none of those proposals helped me out of this problem.
I NEED the contents of the file as a java.io.File, so using Inputstream with getResourceAsStream(argument) won't help me out, because I need to work with the properties in there.
Someone knows how to figure this one out?
Solved it by following the link (Loading a properties file from Java package) AndréStannek provided.
This way it could be read. Didn't know that PropertiesConfiguration accepts InputStreams as well.
InputStream in = testing.class.getClassLoader().getResourceAsStream("files/AStoCSV.properties");
this.fileConfig = new PropertiesConfiguration();
this.fileConfig.load(in);
try {
in.close();
} catch (IOException ex) {
Logger.getLogger(ConverterControl.class.getName()).log(Level.SEVERE, null, ex);
}
Thanks to all.
Try to get the runnig jar file, and access it as a zip file.
This may help:
How to get the path of a running JAR file?
As a solution/hack, you may create a temporary File (and an OutputStream corresponding to this File) then "write" your input stream into your output stream. You'll end up with a copy of your original File.

Using resource files in Java

I'm just getting into using "Java Resource Files" and i have a few questions...
I am hoping to distribute my program to others and I'm assuming JAR file isn't the best way. I'd probably go about it by "converting to exe" is this good practice? what are the limitations?
If I convert to an exe does it keep the resource files?
I'm actually just trying to use a resource file. This file is a text file and will just save the users directories for certain files so they don't need set them up every time they open the program. is this even the best way to go about it?
how do you reference the resource file in the code itself?
Here is what I've done.
created a new resource file and since I'm using Netbeans I can see its location under the files tab in the navigator it looks like this:
Mainproject
build
classes
myclass
resources
directories.txt
here is how i'm trying to access it but when i debug it is coming back null.
private void getPaths()//todo
{
try
{
InputStream is = getClass().getResourceAsStream("/resources/directories.txt");
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null)
{
System.out.println(line);
}
br.close();
isr.close();
is.close();
}
catch(Exception e)
{
}
}
"Converting to EXE" is just a fancy way of saying "wrapping the Jar files into an executable container"
"I'm assuming JAR file isn't the best way" not really. It's nice to provide a OS specific means for launching the program at times, but it's not always the best solution.
"what are the limitations?". Well, to start with, you're limiting your self to a single platform. For Mac's you need to bundle the application into a "app" bundle. For linux, I think most people provide scripts to launch their code.
You could also be limiting your self to particular bit depth. If all you supply is a x32 bit executable, then you'll only ever run within a x32 bit environment. This may not be an issue, but you're limiting the available memory to start with...
So yes, generally, your resource files will be safe.
A resource file is generally embedded. What you're describing in part 3 is more akin to a configuration file. This file needs to be stored on the file system (out side of your exe/jar) so it can easily be updated.
"how do you reference the resource file in the code itself?"
For embedded resources you will need to start by using getClass().getResource(...). For you configuration file, I'd say just like any other file...
I would also have a look at Deployment some ideas on the suggest mechanisms for deploying Java programs,
Jar is a perfect format for distribution. You can convert to exe , but the user will still need the JVM installed to run it. Jars are executed with a doubleclick if the JVM is installed AND the jar has a properly formed manifest file.
You can open any file from the JVM, text, binary, XML, property file etc.
To save user settings a good choice is a property file - see http://www.mkyong.com/java/java-properties-file-examples/

Create and read an xml file outside jar file

I've been asking a lot lately, and all my posts are about the same problem, but in different stages and with different possible answers (because the specific problem is different than the previous one, but closely related). So, i'm sorry if it looks like i'm repeating my question. In fact, i'm not. I've been searching on Google and here, but none of the answers seem to solve my problem, or i'm getting them wrong.
Well, my files hierarchy is:
+ MyGame
+ build.xml
+ src
+ ThisIsWhereEclipsePutsTheXMLFile
+ build
+ manyFoldersWithClassFiles
+ aSpecialFolderWhereTheEntryPointIs
+ ThisIsWhereIWantMyXMLfileToBe.xml
+ game.jar
My problems is basically this: My program is supposed to save it's status to a file, and then read that file. This file should be outside the .jar file (there is only one), in the same folder. The file can exist or not. If it exists, it should overwrite it.
In my previous question, I asked about how to read an xml file that's in the same directory. The answer i got actually solves my problem when i'm using it from Eclipse.
But i need to create a .jar file with my whole program, and i need my program to crear such xml file whenever i ask it to do it.
My save() is like this, and it seems to be working when i run it on Eclipse, but won't work when i run it executing my .jar file:
public void save(Game game) throws IOException{
Document doc = DocumentHelper.createDocument();
doc.add(game.save());
File save=null;
save = new File("save.xml");
FileWriter writer = new FileWriter(save);
doc.write( writer);
writer.close();
}
And this is how i get the informacion back from the file:
public Game getinfofromxml() throws IOException{
Game game;
SAXReader reader = new SAXReader();
try{
URL fileWithData= new File( "save.xml" ).toURI().toURL();
Document document = reader.read(fileWithData);
Element alreadySavedGame= document.getRootElement();
game= getGameSaved(alreadySavedGame);
}catch(DocumentException ex){
throw new IOException();
}
return game;
}
Again, this works from Eclipse, but this won't work when i run it from my jar file. From Eclipse, the xml file is created in the MyGame folder, but not in the folder i have my .jar. When i execute my .jar, no XML is created at all.
Now, i've been reading that this might have something to do with the classpath. So, let me tell you how I compile it:
1) i run Ant, which makes the build directory. It doesn't create the .jar automatically.
2) I create the Manifest.txt file, where i write:
Main-Class: aSpecialFolderWhereTheEntryPointIs.MyMainClass
Class-Path: .
3) i create the .jar file on the cmd:
jar cfm myGame.jar Manifest.txt *
So, i don't think i'm making too many mistakes there...
May Ant have something to do with it?
Any idea?
Thanks beforehand (and sorry for my English)
Stop thinking about the 'current directory' and put the config. in user.home as discussed in this answer. For a long time OS manufacturers have been telling us not to put config. settings in the application directory.
See also this answer to "How can a java program use files inside the jar for read and write?" for more tips.
The way you write and read file is using relative path of the current start directory... It depends on where you started the jvm and where you expect it to write and read your file.

Categories

Resources