views:

170

answers:

3

Our software currently has many features. I've been asked to make a free trial version which consist of a lightweight version of the full software. Only a few specific features would be available in the trial. And since a jar file isn't encrypted, I was relunctant to release a full version with hardcoded restrictions. I want to be able to have 2 jars : 1 containing the basic features and 1 with the advanced features.

The features are in different menus. It would be nice it the code would try to load the jar with the extra features at start up and display a message (like : this feature is unvailable in the trial) when the non-paying user selects an advanced menu. On the other hand, a paying user with access to the advanced features jar wouldn't know the difference (I'm talking about the difference between now, 1 jar, and the new method, 2 separate jars).

  • Any tip on how to proceed ?
  • Any warning on common mistakes to avoid ?
  • Any better strategy than the separate jars ?

Edit : The best suggestion so far describes how to do my crippleware, but also warns me not to do a crippleware. So what do should I do ?

A: 

Many technologies allow pluggable features (called plugins or addons usually).

The idea is that your core code (or framework) declares some interfaces (a well-thought API is ideal). Plugins can provide new implementations of an interface, and register it to the framework.

In its boot sequence, your framework will look (through some convention, in a file for example) if there are plugins, and give them a chance to execute their own boot sequence, consisting of the registration.

After the boot phase, a runtime example (for menus) : The framework looks it the registry where he stores the menus. The registry contains the menus the framework himself declared, plus any additionals provided by plugins... It displays all of them.

If you want specifically the behavior you asked for, I would implement this as follow :

  • menus available in all cases are declared and implemented in the framework
  • menus available only in the expanded edition are implemented twice :
    1. in the framework, the implementation would simply display a message (like : this feature is unvailable in the trial
    2. in the plugin (= paid edition), it would override the previous implementation with the real one, that does the real job.

That way, you paying users have all normal functionality, with the trial version shows the warnings.

Many technologies exist to implement this, the best choice depends on what you already know/use/feel confortable with :

  • interface implementation is plain java, a string in the manifest of your plugin jar can mention the class to start.
  • Eclipse RCP has full implementation of menus that way (so you would have nothing to code, only configuration)
  • Spring is also pretty good when you use interfaces ...
KLE
+2  A: 

As you mentioned, you would probably have 2 jars:

1 with the basic features and stubs for the advanced features. 1 with the actual advanced features.

You could use a factory class with a config setting to determine whether to create the stub classes or the real classes - e.g. "FancyFeatureClass" or "FancyFeatureClassStub". "FancyFeatureClassStub" would be included in the "lite" distribution, but "FancyFeatureClass" would only be in the advanced features jar.

If they tried to change the config setting to create the real class without having the jar with the real classes, they would just end up getting class not found errors.

When upgrading, add advanced features jar to the classpath and change the config setting to tell the factory class to create the real classes instead of the stubs. Assuming your app could be split up that way, it should work fine.

As for common mistakes - I think you've already made one - probably not your fault though :)

"Crippleware" is a bad way to evaluate a product. Better to release a full featured version with an expiration or a nag screen than to release a crippled product. Not having those advanced features would probably make it difficult for someone to really evaluate the product.

Eric Petroelje
Thanks for the answer. I like it. But for the crippledware part : as I said, a jar software isn't encrypted, so releasing the full software is the SAME THING as going open source (which we don't want... for now), because the source code can be made available with the cheapest decompiler. A crippleware is still the best option.
Silence
@Silence: I wouldn't worry so much about decompiling, because that doesn't give you e.g. javadocs and comments and most software are anyways so big and complicated that nobody is really interested in trying to understand how it works :) In my company we release the whole software and features can be enabled with license files. Things are so much simpler for us (and the customers) this way. It's not very hard to circumvent the licensing, but at least for B2B software, it rarely happens. Just think about support, for instance. How to get it, if you have a cracked version?
Kaitsu
@Silence - If your product really is the kind of thing that people want to pirate, it will happen regardless of what you do. All it takes is for one person to buy the full version and put it up on bittorrent and - game over.
Eric Petroelje
So... you're suggesting me how to do my crippleware and also suggesting I don't choose the crippleware stragegy. Now what do I do ? ;)
Silence
Can someone add "crippleware" as a tag ? I think it fits the current problem.
Silence
@Silence - done :)
Eric Petroelje
For the lack of better answer, yours is the best. I am not entirely convinced though.
Silence
A: 

Using a separate Jar which implements the paid for features (and a separate lite front end that displays a suitable message like 'not available' if it gets a ClassNotFoundException) would be the simplest way to do it.

There are many frameworks, up to and including Eclipse RCP for distributing UI applications in a modular form - but this will be overkill for your needs.

In fact, you don't even need two Jars, as long as your build process has the option to compile/package a sub-set of the Java classes in the Jar that you build as part of the distribution process. Just don't include the paid for features.

AlBlue