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.
Related
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.
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.
I am making a math game in Java and I want to create the ability for the user to create a local account (or log in to an existing one), which would have a unique properties file. How would I do this?
You have a couple of options to look into. Java comes with the necessary libraries with which you can create, open, read and write to files. Using the File class, you could create an account file, for instance "User1.properties", and save the information in an easy to parse format. If you're looking to go one further, you can look into using XML or JSON, which are commonly used formats for saving information in this way. Here's some helpful links to get you started.
Using files in Java
Using XML in Java
Using JSON in Java
Another option you have available is to use a database in a similar fashion to websites. The type of database you use is up to you, although MySQL is an example of one commonly used database. Once again, here is a link to help you get started with MySQL in Java.
Regardless of what you use, you will need to take the username and password provided (or whatever combination of login credentials you would like your system to use), and compare them with those stored in your file or database.
I need just a solution to retrieve a path for storing desktop application settings (e.g. a sqlite database) that meets following needs:
cross platform
works from jar and from "normal" invocation
I've spent a lot of time googling and experimenting with getting the codebase path via X.class.getProtectionDomain().getCodeSource().getLocation() and java.util.pref.Preferences
class, but return values gave sometimes different results, returned null or just "/" as path.
"Cross Platform" is kind of hard to define. A solution called "best practice for each platform" won't be easy to achieve. Making a difference between user-specific and shared data would be sensible.
java.util.prefs.Preferences is the proper way to do it. It works perfectly fine (I've used it in a desktop application without any problems). It is cross-platform and is available without any extra jars. It also differentiates between user-specific and global data. Perhaps shed some light on your particular problems with it (or ask another question)
Of course, you can use java.util.Properties as well, and store files in System.getProperty("user.dir").
System.getProperty("user.dir") returns a path to the user directory for most modern systems.
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.