Android: load java.io.file from resource file - java

I would like to use a Java library in my Android application. The class constructors and methods of this library often take paths to files (configuration file, dictionary, etc.) and then build java.io.file instances based on the given paths.
In my android application, I would like to store these file in the 'res' folder (possibly in res/raw). The problem is that I have to give a path to these files to the methods of the library.
I could easily get an InputStream using getResources(), but this would not be directly usable by my library. I would have to go through all the methods taking a path as an argument, replace it by an InputStream and modify the content to deal with InputStreams instead of Files. This represent quite a lot of work and I would much prefer to use the library without modification and keep it easily upgradable.
Even though using java.io.file based on resource file would not be a good practice, is it something possible? It would definitely help if you could indicate a way to do this.
Thank you.

If the library uses java.io.File then I don't think there is a way to do this in Java (let alone the Android subset of Java). It might be possible to solve the problem with a loopback filesystem, but this depends on your Android device's kernel, etc.
See:
https://android.stackexchange.com/questions/25396/how-to-find-out-if-my-devices-kernel-has-loop-device-support
If the library uses java.nio.file.Path, then it may be possible to implement a custom FileSystemProvider that maps the resources into the default file system namespace.
Note this is for regular Java 7. It would require a back-port of the relevant NIO libraries to get this to work on Android. I had another look for a viable backport, and couldn't find one.
See:
Tweaking the behavior of the default file system in Java 7
How to use java.nio.file package in android?
There is another "clunky" way to do this. Get your application to copy the relevant resources to files that can be accessed via a File.

Related

Reading .qm translation files with Java

I'm trying to read a .qm translation files with Java.
.qm files are binary files. I don't have access to the .ts files.
And I don't find much info on these .qm files.
How are they structured ?
Regards,
There's no documentation that I know of, but if you look at QTranslator::load you should be able to follow the format of the QM file.
You will probably need to reimplement QTranslator in Java, as you need not only the ability to load the files, but also to extract and apply translations in Qt fashion.
As per request of OP:
You could use those files by using the Qt libraries and JNI. By using the translator in a c++ dll you can translate strings easily. However, you cannot extract the files or list the contained translations. But if all you need is the actual translation, this solution should work.
I cannot give a real example, because I only now how it works in theory, I haven't tried it, because it's not trivial. But if you are eager to try it out, the general idea would be:
Create a C++ dll and build it against QtCore. The easiest way is to download Qt from their website qt.io. You can for example create a default library project with QtCreator. Note: Besides Qt5Core.dll, Qt requires other libraries to correctly run. They are all included in the installation, but once you deploy your application, those of course have to be includes as well.
Include JNI to the C++ project and link against it. if you're new to this, here is a nice tutorial: Java Programming Tutorial
Create your wrapper methods. Methods in cpp you can call from java that take java strings, convert them to QString, translate them with QTranslator and convert them back.
Load the library in Java and execute those methods
Important:
First, I don't know how java handles dll dependencies. If you encounter errors while loading the dll, it's probably because dependencies of your dll are not present. Second, Qt typically requires a QCoreApplication running in the main thread for most of it's operations. I tested the translator without such an app, and it worked. So apparently for translations only the app is not required. However, depending on what you do in your dll, I think this is important to know.
If you need more details, feel free to ask.

how to bundle javascript files into Java application?

Javascript is executed by Java application. However, something like Jquery library is really too long to fit into a String variable. I am able to read jquery.js from a file but not sure how to package it inside the .jar file.
Loading the .js files is the same as loading any other resource from a jar file. Generally, this is what I do:
For files stored in the root of the jar file:
SomeClass.getClass().getClassLoader.getResourceAsStream( "myFile.js" );
For files stored along side a .class file in the jar:
SomeClass.getClass().getResourceAsStream( "myFile.js" )
Both techniques give you an InputStream. This can be turned into a String with code a little bit more work. See Read/convert an InputStream to a String.
This technique is for when your resource files are in the same jar as your java class files.
There are all sorts of places you can keep your JavaScript sources:
In the CLASSPATH. You fetch them with getResourceAsStream()
In the database. Yes, the database. You fetch them like you'd fetch any other CLOB.
Personally I've use both approaches for different purposes. You can keep your JavaScript files around in your build tree in a way that exactly parallels the way you keep .properties files. Personally I just keep them in with the .java files and then have a build rule to make sure they end up in the .war, but they can really live anywhere your build engine can find them.
The database is a nice place to keep scripts because it makes it much easier for your web application to support a "script portal" that allows dynamic updates. That's an extremely powerful facility to have, especially if you craft the web application so that Javascript modules control some of the more important business logic, because you can deploy updates more-or-less "live" without anything like a deployment operation.
One thing that helps a lot is to create some utility code to "wrap" whatever access path you're using to Javascript (that is, either the Sun "javax.script" stuff, or else the Rhino bindings; at this point in time, personally I'd go with straight Rhino because it really doesn't make much difference one way or the other anyway, and the Sun stuff is stuck with a fairly old and buggy Rhino version that in the current climate will probably not see an update for a while). With a utility wrapper, one of the most important things to do is make it possible for your JavaScript code (wherever it comes from) to import other JavaScript files from your server infrastructure. That way you can develop JavaScript tool libraries (or, of course, adapt open-source libraries) and have your business logic scripts import and use them.

Creating java executable using JNI?

I am trying to create executable under windows platform for Java program using JNI ,C/C++ and invocation API, I have already created jar file for my program which includes all dependencies. I want to embed it in exe file, I was successful in running simple main class(present in file system) using JNI invocation API, I am planning to add jar file as resource in C/C++ program. But I don't know how do I run that jar file , One option is create temporary jar file on file system and run it using java, But I do not want to expose my jar file to everyone for security reasons, How can I run jar file on the fly using JNI ?
Compiling Java to an executable with GCJ does not work all the time, there are limitations as far as using reflection and other items such as UI classes, Look at this page.
If you convert you Java Code to a library or simply another module then you could link to it and simply run it without the need for a JVM.
My initial reaction was that I would be shocked if you could get this to work and have it be performant. But then I started thinking about it, and maybe you could pull this off using a custom class loader. If you embed the jar in the exe as a resource, it would be exactly the same as having the jar bytes be present at a particular offset in any file (whether an exe or not).
So, here's a potential strategy: implement a custom class loader that accepts the exe path and offset of the jar resource in that file. This would use a custom version of ZipFile that uses a fixed index offset for it's reads (unfortunately, it isn't going to be possible to use ZipFile itself - but if you grab the source of ZipFile it should be pretty obvious where you'll need to add the offset).
There is a bootstrapping issue here (how do you load the custom class loader?) - but I think it might be possible to do that from the JNI side. Basically you'd store the .class file for the loader as a separate resource in the exe, load it fully into memory then construct it using JNI calls. That will be a hassle, but it's just for one class, and then you can let the Java runtime take over the rest.
Sounds like an interesting project (Although, as others are pointing out, there isn't much security in what you are doing... I suppose that you could encrypt the embedded jar and add decryption code to the classloader, but you've kinda got to decide how far you want to take this thing).

Shipping Java code with data baked into the .jar

I need to ship some Java code that has an associated set of data. It's a simulator for a device, and I want to be able to include all of the data used for the simulated records in the one .JAR file. In this case, each simulated record contains four fields (calling party, called party, start of call, call duration).
What's the best way to do that? I've gone down the path of generating the data as Java statements, but IntelliJ doesn't seem particularly happy dealing with a 100,000 line Java source file!
Is there a smarter way to do this?
In the C#/.NET world I'd create the data as a separate file, embed it in the assembly as a resource, and then use reflection to pull that out at runtime and access it. I'm unsure of what the appropriate analogy is in the Java world.
FWIW, Java 1.6, shipping for Solaris.
It is perfectly OK to include static resource files in the JAR. This is commonly done with properties files. You can access the resource with the following:
Class.getResourceAsStream ("/some/pkg/resource.properties");
Where / is relative to the root of the classpath.
This article deals with the subject Smartly load your properties.
Sure, just include them in your jar and do
InputStream is = this.getClass().getClassLoader().getResourceAsStream("file.name");
If you put them under some folders, like "data" then just do
InputStream is = this.getClass().getClassLoader().getResourceAsStream("data/file.name");

Any way to get a File object from a JAR

I have a JAR file that contains an API that uses external model files. I would like to include the model files in the JAR itself so it easier to use for other developers. The API will accept a File object only, is there any way to do this? I have already tried the following, and they have failed:
Using class.getResourceAsStream(). This would work if the API accepted an InputStream.
Parsing the classpath and trying to build from the entries (the JAR will show as app.jar)
I suppose an option is to use getResourceAsStream and move the files to a permanent location on the HDD but, I do not like this option. There has to be something better, any thoughts?
Resources in a .jar file are not files in the sense that the OS can access them directly via normal file access APIs.
And since java.io.File represents exactly that kind of file (i.e. a thing that looks like a file to the OS), it can't be used to refer to anything in a .jar file.
A possible workaround is to extract the resource to a temporary file and refer to that with a File.
Note that generally APIs that try to handle files should be written to handle InputStream/OutputStream as well to allow this kind of operations to suceed.

Categories