Best way to get values from a external file in java - java

I have a java code which I'm currently running as a jar. This code checks for a specific file in the given directory which is currently hard coded in the code.
To give more flexibility and not to touch the code. I would like to have the folers list managed by a different file and the code reads this config file and gets the list of folders each time and execute it.
I would like to know which is the best possible option of maintaining the folder list outside the code so that anyone can update it. Can a properties be used for this ? can we dynamically take values from a property file

In Java you have the java.util.Properties that allow you to load flat key/value data from external resources.
If you need something that can be dynamically updated, there's also the more sophisticated Preferences library. This one allows you to:
Keep data organized in tree structures (it's a tree of nodes, each node storing its own key/value preferences).
Make use of basic types (primitive types, strings and binary data).
Make use of platform-dependent "native" stores transparently (under the hood, it's going to use the file system on Unix systems and registries on Windows by default).
Plug in your own backing store if needed.
Get any data changes performed within the application persisted transparently.
Register node/preference change listeners and react to any change if needed.
The API is quite old and hasn't been updated, but it doesn't mean it's deprecated. It is used mostly with GUI applications (notably, IntelliJ IDEA was storing its configuration using Preferences the last time I checked).
There's also an attempt to revive this library that I made with a project called cross-preferences by integrating modern distributed config stores (such as zookeeper, etcd or consul) as backing stores for java.util.prefs.Preferences and providing a web console for preference management.

Related

Set up permissions/features in desktop application?

i have a desktop application that consists of 10 features, and some clients asks only for 8 features or 7 features.
i want to have a way to manage adding/removing the permissions/features for the client (only i can control that). so that i can hide/show feature based on a flag.
is that should be done through a property file that contains the name of the feature with boolean flag, or what ?
please give me some ideas, thanks.
From your other answers, it sounds to me like the following additional details have cropped up; please let me know if I have these wrong:
You're delivering your application as a .jar file,
Each customer gets their build directly from you, and there's a small number of customers,
You configure a build specifically for each customer, and
You don't want your customers to be able to modify their feature access.
In that scenario, I'd store the "active" feature list in a hashed property value stored in a .properties file bound into the .jar. I'll describe one way to do that below. You generate the properties file just before delivery, add the file to the jar:
jar -uf applicationJarFile.jar configuration.properties
then sign the .jar and deliver it. At runtime, your app can load the properties file, run the hash of each feature, compare with the properties you've stored, and determine which ones are off or on.
Your properties, which determine which features are enabled, might consist of a list like this:
feature1=enabled
feature2=disabled
feature3=disabled
feature4=enabled
Write yourself a utility which hashes the whole string "feature1=enabled" plus a salt value, e.g. "feature1=enabledaKn087*h5^jbAS5yt". (There's code for this built into java; see How can I generate an MD5 hash?, for example.) The result will be an opaque 16-byte number, which you can then store in another properties file to be included in your app: feature1=1865834.... The salt value should be broken into multiple shorter strings in your code so your customer can't just retrieve it and easily duplicate the process themselves.
In your app, at startup, you construct the string above using both the "enabled" and the "disabled" value, run the MD5 of both, and compare it with the stored hash. That'll tell you what features to enable.
I think a separate .jar or .properties is a bad idea; it clutters your delivery.
You can automate the whole process fairly easily, since you can generate the properties on the fly any time, and bind them into your app.
You can add other "baked in" properties which gives you a lot of flexibility in the final deliverable, including things like skinning for customer branding.
As others have pointed out, though: there's lots of ways to approach this, depending on the rest of the details of your product and your overall goals. This is one way to do it, given the assumptions above. AFAIK, there's no "canonical" way to do this sort of thing.
You should consider using a License management api to do the same, which will give u both security and capability to change License pre/post installations.
It is not advisable to build adhoc licensing capabilty, take a look at License3j and TrueLicense, they are both free and can help you gain perspective or better fulfil your requirement
You could try and encode that in a file. I assume each user has an own installation/version of the application, right? I further assume the application should not need to check some web resource. Thus you need to implement that in a file.
However, you should encrypt that file and put the salt and key somewhere in the code where they can't easily be decompiled. Additionally create a hash to check for modifications of the file. That hash could be based on the application's size or something else.
Please note that there's no 100% security and any hacker could still crack your application. But in that case this would need some form of criminal energy not commonly present in the business world.
Modularize the application and deploy to each client only those parts that he wants/has access to. There's many ways to do it (the most complete but heavyweight being OSGi), but the specifics depend on your circumstances and requirements.
The quickest way to implement it might be to simply extract your extra functionality in separate JARs, and on deployment update the classpath appropriately.
It depends on the kind of application,kind of security you want and the number of people likely to use the application.
If the number of clients is not that big you can store their preference in some in memory data structure like a Map . Otherwise you can use file system or a DB depending upon the kind of security you want.
This is very open ended - it really depends on what you're trying to achieve, and what you mean by a feature.
One approach is to use a plugin based architecture. e.g. you have an interface
public interface Feature {}
and provide each of your ten features as implementors of this interface. Then have some method which runs at application start which looks for Feature subclasses on the classpath.
You can control which features a client has by including only the relevant features on the classpath, e.g. using maven.

Properties location

I need to create a properties file to store username/passwords for DBs and other websites for my application.
Is there a good place to put this?
I was thinking of putting in /usr/local/myapp/myapp.properties
However...this doesnt really make much sense for Windows boxes. However, I don't want to store it under a particular user's account as I want it to be global for all users.
Any thoughts?
Store it wherever you like, and point your application to it via a vm parameter: -Dproperties.location=/usr/local/...
Then you can read it with System.getProperty("properties.location")
If you use the built-in Preferences class, the values will be automatically saved in the appropriate place on the user's system.
Edit:
Oops, I missed the "global to all users" requirement. This will not work on all systems in that case.
I have written on this property framework for the last year.
It will provide of multiple ways to load properties, and have them strongly typed as well. Which also include a way to encrypt/decrypt a password property.
Have a look at http://sourceforge.net/projects/jhpropertiestyp/
JHPropertiesTyped will give the developer strongly typed properties.
Easy to integrate in existing projects.
Handled by a large series for property types.
Gives the ability to one-line initialize properties via property IO implementations.
Gives the developer the ability to create own property types and property io's.
Web demo is also available, screenshots shown above.
Also have a standard implementation for a web front end to manage properties, if you choose to use it.
Complete documentation, tutorial, javadoc, faq etc is a available on the project webpage.

What is the right location to store persistent objects?

I am developing a medium Java desktop application, without using a database.
I am using xml, serializable objects, etc. to store the user/application data, but what is the right location to save these files to (system-independent)?
If you really don't want to store them in a data base take a look at the Preferences API it is platform neutral.
Why aren't you using a database? Use file-system database (like hsqldb) and an object relational mapping layer. You probably won't even need to write a mapping file of any kind, or arbitrarily make your classes serializable.
Store data in %APPDATA%/appName on windows, and probably ~/.appName on linux.
User/Library/Application/appName could work on macs.
Most, if not all, OSes have a concept of a home directory where you end up having a lot of hidden configuration directories of one form or another. You could create a hidden directory under the users home directory and store your configuration/data files there.

How to efficiently manage files on a filesystem in Java?

I am creating a few JAX-WS endpoints, for which I want to save the received and sent messages for later inspection. To do this, I am planning to save the messages (XML files) into filesystem, in some sensible hierarchy. There will be hundreds, even thousands of files per day. I also need to store metadata for each file.
I am considering to put the metadata (just a couple of fields) into database table, but the XML file content itself into files in a filesystem in order not to bloat the database with content data (that is seldomly read).
Is there some simple library that helps me in saving, loading, deleting etc. the files? It's not that tricky to implement it myself, but I wonder if there are existing solutions? Just a simple library that already provides easy access to filesystem (preferrably over different operating systems).
Or do I even need that, should I just go with raw/custom Java?
Is there some simple library that
helps me in saving, loading, deleting
etc. the files? It's not that tricky
to implement it myself, but I wonder
if there are existing solutions? Just
a simple library that already provides
easy access to filesystem (preferrably
over different operating systems).
Java API
Well, if what you need to do is really simple, you should be able to achieve your goal with java.io.File (delete, check existence, read, write, etc.) and a few stream manipulations with FileInputStream and FileOutputStream.
You can also throw in Apache commons-io and its handy FileUtils for a few more utility functions.
Java is independent of the OS. You just need to make sure you use File.pathSeparator, or use the constructor File(File parent, String child) so that you don't need to explicitly mention the separator.
The Java file API is relatively high-level to abstract the differences of the many OS. Most of the time it's sufficient. It has some shortcomings only if you need some relatively OS-specific feature which is not in the API, e.g. check the physical size of a file on the disk (not the the logical size), security rights on *nix, free space/quota of the hard drive, etc.
Most OS have an internal buffer for file writing/reading. Using FileOutputStream.write and FileOutputStream.flush ensure the data have been sent to the OS, but not necessary written on the disk. The Java API support also this low-level integration to manage these buffering issue (example here) for system such as database.
Also both file and directory are abstracted with File and you need to check with isDirectory. This can be confusing, for instance if you have one file x, and one directory /x (I don't remember exactly how to handle this issue, but there is a way).
Web service
The web service can use either xs:base64Binary to pass the data, or use MTOM (Message Transmission Optimization Mechanism) if files are large.
Transactions
Note that the database is transactional and the file system not. So you might have to add a few checks if operations fails and are re-tried.
You could go with a complicated design involving some form of distributed transaction (see this answer), or try to go with a simpler design that provides the level of robustness that you need. A possible design could be:
Update. If the user wants to overwrite a file, you actually create a new one. The level of indirection between the logical file name and the physical file is stored in database. This way you never overwrite a physical file once written, to ensure rollback is consistent.
Create. Same story when user want to create a file
Delete. If the user want to delete a file, you do it only in database first. A periodic job polls the file system to identify files which are not listed in database, and removes them. This two-phase deletes ensures that the delete operation can be rolled back.
This is not as robust as writting BLOB in real transactional database, but provide some robustness. You could otherwise have a look at commons-transaction, but I feel like the project is dead (2007).
There is DataNucleus, a Java persistence provider. It is little too heavy for this case, but it supports JPA and JDO java standards with different datastores (RDBMS, object storage, XML, JSON, Excel, etc.). If the product is already using JPA or JDO, it might be worth considering using NataNucleus, as saving data into different datastores should be transparent. I suppose DataNucleus supports splitting the data into several files, creating the sensible directory/file structure I wanted (in my question), but this is just a guess.
Support for XML and JSON seems to be experimental.

Where to store application data (non-user specific) on Linux

In my OSGi-based Java application I am developing a bundle to provide the rest of the system with access to the file system. In addition to providing access to the user home directory, I also wish to provide access to a non-user specific area. Exactly what this area will be used for is as yet undetermined, but it will not be for preferences (handled by a different bundle), however it may be used to store data that could change at runtime.
I intend on using the following directories for this purpose:
Windows Vista and Windows 7: “\ProgramData”.
Windows XP: “\Documents and Settings\All Users“.
Mac OS X: “/Library/Application Support”.
Where is a sensible equivalent in Linux and how do I get a handle on it from my Java code?
It depends on what kind of data you're planning on storing. This answer is under the premise that you're storing and modifying data at run time.
Contrary to what others have suggested, I would recommend against using /usr/share for storage. From the Filesystem Hierarchy Standard:
The /usr/share hierarchy is for all
read-only architecture independent
data files.
As you're modifying data, this goes against the read-only nature of the /usr subsystem.
A seemingly better place to store your application state data would be /var, or more specifically, /var/lib. This also comes from the Hierarchy Standard. You could create a /var/lib/myapp, or if you're also using things like lock files or logs, you could leverage /var/lock or /var/log.
Have a deeper look at the standard as a whole (linked to above)—you might find a place that fits what you want to do even better.
Like Steve K, I would also recommend using the Preferences API for application preference data.
It depends.
Global configuration → /etc/appname
Read-only, independent of machine architecture → /usr/share/appname
Read-only, machine specific → /usr/lib/appname
Read-write → /var/lib/appname
There isn't any guarantee for completeness. Please
check the Filesystem Hierarchy Standard.
Since you are using Java, look at the Preferences API.
From the introduction:
Applications require preference and configuration data to adapt to the needs of different users and environments. The java.util.prefs package provides a way for applications to store and retrieve user and system preference and configuration data. The data is stored persistently in an implementation-dependent backing store. There are two separate trees of preference nodes, one for user preferences and one for system preferences
I'd let the built-in API do the work.
The freedesktop.org (previously known as the X Desktop Group) project has defined some standards for this in the XDG Base Directory Specification.
In your case, I'd have a look at $XDG_DATA_DIRS:
$XDG_DATA_DIRS defines the preference-ordered set of base directories to search for data files in addition to the $XDG_DATA_HOME base directory. The directories in $XDG_DATA_DIRS should be seperated with a colon ':'.
If $XDG_DATA_DIRS is either not set or empty, a value equal to /usr/local/share/:/usr/share/ should be used.
I warmly suggest to read the XDG Base Directory Specification.
In the /usr/share or /usr/local/share folders.
According to Filesystem Hierarchy Standard
(which seems to be updated and correct as of July 2015)...
Assuming that the datafiles are understood to not meet the requirements of /tmp or /var/tmp then /usr/local/share/theApp or /usr/local/theApp.
If it is non-user-specific, you can probably store it under /usr/share/appname
You could use the System.getProperty("user.home") to get the users home, so it's more platform independent.

Categories