Add a file to spring properties - java

I would like to add a file to a spring properties YAML file. What would be the best way to do it?
I'm providing default files, but the user has to be able to change them and add his files as well. These files are mainly certificates and keystores.
My solution to this problem is to encode a file in base64 and then store this string as a property to load at the runtime. But i wonder if there is a better way to store these files?
For example:
trustedProfileKeystoreFile: MIIJcgIBA(..)zCCCTwGCSqGS
But i need a way to store multiple files also:
trustedCertificateFiles:
- Q2VydGl(..)maWNhdG
- RQTF4zr4(..)fzaw512
However Spring does not allow to store a list of strings like in the example above and i would have to "hack" it like in the post in patrickjamesbarry comment.
I cannot store all files in a single folder and then load this folder because the application will be available at docker and that would mean that i have to mount multiple folders for multiple types of files, and that's not acceptable. I need to have a centralized way to save all files.

yml file is the configuration file, and you cannot overload it with something which has no relation to it.
you should rather put the file locations in YAML file, and extract data in code.

Related

Is it normal to store large pieces of HTML-code in properties file?

I need to store a quietly big piece of HTML-code as a static resource. Is it normal to put it into properties file? Or would it be better if it stored in separate HTML-file? Storing in properties file seems to be more convenient since Spring has build-in mechanism to work with it, but I'm not sure this is a good approach.
Thanks.
I have never seen HTML in a .properties file. I cannot think of any problem where this would be a solid solution.
Put that HTML where it belongs: in an HTML file or a template of some kind. Not a .properties file.
How about using freemarker, a Java template engine, spring also can process it easily.
here is the freemarker.org
See http://mixer2.org .
Mixer2 can use *.html template files in classpath with other resource files such as *.xml, *.properties.
You need not to store html tag into *.properties file.

Best practice to create a config file for an existing software programmatically

I am working on a tool that can help me generate a configuration file for use with an existing software (Vagrant), of course, in the format which Vagrant understands.
However, I am having a tough time planning my program design that can help me with dynamic generation of the configuration file with a programmatic approach. Moreover, the config file structure will consist of many optional snippets as well which may/not be required in the final configuration file as per the requirements of the user. I can't think of some efficient approach to go about it.
Three approaches which I have thought of are :
1) Working on a readymade template and just replacing the placeholders with appropriate text.
2) Creating the config file on the fly with String append etc. (Doesn't look like a robust and future proof solution to me).
3) Bifurcation of the basic config structure into sub parts and then including each required component one by one as and when required, then replacing the placeholder values.
I am not very confident if any of these is the best professional approach to dynamically generate such a file.
Are there any constraints on the format of the config file? If not, use YAML (or similar) with two config files: default.yml and deploy.yml. Put the defaults for non-required config params in default.yml and then have Vagrant/Chef/Ansible/bash/whatever write the deploy.yml file. On launch, your app reads both config files, giving precedence to deploy.yml.

Where to place a writable properties file in a java webapp?

I'm using a properties file to store configuration information for a webapp. I'd like to allow the user to set certain values via the webapp. I'm just wondering where I should place it?
I see this is tagged with Spring. Have you looked at the PropertyPlaceHolderConfigurer ?
This can be used to specify multiple property files used to expand properties in the Spring configs. You can use this to (say) specify a properties file on the classpath (in your app bundle) and an optional overriding properties file in (say) the user's home dir.
That way you can provide defaults in the app, and override using optional properties files in the user's home directory, the /etc/ filesystem etc. This is what I typically do, providing locations for different prperties files that are user-editable (in /home) and admin editable (in /etc).
I appreciate that this doesn't quite answer your question, but gives you new options for what you really want to achieve.
If it is project setting conf file, I would put it to ${user.home}/app/app-conf.properties
platform independent & uniform and easily accessible place

Alternative to ZIP as a project file format. SQLite or Other?

My Java application is currently using ZIP as a project file format. The project files contain a few XML files and many image and sound files.
The project files are getting pretty big, and since I can't find a way with the java.util.zip classes to write to a ZIP file without recreating it, my file saves are becoming very slow. So for example, if I just want to update one XML file, I need to rewrite the entire ZIP.
Is there some other Java ZIP library that will allow me to do random writes to a ZIP file?
I know switching to something like SQLite solves the random write issue. Would using SQLite just to write XML, Sound and Images as blobs be an appropriate use?
I suppose I could come up with my own file format and use RandomAccessFile but then there would be a lot of bookkeeping I'd have to write.
Update...
My file format is very much like Office Open XML. It is a ZIP file containing XML and other resources.
Someone must have solved the problem of how to do random writes to update a ZIP file. Does anyone know how?
There exist so-called single-file virtual file systems, that let you create file-based containers and provide file-system like structure and APIs. One of the samples is SolFS (it has C-written core with JNI wrapper) and some other C- and Delphi-written solutions (I don't remember their names at the moment). I guess there exist similar native Java solutions as well.
First of all I would separate your app's resources in those that are static (such as images) and those that can be changed (the xml files you mentioned).
Since the static files won't be re-written, you can continue to store them in a zip file, which IMHO is a good approach to deploy any resources.
Now you have 2 options:
Since the non-static files are probably not too big (the xml files are likely to be smaller than images+sounds), you can stick with your current solution (zip file) and simply maintain 2 zip files, of which only one (the smaller one with the changeable files) can/will be re-written.
You could use a in-memory-database (such as hsqldb) to store the changeable files and only persist them (transferring from the database to a file on the drive) when your application shuts down or that operation is explicitly needed.
sqlite is not always fast (at least in my experience). I would suggest individually compressing the XML files -- you'll still get decent compression, and just use the file system to save them. You could experiment with btrfs, or just go with ext4. If you're not on Linux, then this should still work okay, but it might not be as fast until things are cached in memory.
the idea is that if you do not have redundancy between XML files, then you don't get that much saving by compressing them in one "solid" archive.
Before offering another answer along the lines of using properly structured JARs, I have to ask -- why does the project need to be encapsulated in one file? How do you distribute the program to users to run?
If you must keep a project contained within a single file and be able to replace resources efficiently, yes I would say SQLite is a good choice.
If you do choose to use SQLite, also consider converting some of the XML schemas to one or more SQL tables rather than storing large XML documents as BLOBs.

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