Where to store preferences in a Java application? - java

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.

Related

Library to access Javadoc from Java

I want to find a library that I can use from my Java application that will allow me to access specific Javadoc in the scope of my project (I specify where Javadocs are located). Just like in Netbeans, I want to potentially access the Javadoc from html files locally and remotely, and from source.
I expect that I could use code from Netbeans to achieve this, but I don't know how, and I can't easily digest their documentation.
Today I started thinking about the same thing.
From CI point of view, I could use #author annotation to send e-mail to someone, who wrote a test that is failing with error, not with a failure.
Google didn't help me (or I didn't google deep enough), so I started wondering how to do it on my own.
First thing that came to my mind is writing a little tool that will check all *.java files specified in a directory, bound file name to annotations and allow user to perform some actions on them.
Is that reasonable?

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.

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");

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.

Hacker proofing a jar file

What techniques could I use to make my "jar" file Reverse Engineer proof?
You can't make it reverse engineer proof. If the java runtime can read the instructions, so can the user.
There are obfuscators which make the disassembled code less readable/understandable to make reverse engineering it harder, but you can't make it impossible.
Don't release it.
There is no such thing as hacker proof. Sorry.
EDIT FOR COMMENT:
The unfortunate truth is that no matter what barricade you put in the way, if the honestly want in, they'll get in. Simply because if they're persistent enough they'll be looking at your code from an Assembly level. Not a thing on earth you can do about it.
What you can look at doing is Obfuscating code, packing the jar and merging all externals packages into a single to make life harder. However no matter how high the hurdle, my comment in the previous paragraph still applies.
I think this is more about hardening the access path to the jar, more than anything else.
Try to determine what user context
will actually be executing the code
that will access the .jar. Lock
down access to the jar to read-only
access from only that user. How you do this
will depend on if you're using the jar from
a web app or a desktop .exe, and it will also
depend on the operating system you're running
under.
If possible -- sign the jar and
validate the signature from the
executable code. This will at least
tell you if the .jar has been
tampered with. You can then have
some logic to stop the executing application
from using the .jar (and log and display an error).
See jarsigner docs for more information.
I have seen one case where a company wrote a custom classloader, that could decrypt an encrypted jar file. The classloader itself used compiled JNI code, so that the decryption key and algorithm were fairly deeply obfuscated in the binary libary.
You are looking for an "obfuscator" (if you want to ship jars) . Many exist:
http://java-source.net/open-source/obfuscators
You should be aware that many obfuscation techniques removes information you may want to keep for troubleshooting purposes - think of the value of a stack trace from an irreproducible situation - or actual debugging sessions. Regardless of what you do, your quality testing should be done on the jars-to-be-shipped since the obfuscator may introduce subtle bugs.
If you really want to hide things, consider compiling to an native binary with gcj.
Definitely avoid placing any sensitive data in the code. For example:
passwords
database connection strings
One option would be to encrypt these (using industry-standard encryption routines; avoid rolling your own) and place them in an external configuration file or database.
As others have stated, any algorithms in deployed code can be reverse-engineered.
Sensitive algorithms could be placed in a web service or other server-side code if desired.

Categories