HotDeploy

HotDeploy: Small Java library adding hot deployment to your plugins.
HotTables: Natural extension to HotDeploy adding support for database tables to your plugins.
BucketBackup: Simple Java program/library to get a regular backup of your database.
InfoAccess: Easy to use Java Library to access a database using Java objects.
top

HotDeploy

HotDeploy is a Java library which allows you to make plugins of your application hot deployable.

Assume you have an application which can be extended by means of plugins. A static approach would load these plugins at startup and to add, modify or remove a plugin you would have to restart your application. HotDeploy now allows you to dynamically change the deployed plugins.

What is a plugin? Technically speaking, for HotDeploy a plugin is a set of Java classes bundled into a jar file. Less formally, a plugin should bundle some functionality which may or may not be made available to an application at runtime.

How to write a plugin A plugin is recognized as such if one of its classes implements the Plugin interface. Therefore to code a plugin you simply derive one of its classes from the Plugin interface. Since the Plugin interface by itself does not offer any functionality (its an empty interface), it doesn't make much sense to only implement this interface. So in real life, you would create another interface (which is not empty) in the application where you want to use your plugins. This interface, which may be called MyPlugin, will extend the Plugin interface. Now whenever you write one of your plugins (which implements the MyPlugin interface) it will be recognized as a plugin by HotDeploy since it also implements the Plugin interface.

// from HotDeploy
public interface Plugin {}

// in your application
public interface MyPlugin extends Plugin {
  ...
}

// one of your plugins
public class APlugin implements MyPlugin {
  ...
}

How to start/stop HotDeploy

start: Create plugins, put them in a directory and call PluginContainer.initHotDeployment() with appropriate configuration properties.

Map<String, String> properties = new HashMap<String, String>();
properties.put("pluginDir", "./plugins/");
properties.put("pluginScanInterval", "10000");
properties.put("runGCOnShutdown", "false");
PluginContainer.initHotDeployment(properties);

stop: Call shutdown.

PluginContainer.getInstance().shutdown();

Usage After HotDeploy has been started, you may get a reference to a single plugin by using getPlugin() passing it a classname.
To get all currently registered plugins, either call getClassnames() to get the all the classnames of the plugins and afterwards call getPlugin() using some of the classnames, or use getPlugins() to directly get references to all plugins.
Whenever a plugin is added, changed or removed in the plugin directory, HotDeploy will detect that change and notify its registered observers. Therefore if you are interested in these changes, just register as an observer.
To explicitly delete a plugin, either just remove the plugin jar or call deletePlugin().

Configuration Properties Properties which may be provided to PluginContainer.initHotDeployment():

top

HotTables

HotTables is natural extension of HotDeploy which allows your plugins to define database tables.

When to use it? Assume you have a set of plugins. Now the issue arises, that some of your plugins would like to store data into a database. Therefore each plugin should have a simple way do define the tables it wants to use. After the tables are defined, they should be automatically created.
If you run into such a case you might give HotTables a try - read on...

What HotTables does: HotTables provides you with three interfaces (Table, ForeignKey, StorablePlugin) which allow you to define database tables in your plugins. After the tables have been defined, the DbManager can be used to create the tables. The DbManager also does a regular backup (using BucketBackup) and enables access to the tables through an object oriented approach (using InfoAccess).

How to use it? A typical usage would look like this:

// hotdeploy config
Map<String, String> properties = new HashMap<String, String>();
properties.put(PluginLoader.PLUGIN_DIR_PARAMNAME, "./plugins/");
properties.put(PluginLoader.SCAN_INTERVAL_PARAMNAME, "60000");

// hotdeploy init
PluginContainer.initHotDeployment(properties);
Set plugins = PluginContainer.getInstance().getPlugins();
log.info("Plugins: " + plugins.size() + " " + plugins);

// hottables
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost/hottables_test?user=hottables&password=hottables";
int cacheExpireTime = 3600000;
long interval = 3600000;
String backupDir = "./backup/";

// hottables init
DbManager dbm = DbManager.getInstance();
dbm.setInfoAccessProps(driver, url, cacheExpireTime);
dbm.setBackupProps(interval, backupDir);
dbm.setCoreTables(new ArrayList<Table>());
dbm.init();

// do something usefull
try {
  log.info("Table names: " + dbm.getTableNames());
  log.info("JDBC connection: " + dbm.getConnection());
  log.info("InfoAccess: " + DbManager.getInfoAccess());
} catch (Exception e) {
  e.printStackTrace();
}

// shutdown
PluginContainer.getInstance().shutdown();
DbManager.getInstance().shutdown();

When HotTables is initialized, you may get the database table names getTableNames(), get a plain JDBC connection getConnection() or access the tables through InfoAccess getInfoAccess().

How to define tables? Your plugin interface (e.g. MyPlugin) should no loger extend Plugin (as in the description for HotDeploy), but instead extend StorablePlugin. This causes all your plugins to implement the getTables() method. To a call to this method, return your table definitions. A possible hierarchy of interfaces and classes is shown below:

// from HotDeploy
public interface Plugin {}

// from HotTables
public interface StorablePlugin extends Plugin {
  public List<Table> getTables();
}

// in your application
public interface MyPlugin extends StorablePlugin {
  ...
}

// one of your plugins
public class APlugin implements MyPlugin {
  ...
}
top

BucketBackup

This small Java program allows to start a regularly executed database backup.

Its backup files are kept in a directory. To ensure that the number of backup files doesn't grow too large, it uses an idea of buckets to put the files in. Every bucket may contain only one file. BucketBackup loops over every file found in the backup dir. It then tries to put the backup file in the youngest bucket found which is older then the backup file. If this bucket already contains a file, the newer file of the two is deleted. The buckets are choosen in a way, that fewer backup files are kept, the older the files get.

Thus the older the backup files are, the fewer they become.

The backup files consist of simple SQL insert statements and stored in plain text. This might be not the most performant solution possible, but its easy to use and may work with many database vendors. Currently only java.sql.Types.INTEGER and columns which can be mapped to a String (e.g. dates) are supported. The best tested DBMS is MySQL.

Usage: There are at least two ways this program may be used - as a standalone application or as a library for another Java program.

Standalone:

  1. Create a file 'bucketbackup.properties' in the directory where you want to start BucketBackup (example properties).
  2. Create the directory which should hold the backup files.
  3. Run it: java -cp <classpath> org.hotdeploy.bucketbackup.Main (example shell script).

Java Library:

  1. Add the bucketbackup-<version>.jar to your classpath.
  2. Instantiate org.hotdeploy.bucketbackup.BucketBackup and use one of its start() methods.

top

InfoAccess

InfoAccess is an easy to use Java Library to access a database using Java objects. It is another abstraction layer above JDBC, which provides a more object oriented way of accessing the database. A typical usage example looks like this:

InfoAccess infoaccess = new SqlInfoAccess(props);
InfoBean infobean = infoaccess.get(type, id, readOnly);
Object value = infobean.getProperty(propname);

Collection<InfoBean> beans = infoaccess.query(type, filter, ordering, readOnly);

InfoAccess has support to

SourceForge.net Logo