[fleXive] run-once and startup scripts provide an easy way for running customized code at application installation and server startup time inside the EJB container (documentation).
Today I checked in code that allows those scripts to be stored in any JAR file of your application (previously a build task had to index the files and store them under a unique path). This greatly simplifies the usage of those scripts in custom projects that do not use the distribution’s build infrastructure.
To execute run-once scripts from a JAR file, you have to:
- add a file named flexive-application.properties in the JAR’s root folder, and
- store the scripts under scripts/runonce and scripts/startup.
flexive-application.properties contains at least the application name and may provide additional information about your [fleXive] application:
# Application name
name=hello-flexive
displayName=Hello World Application
# The web application context root (if any)
contextRoot=war
For an example create a new project using the current version of our EAR archetype for Maven (instructions). In the “shared” module you find two scripts that will be executed at application startup time:
|– shared
| |– pom.xml
| `– src
| `– main
| |– java
| `– resources
| |– ApplicationMessages.properties
| |– flexive-application.properties
| `– scripts
| |– runonce
| | `– 01-runonce.groovy
| `– startup
| `– 01-startup.groovy
The implementation is based on a JarInputStream, the JAR filename is extracted from the URL of the flexive-application.properties resource. A simplified version is shown below:
[Update 2009/04/30: fixed the JAR read method. Apparently JarInputStream#read delivers data in arbitrary sized chunks, which was not really clear to me from looking at the documentation alone]
final Enumeration<URL> fileUrls =
Thread.currentThread()
.getContextClassLoader()
.getResources("flexive-application.properties");
while (fileUrls.hasMoreElements()) {
final String path =
fileUrls.nextElement().getPath()
.replace("/flexive-application.properties", "");
final JarInputStream jarStream =
new JarInputStream(new URL(path).openStream());
JarEntry entry;
while ((entry = jarStream.getNextJarEntry()) != null) {
if (!entry.isDirectory()
&& entry.getName().startsWith("scripts/startup/")) {
int offset = 0;
int readBytes;
while ((readBytes = jarStream.read(buffer, offset, (int) entry.getSize() - offset)) > 0) {
offset += readBytes;
}
if (offset == entry.getSize()) {
final String code = new String(buffer, "UTF-8");
// do something...
}
}
}
jarStream.close();
}
A new [fleXive] snapshot (build 937) is available in the downloads section.
It features full JBoss 5.0.0 GA compatibilty and includes the H2 database as optional database backend as well as Maven build support.
Who said JavaEE servers have to be resource hogs? It turns out that the combination of Jetty, OpenEJB and H2 mentioned in the Maven integration article is actually relatively lightweight in terms of memory usage (for a JavaEE application, that is).
While it required some fixes to get the [fleXive] content cache under control, a [fleXive] application including the backend clocks in at about 40 megabytes heap usage (Linux, 32 bit). Looking at the system resources reveals slightly less encouraging numbers, but still more than manageable even on a shared host:
25587 11335 158440 247972 30.4 4.7 /usr/lib/jvm/java-6-sun/bin/java -Xmx64M -client -classpath /usr/share/maven2/boot/classworlds.jar -Dclassworlds.conf=/usr/share/maven2/bin/m2.conf -Dmaven.home=/usr/share/maven2 org.codehaus.classworlds.Launcher “jetty:run” “-Dflexive.cache.config=cacheconfig.xml”
This means about 150 MB of memory for the web and EJB containers, the (in-process) H2 database engine, all flexive libraries (about 30 MB in compressed JAR files), and the cluster-enabled JBoss Cache.
Since Maven and Jetty already consume about 70 MB of memory right after startup (I assume most of it is on Maven), it should be possible to reduce memory usage considerably by launching Jetty outside Maven (but then I’d lose the convenient dependency injection, so I left it at that for now).
A tested snapshot of the current development branch has been released ([fleXive] download page, browse Sourceforge release).
This release offers two major new features over 3.0 (still under development, but definitely usable!):
- A database backend for the H2 database engine, which provides a pure Java database environment (either file or socket based). All but one of our 700+ testcases succeed on H2, so I’d call it pretty polished by now.
- OpenEJB (3.1) support, which is also the container used for unit and integration testing (run “ant tests.all” on the [fleXive] sourcetree).
A major meta feature is of course the Maven support mentioned in the last post – Maven support has been added for all released [fleXive] versions, including 3.0 and 3.0.1.