UNIX Bash: Create incrementally numbered directories
The Problem
You would like to be able to create UNIX directories with numerical names, which increase incrementally, for instance:
0000 0001 0002 0003 etc.
The Solution
Just execute the following bash script in a directory, which contains at least the subdirectory ’0000′. The script will create a new directory with a numerical name with trailing zeros precisely being the last created directories name +1.
echo "=== Create new deployment dir ===" lastdir=$(ls -d [0-9][0-9][0-9][0-9] | tail -1) myvalue=$lastdir newvalue="0" while [ "$newvalue" != "$lastvalue" ] do newvalue="$(echo $myvalue | sed 's/^0//')" lastvalue=$myvalue myvalue=$newvalue done echo "Last created dir: $lastdir" lastdirnr=$newvalue newdirnr=$((($lastdirnr) + 1)) newdir=$(printf "%04u" $newdirnr) echo "Create new dir: $newdir" mkdir $newdir
References
(there was one more post I got the ‘ls’ and ‘printf’ part from but I cannot find it at the moment
)
Run a Background Unix Process (even if user is disconnected)
Given we have a script test.sh, it is easy to run this script in the background while continuing to work in the current shell session. The most cited way is by adding ‘&’ to the end of the command:
./test.sh &
However, this approach has one major disadvantage: When the shell session of the user is disconnected or ended in any way, the script we have started in the background will cease to work.Luckily, it is quite easy to start a process in a way, which will prevent the process from ending upon an error with the current user’s session: meet nohup. Using the nohup command, we can start the background script as follows …
nohub ./test.sh &
… the the process will continue to run even if the shell session ends.
Depending on your OS it can be a bit tricky to ‘find’ the process again. You may want to try the following commands to get the process id of your nohub process:
ps -A sudo ps -A
Note: Depending on your use case, it might be a better idea to install a UNIX daemon instead of using nohub.
Resources
Unix Nohup: Run a Command or Shell-Script Even after You Logout
stackoverflow.com: What’s the difference between nohup and a daemon?
Java NIO HttpClients
Java’s non-blocking IO (NIO) is a complex, yet amazingly powerful addition to Java to build scalable and performant network applications. The capabilities of Java NIO are particularly impressive if compared with alternative ways in the JRE to connect to web resources over http. Here is a small collection of libraries and tutorial, which can aid in building asynchronous Java NIO based http clients.
Open Source Projects
| Project | License | Dependencies |
| Async Http Client | Apache 2.0 | Netty 3.9.1 |
| httpnio | LGPL | None |
| NIO Framework | LGPLv3 | None |
Tutorials/Examples
High-Performance I/O with Java NIO: Nice tutorial with lots of code samples
The Rox Java NIO Tutorial: Great in-depth tutorial, including examples for SSL
SSL Echo Client and SSL Echo Server: SSL Client/Server example using NIO Framework listed above.
Java NIO Tutorials by Jakob Jenkov: Great tutorials to get started with Java NIO
SSL NIO from onjava.com: In depth discussion on SSL and NIO
Debugging StackOverflowExceptions in Java
Problem
StackOverflowExceptions in Java and in other programming languages can be notoriously difficult to debug. The most troublesome attribute of these exceptions is that they occur in no specific place in the application. In specific, the location (class+line number) in which the exception is thrown does only point indirectly to the erroneous part of the application.
For instance, the StackOverflowException reported in the following stack trace …
Exception in thread “pool-1117-thread-1″ java.lang.StackOverflowError
at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(Unknown Source)
at java.util.concurrent.locks.ReentrantLock.unlock(Unknown Source)
at one.utils.jre.concurrent.JreConcurrency$4.unlock(JreConcurrency.java:146)
… has the same cause as this stack trace:
Exception in thread “pool-1115-thread-1″ java.lang.StackOverflowError
at java.lang.String.endsWith(Unknown Source)
at mx.gwtutils.MxroGWTUtils.assertNoSlash(MxroGWTUtils.java:311)
at nx.core.nodes.v01.ReferenceData.<init>(ReferenceData.java:34)
at nx.core.Nx.reference(Nx.java:156)
Solution
The first sensible action is to run the application multiple times and identify common patterns in the reported stack traces. In particular, the overflow exception is most likely caused by an undesired recursive loop involving one or multiple method calls. The first case can usually easily be identified from the stack trace. For instance, in the following example there is probably something wrong with line 36 in the tested class.

The latter case, that of multiple involved method calls, is often the more interesting (to use a daring euphemisms). For instance, a recursive loop might occur in the following constellation:
method 1 -> method 2 -> … -> method 40 -> method 41 -> method 1
In this case, it is significantly more difficult to find the original cause of the problem, since, theoretically, the cause might be in any of the involved methods.
The useful construct ‘assert’ in combination with the capabilities of Java Exceptions can be of great help to pinpoint the error leading to undesired recursion. The following guard will check that the total depth of the stack trace is below a sensible threshold (in the example 799 nested method calls). If this threshold is violated, the application will terminate with a message hopefully of greater aid than Java’s StackOverflowException.
assert new Exception().getStackTrace().length < 800 : “Stack overflow for message: “+ message;
Adding a number of such asserts in the methods involved in the stack overflow can greatly speed up the process of identifying the cause of the error.
Notes
- Asserts will only be evaluated when the JVM is started using the argument ‘-ea’
- While asserts should be disabled by default in production deployments and therewith the additional guards inserted in the code should not affect application performance, the performance penalty of getting a stack trace in Java (new Exception().getStackTrace()) is very high. Therefore, one might consider adding an additional Boolean flag to these asserts to assure they are only invoked when one is actively searching for the cause of StackOverflowExceptions.
GWT Serialization: ‘Expected type ‘int’ but received an out-of-range value’
Problem
While the GWT application works fine in development mode, it reports a mysterious NumberFormatException exception in production mode upon deserialization of an RPC on the server side.
java.lang.NumberFormatException: Expected type ‘int’ but received an out-of-range value: -43400113595222000
at [..]ServerSerializationStreamReader.getNumberFormatException(ServerSerializationStreamReader.java:839)
Analysis
Apparently Java and JavaScript have a different definition of the capacity of the type int. JavaScript integers can hold larger values than allowed by Java integers. While usually testing the application in an Java environment can easily spot integer overflows occurring for Java integers, generated integer values can cause problems in some special cases. In specific the algorithm employed by GWT to calculate the hash codes of objects (Object.hashCode()) is prone to produce integer values, which exceed the maximum value for integers in Java. If this occurs, abovementioned exception might be cast during deserialization of incoming Objects with int fields.
Solution
First it boils down to finding the ‘int’ field of the serializable object, which is sent over the RPC wire, causing the exception. Unfortunately the exception provided by the GWT deserialization logic is not very helpful in this cause. A good starting point is to search for integer fields containing hash codes. For instance using the eclipse search as shown below:

After the integer field causing the overflow has been located, all assignments to this field must be checked whether they might cause a too large ‘int’ value to be assigned. For instance, the following assignment might lead to such a faulty assignment:
this.versionHash = this.generateHashCode();
Adding a binary mask to this assignment makes it ‘safe’ in preventing integer overflows:
this.versionHash = this.generateHashCode() & 0xffffffff;
Resources
GWT: ‘A widget that has an existing parent widget may not be added to the detach list’
Problem
When wrapping an existing DOM element with a GWT widget (e.g. Button.wrap(…), HTML.wrap(…), etc), the GWT module will not load and report the exception like the following:
java.lang.AssertionError: A widget that has an existing parent widget may not be added to the detach list
at com.google.gwt.user.client.ui.RootPanel.detachOnWindowClose(RootPanel.java:136)
at com.google.gwt.user.client.ui.Label.wrap(Label.java:130)
Analysis
In GWT it does not seem to be possible, to wrap an element in the document’s DOM if any of its parents has been wrapped with a GWT widget before. For instance, see for the following HTML document …
<div style=”display: none” id=“outer_element”>
<form class=“well”>
<label><i class=“icon-exclamation-sign”></i> An error occurred while requesting your API key.</label>
<div id=“inner_element”>No error message.</div>
</form>
</div>
… if we first wrap the element “outer_element” and then the element “inner_element” as in the following …
final HTML errorForm = HTML.wrap(DOM.getElementById(“outer_element”));
final Label errorMessage = Label.wrap(DOM.getElementById(“inner_element”));
.. an exception will be thrown, since “outer_element” is the parent in the DOM of “inner_element“.
Solution
The exception can easily be prevented by wrapping DOM elements as GWT widgets from the inside out. So, the elements nested the deepest in the DOM will be wrapped first. Therefore, the example above will work smoothly, if the order in which the elements are wrapped is reversed, so that the inner element “inner_element” is wrapped before the outer element “outer_element“.
// inner element must be wrapped BEFORE outer element
final Label errorMessage = Label.wrap(DOM.getElementById(“inner_element”));
final HTML errorForm = HTML.wrap(DOM.getElementById(“outer_element”));
References
gwt – How to add a custom widget to an element – Stack Overflow
How to wrap an existing div into an HTML widget ? – Google Web Toolkit | Google
Amazon EC2 Micro Instance Roundup
Since some time now, Amazon offers a free (for 1 year) Micro Instance in their cloud for new sign ups. Micro instances are widely discussed as easy and relatively cheap way to run a cloud-based application (e.g. website/blog). Below a collection of a number of links regarding Amazon’s Micro instance hosting.
Some Fundamental Components
Amazon Elastic Compute Cloud (Amazon EC2): Who came up with this product name? It’s a VPN hosting service, allowing you to run UNIX/Windows virtual machines on the Amazon servers.
Amazon Elastic Block Store (EBS): Amazon offers 10 GB of EBS storage for free as part of the micro-instance. This storage is external to your instance, which is nice, since the data is available when you shutdown/restart the instance or switch to a completely new image.
Amazon Simple Storage Service (Amazon S3): 5 GB for free are offered for the Amazon S3. This is another way to store data external to your instance. However, in difference to the EBS, which can be mounted simple as a node in a unix file system, S3 requires one to use Amazon’s S3 access API.
Performance and Pricing
“Amazon EC2 Micro Instance and Stolen CPU“: Cheap, but sometimes slow. In particular, if the CPU is heavily used for a few seconds, an automatic throttling might occur.
“Amazon EC2 “micro instances” vs. Google App Engine“: EC micro not necessarily cheaper than GAE, especially when considering additional costs for EBS storage.
“What is the real price of an Amazon EC2 machine?“: Some consensus that EC is rather expensive.
“Amazon EC2 Micro instances deeper dive“: Calculates that a micro instance gets ca. ¼ of the allocation of a small instance. Suggests that rackspace and other competitors have better offerings.
“WordPress at Amazon For $10 a Month“: Shows how to build up a website on the Amazon infrastructure costing only $10 a month.
“Deploying node.js on Amazon EC2“: Estimates to run a node.js server would cost about $15 a month using a micro instance.
Tutorials
“Amazon EC2 Cloud Installation.“: A nice tutorial walking through the various steps in setting up a micro instance.
“Quick start to using Amazon EC2 as a free VPS!“: Gives a good introduction to various aspects of setting up a micro instance.
“A LAMP guy’s n00b quick start to Amazon Web Services” Some discussion here on EBS storage vs. instance level storage.
Others
“Amazon Linux vs. Ubuntu for Amazon EC2“: Amazon Linux seems to be running okay. However, maybe it’s better to stick with a more ‘standard’ distribution.
Inside GWT RPC: Understand and Use the Serialization Format
GWT RPC is a technology with both great promises as well as many practical pitfalls. On the one hand, GWT RPC magically handles the transport of objects from a Java server to a JavaScript based client, without any need to create and maintain legacy data formats (e.g. in JSON). On the other hand, caused by the architecture of GWT RPC, it is easy to bloat up the size of JavaScript clients, since any for any object transported from server to client, the client needs a type-specific scaffold to instantiate the types in JavaScript. Calling eval(…), in contrast, is a much more lightweight solution. Moreover, serializing and deserializing large object graphs can be a performance hog, both for server and client.
Below a collection of a few interesting links, which can help in understanding GWT RPC better and using it beyond its initially devised use cases. In particular:
- To have a detailed understanding of how the GWT serialization format works on the inside (“Understand the GWT Serialization Format”),
- How to consume a GWT RPC service from a Java (JSE) client (“Consume GWT RPC using a Java Client”), and
- How to generate messages in the GWT serialization format using an environment different from the GWT provided servlet (“Generate Textual Representations of Java Objects using GWTs Serialization Format”)
Understand the GWT Serialization Format
Stackoverflow “GWT RPC data format”
This discussion provides details on the GWT serialization format, particularly by referring to this presentation. Looking at the format in detail, it indeed seems to resemble a remote method invocation protocol (RMI) rather than a sole remote procedure call protocol. This is not necessarily good, since a lot of meta-data has to be sent with every request (e.g. class on which method is to be invoked).
Consume GWT RPC using a Java Client
Stackoverflow “Invoke a GWT RPC service from Java directly”
It appears that attempting to consume GWT RPC services from Java clients has mostly been pursued for testing purposes. However, it seems that some of the discussed libraries might be out-dated and might necessarily work with the most recent version of GWT (since the GWT serialization format can change from version to version).
Generate Textual Representations of Java Objects using GWTs Serialization Format
Simpler and Speedier GWT with Server Side RPC Serialization – TechHui
This article describes how data can be serialized using GWTs server side serialization and written into the initially downloaded HTML. This can speed up startup time of applications, since it leads to a reduction of RPC calls. I am not quite sure but there might have been mention of this technique in one of the Goolge IO talks on GWT performance. There can be other use cases for attempting to do the GWT serialization ‘by hand’, for instance if one wants to avoid using a Servlet container (tomcat, jetty) and replace it by something nicer like netty. The JavaDoc of the following classes are a good starting point to explore further how to perform GWT serialization Google Web Toolkit JavaDoc Class RPC, Restlet JavaDoc Class Object Representation
Xtend Tutorial
The world is rife for a new dominant programming language! Actually, has been rife for a couple of years, which, however, does not stop Java and C++ from dominating the screens of many unfortunate developers. Apart from the inarguably impressive features offered by ‘new’ languages, such as Scala, Goovy, Ruby, Haskell, Clojure, Dart? and Go, I am highly suspicious of these languages: What happens to the billions of lines of code written in legacy programming languages? Will my Groovy app work with the next update of Groovy, or will it work in 10 years, when I have to update my app? I don’t want something big, not the total reinvention of computing but would already be happy with more concise syntax to create inline objects, type inference and simple closures.
Xtend defines itself as a language for Java developers. In specific, it allows to write code, which is similar to Java but improved in many ways. Compiling code written in the Xtend language generates Java source files. These files can easily be used with any ‘legacy’ Java application or library. I have assembled a little tutorial and introduction to get started with the Xtend language. Find below:
- How to install the Xtend Eclipse Plug-in
- How to materialize Xtend Example Project in your Workspace
- How to create Your Own Xtend Project
- A discussion of Xtend Advantages and Disadvantages
- Conclusions
Install the Xtend Eclipse Plug In
UPDATE: As Daniel pointed out below, Xtend is now available on the Eclipse Marketplace. Installing it from there rather following the instructions in this section, might be much easier!
- Open the install new software dialog in eclipse
- Connect to the XText release repository: http://download.eclipse.org/modeling/tmf/xtext/updates/composite/releases/
- Select all packages “TMF Xtext-2.1.0″ (or of a newer version if available)
- This includes the “Xtend2 SDK” mentioned in the Xtend tutorial. The other packages need to be selected since otherwise the Xtend editors will not work.

- Click Next again
- Accept EPL licence agreement
- Restart eclipse
Materialize Xtend Example Project in your Workspace
After the installation of Xtend is complete, the best way to get started is to install the Xtend example
- Create a new Example Project as shown below

- Or under the new project wizard select “Examples / Xtend Examples / Xtend Tutorial”

- Initially the project was not built correctly in my eclipse.

- However, after closing and reopening the project everything appeared to be (maybe the Infinitest plugin in my installation has caused the problem, so I have deactivated it).
- Below a screenshot of the examples provided by Xtend:

- You can right click the project and select “Run as JUnit test” to execute some of the examples

Create Your Own Xtend Project
After browsing and testing the provided examples, it’s time to create a new project with Xtend support.
Xtend seems to be nicely integrated with the eclipse PDE. Therefore, its easiest to create an Xtend project as eclipse Plug In Project. Using the PDE tooling such projects can be easily deployed as executable applications on numerous platforms. However, since Xtend generates plain Java files, we can always compile the generated files as independent Java application. Below the steps to create a simple Hello World application.
- Use Eclipse’s New Project Wizard to create a new ‘Plug-in Project’
- Adjust the source folder and output folder to sensible values (Maven anyone?) and create the project

- Open the MANIFEST.MF file in the folder META-INF
- Add the package org.eclipse.xtext.xtend2.lib to the [Imported Packages] on the [Dependencies] tab

- Also add the following packages:
com.google.inject
org.aopalliance.aop
org.eclipse.xtext.base.lib

- Create a new source folder for your project: src/main/xtext (Right click the project and select Build Path / New Source Folder)
- Now create a new package in the source folder src/main/xtext
- For instance, de.mxro.examples.xtend1
- Right click this package and select New / Xtend Class

- Select the name “HelloWorld”
- When prompted to add the Xtext nature to the project, click [Yes]

- Right click your project and select “Properties”
- Open the properties for Xtend / Compiler
- Change the output folder to src/main/java and deselect “Override existing files”
- Click [Apply] to apply the changes

- Go back to your file HelloWorld.xtext and define the following class:
class HelloWorld {
def public void helloWorld() {
val message = “Hello, World!”;
System::out.println(”’«message»”’)
}
}
Tip: writing the symbol “«” can be achieved by pressing CTRL + SHIFT + < (or ,)
- Now check the folder src/main/java. Here, a file HelloWorld.java should have been generated as follows
import org.eclipse.xtext.xtend2.lib.StringConcatenation;
@SuppressWarnings(“all”)
public class HelloWorld {
public void helloWorld() {
final String message = “Hello, World!”;
StringConcatenation _builder = new StringConcatenation();
_builder.append(message, “”);
System.out.println(_builder);
}
}
Does not look 100% efficient but that’s the tradeoff for source code generation. I did not find out how to define static methods using Xtend, so we need a standard Java class to run this code:
- In the source folder src/main/java add a Java class “Application”, while checking create main(String[] args).
- Implement the following class
public
class Application {
/**
* @param args
*/
public static void main(String[] args) {
new HelloWorld().helloWorld();
}
}
- Right click the file Application.java and select “Run as Java Application”
Volia! You should be friendly greeted with the output “Hello, World!”

Xtend Advantages and Disadvantages
After following this little exercise and browsing the Xtend documentation, these are a number of advantages and disadvantages I see in this languages:
Advantages
- Allows writing more concise code for the Java platform.
It is no secret that Java syntax is unnecessarily verbose. This sets the bar relatively low for better languages for the Java platform. Xtend has a number of very nice features to allow writing more concise Java code, my favourite example being type inference.
- Is fully compatible with most Java technologies.
Although the JVM has received considerable attention with alternative Java byte code generating languages such as Scala, not everything Java is Java byte code. Most notably, the Android platform draws on the Java language but is not compatible with generated Java byte code. The Google Web Tookit (GWT) is another technology working with the Java language but not with the JVM. Xtend enables to write code, which interoperates both the platforms build on top of the JVM (since its Java source files can be compiled into byte code) as well as platforms build on top of the Java language syntax.
- Performance
Since the Xtend language is close to the Java language and generates relatively optimal Java source files, its performance can be expected to be far superior to other improved Java dialects, especially Groovy. Moreover, since it does not generate byte code but Java source files, more compiler optimization can be applied to the applications.
Disadvantages
- Tight coupling with eclipse tooling
Xtend and Xtext are doubtlessly eclipse technologies through and through. This is a definite advantage for starting to use these technologies since they offer nice integration with the eclipse IDE. As a downside, however, code written in the Xtend language might be difficult to use with other tools apart from eclipse. On the other hand, the Java code generated by Xtend is vanilla Java code (apart from the lightweight Xtend library used in the generated code). This code, of course, can be used by most other tools. Therefore, I have chosen above to place the xtend source files not in the main Java source code folder of the project (src/main/java) but into a separate folder (src/main/xtext). This enabled to let Java code be generated into the src/main/java folder. From there, it can be picked up and used by other tools such as Maven.
- In places, insufficient documentation
The documentation available for Xtend is far from extensive. In comparison, the documentation available for Groovy is extensive including books and various web sites.
Conclusion
I believe that Java and C++ are the very best programming languages around. Not in terms of developer productivity, measured in implemented features/hours of course, but in terms of creating sustainable code. Most Java or C++ applications written a decade ago will still run today. Java programs even without the need to be recompiled. This makes one rather confident that a decade from now, still people will be able to compile and run written in Java and C++ today. Adopting terms from the finance industry, they are simply too big to fail.
Give that, I am very suspicious of any new programming language. That is it more elegant and allows me to be more productive are simply insufficient arguments. Code is too difficult to write that I would want to run into the risk of having to dump it ever. Xtend offers a neat compromise. It allows to write code in a more modern, more productive language but yet defining the application in plain old Java code. Therefore, I see Xtend primarily as a useful tool to generate Java tool. Even if Xtend becomes deprecated at some point in time, one always has the Java code to fall back to.
Mistakes to Avoid
As mentioned above, installing the plugin following the documentation provided on the Xtend tutorial page has not been a smooth process. Below a number of mistakes in installing the plugin, which are better avoided.
Do not install only the Xtend2 SDK
Installing only the Xtend 2 SDK package as shown below …

.. and creating a new class …

… will result in a problem being reported by Xtend.

Do not Install the Xpend/Xtend All-in-One Package
Selecting “Xpand/Xtend All-in-One” …

… with all these packages …

… will not allow you to create the Xtend example project.
Do Not Create an Xtext Project to Start an Xtend Project
Xconfused? An Xtext project does not automatically allows to get started with Xtext. It is better to create an eclipse Plug-in project as shown above.

References
Xtend 2 – the Successor to Xpand post by creator Sven Efftinge
Key-Value Stores for Java
One common theme in discussions of persistence is to be critical of the traditional SQL databases, which have been successfully used in business applications for decades. As alternative to these SQL databases, often so called NoSQL solutions are advocated. NoSQL, essentially, dramatically simplifies the kind of data, which can be managed by the database. Often, a simple key-value store is at the heart of the database. Such stores allow the user to store data in a similar way as it has long been known for the Map data structure. However, whereas the traditionally Maps have been used in-memory, e.g. to hold data temporarily, which fits on one system’s memory, NoSQL key value stores are designed to persist and scale up to millions or billions of key-value records, distributed among potentially thousands of servers. As can be expected, in the Java space, there is not one all-encompassing NoSQL solution but various (mostly free and open source) offerings compete with varying features.
In the following I discuss two categories of implementations:
- Object Prevalence engines: which assure objects stored in memory are never lost and constantly backed up onto a hard disk.
- Persisted Databases engines: which allow to work with key-value databases, which are larger than the systems memory by persisting parts of them onto a hard disk (or another persistence backend).
Object Prevalence
Object Prevalence systems keep all records in-memory. However, they are designed to keep a synchronized persisted copy of all objects on the hard disk. In case of a system failure or reboot they therewith can easily restore the state before the interruption. Object prevalence systems are often used to speed up applications, for which all required data can be stored in memory (Villela, 1st of August 2002).
One prominent example of an object prevalence system is the open source solution Prevayler (http://prevayler.org). A significant limitation for such object prevalence systems is, of course, that the amount of data the application can work with is limited to the memory available on one server. To allow systems to scale, an object prevalence system can be distributed among various systems. A very well-performing open source solution for this purpose is hazelcast (http://www.hazelcast.com/).
| Engine | Project home | Description |
| Prevayler | http://prevayler.org | Lightweight solution to build prevalent systems. |
| Space4j | http://www.space4j.org/ | Keeps an incremental record of all operations saved on disk in order to recreate a state in memory (but also has the option to create snapshots). |
| MegaMap | http://megamap.sourceforge.net/ | Allows to work with Maps larger than the memory and persist these onto disk. However, not developed for a while and not fault tolerant. |
| hazelcast | http://www.hazelcast.com/ | Allows to distribute objects held in memory among a cluster of physical systems (within a network or connected through WAN). |
Persisted Databases
While object prevalence systems are arguably one of the best performing solutions to store the data of an application, there are many use cases, in which data is only rarely accessed and therewith not required to be available in memory. For these purposes key-value stores, which keep only a fraction of their data in the memory are best suited. Below a number of examples implementing this pattern. To get started quickly, I think jdbm2 is a good option, for large scale solutions, you might have to consider Berkely DB – but this might end up being a pricy pathway.
| Engine | Project home | Description |
| jdbm2 | http://code.google.com/p/jdbm2/ | Persists a HashMap or TreeMap using Java Serialization. |
| Banana DB | http://people.apache.org/~kalle/bananadb/ | Persists a Map in a file. Potentially inefficient read operations. |
| BabuDB | http://code.google.com/p/babudb/ | Persists key-value pairs of byte[] values. |
| Berkeley DB | http://www.oracle.com/technetwork/ database/berkeleydb | Key-value store solution from Oracle. Rather restrictive open-source licence. |
| JOAFIP | http://joafip.sourceforge.net/ | Rather than providing a simple key-value store, JOAFIP attempts to dynamically persist an object tree to the disk (to manage object trees too large to fit into memory). |
Resources
JDBM
“HIVE-1754 – Remove JDBM component from Map Join” Apache Hadoop has removed the JDBM dependency from their codebase due to poor performance. However, they seem to have replaced the persistence backed map with a map solely in memory. So they did not really find a better alternative for JDBM but rather removed the necessity for file-based persistence altogether. The old implementation of JDBM used by them can be found in the source repositories: e.g. BaseRecordManager in hive-0.5.0, or how it was used in HashMapWrappper also in hive-0.5.0.
“JDBM2 released” Blog post with some additional info concerning JDBM2
SQL Alternatives
For an SQL database with a very low footprint and high performance see: http://www.h2database.com/
Other Resources
“An introduction to object prevalence” (Villela, 1st of August 2002)
“Anti-RDBMS: A list of distributed key-value stores” (Jones, 19th of January 2009)
“NoSQL Services Available” (Menon, 29th of March 2011)
“The Jalapeño Persistence Library for Java” (intersystems.com)
“POJO Persistence” (on this blog)
Prevayler (http://prevayler.org)
hazelcast (http://www.hazelcast.com/)