Application configuration through JVM properties
The Java Virtual Machine of the application, or the application server that hosts it, is executed with JVM properties set using the -D command
Features
- The tool starting the JVM sets up the JVM properties for the process from its own state.
- Applications read individual properties using System.SetProperty().
- Applications can use System.setProperty() to set a property
Advantages
- Can set those properties which control the JVM itself
- Can set properties which control the application server (such as Log4J options).
- Can set application properties which must be read using System.getProperty()
Disadvantages
- On Unix, properties set with on the command line are visible to all users.
- No hierarchical configuration tree.
- Properties are usually set and read once only, on application startup.
- Not thread-safe: properties are shared across all threads running in the same process, which, in an application server, means all web applications.
- Security managers can raise exceptions when programs try to read properties.
SmartFrog Support
This is one of the key ways that SmartFrog can configure Java applications, because it does not require any changes to the application itself. The Java process is executed with all system properties defined, which can tune both the JVM and pass information down.
Here is an example deployment of JBoss with some system properties for garbage collection (picked up by the JVM) and the application server (which is expected to pick up the jdbc. properties and make use of them)
Unknown macro: {code}
dbserver "database1.example.org";
server extends ServerBase:server
Unknown macro: { arguments [ "-c", config];
processName "jboss"; classname "org.jboss.Main"; classpath [ LAZY tools.jar, LAZY launcher.jar ]; gcInterval "3600000"; sysProperties [ ["sun.rmi.dgc.client.gcInterval",gcInterval ], ["sun.rmi.dgc.server.gcInterval",gcInterval ], ["jdbc.driver", MysqlBinding}
Java Test Runner support
The SmartFrog testharness has a helper class that extracts system properties. This adds a layer of indirection to allow alternate ways of setting properties, or optionally better logging. The getRequiredTestProperty() method is useful to pull required test properties into a test.
Unknown macro: {code}
/**
- get any test property; these are (currently) extracted from the JVM props
- @param property system property
- @param defaultValue default value
- @return the system property value or the default, if that is undefined
*/
public static String getTestProperty(String property, String defaultValue) {
return System.getProperty(property, defaultValue);
}
/**
- get any test property; these are (currently) extracted from the JVM props
*
- @param property system property
- @param defaultValue default value
- @return the system property value or the default, if that is undefined
*/
public static int getTestPropertyInt(String property, int defaultValue) {
return Integer.getInteger(property, defaultValue).intValue();
}
/**
Ant Support
To pass properties down to an Ant process, use the <sysproperty attribute
Unknown macro: {code}
<junit
fork="true"
forkmode="once"
errorProperty="system.test.failed"
failureProperty="system.test.failed"
includeAntRuntime="true"
>
<classpath refid="tests.run.classpath" />
<sysproperty key="test.classes.dir"
value="$
Unknown macro: {build.classes.dir}
"/>
</junit>
This sets the system property test.classes.dir to whatever the value of the Ant property build.classes.dir is.
Setting individual properties is very time consuming; it is often better to pass down a block of Ant properties:
Unknown macro: {code}
<syspropertyset>
<propertyref prefix="test."/>
</syspropertyset>
Such a propertyset is evaluated whenever it is used; it can be given an id and used across many tasks:
Unknown macro: {code}
<propertyset id="proxy.settings">
<propertyref prefix="http."/>
<propertyref prefix="https."/>
<propertyref prefix="socks."/>
</propertyset>
This propertyset can be used on demand; when passed down to a new process, all current ant properties that match the given prefixes are passed down, here propagating proxy settings from Ant to a <junit> run:
Unknown macro: {code}
<presetdef name="sf-junit">
<junit printsummary="no"
fork="true"
forkmode="once"
includeantruntime="true"
showoutput="true"
timeout="6000000"
>
<jvmarg value="-ea"/>
<jvmarg value="-esa"/>
<!-copy all proxy settings from the running JVM->
<syspropertyset refid="proxy.settings"/>
<!-- #Tests take system property parameters -->
<!-- #Formatters for capture and display -->
<formatter type="xml"/>
<formatter type="brief" usefile="false"/>
</junit>
</presetdef>