[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();
}