Almost every WebObjects project has a build.properties at its root, and most have collected keys over the years from tools that have come and gone. This guide describes what the file is for today: the keys a modern project uses, what each means and which tool reads it, and, separately, every legacy key you're likely to find, with what replaced it.

"Modern" here means a project built with vermilingua, edited with Parslips, and, for WebObjects applications, running on wonder-slim. It describes wonder-slim 8.0.12, vermilingua 1.1.10 and the current Parslips.

1. What belongs in it

build.properties holds facts about the project that tools need without running it: what the project is called, whether it's an application or a framework, which class starts it, how its templates are written, and how the built application is launched and deployed. The build reads it, the editor reads it, and so does the framework when an application runs from its project folder.

Configuration of the running application, the port, the database, logging levels, belongs in the application's Properties. A rule of thumb: if a deployed application should be able to change it without being rebuilt, it isn't a build.properties key.

It's a plain Java properties file, one key=value per line, next to pom.xml. These read it, each for its own keys, ignoring the rest:

ReaderWhenWhat it takes from the file
vermilinguaBuilding and deployingThe bundle's name, the application's main class, how the launch script starts the JVM, and where to deploy. It refuses to build a project without the file.
ParslipsEditingWhether the project is WebObjects or ng-objects, how its templates write bindings, and whether it's an application it can launch.
ERFoundationRunning from the project folderThe project's name, whether it's an application or a framework, and its principal class. This is how a project open in Eclipse becomes a bundle without being built into one.
wonder-slimStarting an applicationOnly whether the file exists (see section 4).

ng-objects applications don't read the file at runtime; for them it's the build and the editor that do. Older readers, WOLips and its Ant builds, and the wolifecycle Maven plugin, account for most of the legacy keys.

A build.properties with keys like bin.includes, source.. and output.. belongs to an Eclipse plugin project, which uses the same name for an unrelated file. Nothing here applies to it.

2. The modern file

This is a complete build.properties for an application, every current key included. Only the first four are required; the rest are there when the project needs them.

# What the project is (required)
project.base=wo
project.name=MyApp
project.type=application
principalClass=com.example.Application

# How its templates write bindings (only when not the defaults)
component.inlineBindingPrefix=$
component.inlineBindingSuffix=
component.wellFormedTemplateRequired=true

# How the built application's launch script starts the JVM
launch.jvm=/opt/jdk-25/bin/java
launch.jvmOptions=-Xmx2g

# Where vermilingua:deploy ships it
deploy.monitorHost=https://javamonitor.example.com
deploy.appName=MyApp

Most projects need only this:

project.base=wo
project.name=MyApp
project.type=application
principalClass=com.example.Application

A framework has no main class, so three lines:

project.base=wo
project.name=MyFramework
project.type=framework

That's what Parslips writes when it creates a project.

3. The current keys

What the project is

KeyRead byMeaning
project.base requiredParslipswo for WebObjects, ng for ng-objects. It tells the editor which elements and components exist and how templates are validated. Without it, Parslips looks at the classpath and usually guesses right; with it, there's nothing to guess.
project.name requiredvermilingua, ERFoundation, ParslipsThe bundle's name: MyApp gives MyApp.woa, and it's the name the bundle has at runtime, in development and deployed alike. Without it vermilingua takes the Maven project's <name>, and a project running from its folder takes the folder's name, with a warning, so the two can drift apart. A missing name is the usual cause of "main bundle not found" when launching from Eclipse.
project.type requiredERFoundation, Parslipsapplication or framework. When the project runs from its folder, it decides whether it becomes the application's main bundle or a framework bundle. vermilingua goes by the pom's <packaging> instead, woapplication or woframework, so keep the two in agreement.
principalClass applicationsvermilingua, Parslips, ERFoundationFor an application, the fully qualified class with its main(). vermilingua writes it into the bundle's config.txt, where the launch script reads it, and won't build an application without it. Parslips takes a project with a principalClass to be an application, and creates its Eclipse launch configuration from it. A framework may name one too, the class loaded when the framework is, but wonder-slim frameworks take part in startup as plugins instead (see How an application starts).

How templates write bindings

For the editor: Parslips reads these to parse and validate the project's templates. They change nothing at runtime, and a key set to its default can be left out.

KeyDefaultMeaning
component.inlineBindingPrefix$What marks an inline binding's value as a key path rather than a literal, as in value="$name".
component.inlineBindingSuffixemptyWhat ends one. A project writing value="[name]" would set the prefix to [ and the suffix to ].
component.wellFormedTemplateRequiredthe workspace preferencetrue to require well-formed templates, every element closed.

Launching: launch.*

vermilingua writes these into the built bundle's config.txt, and its launch script reads them to start the JVM.

KeyDefaultMeaning
launch.jvmjavaThe java to run, when it isn't the one on the PATH, as in /opt/jdk-25/bin/java.
launch.jvmOptionsemptyArguments for the JVM, as in -Xmx2g. The --add-exports and --add-opens arguments WebObjects needs on a modern JDK are added for you, unless they're already there.

Deploying: deploy.*

Read by vermilingua:deploy, which ships a build to JavaMonitor; the deployment guide covers it in full.

KeyDefaultMeaning
deploy.monitorHostnoneThe JavaMonitor to deploy to: a host name (port 56789), host:port, or a full https:// URL for a JavaMonitor behind a front end.
deploy.appNamethe bundle's nameThe application's name in JavaMonitor, when it differs.
deploy.passwordnoneJavaMonitor's password. Pass it as -Ddeploy.password=…; it has no place in a file you commit.

Per environment and on the command line

The launch.* and deploy.* keys can be set at three levels when building, a later one winning:

  1. build.properties,
  2. build.properties.<env>, when building with -Dbuild.env=<env>: a file holding only what differs in that environment, say build.properties.prod,
  3. a system property, as in mvn package -Dlaunch.jvm=….

And a built application can still be started with different ones: ./MyApp -launch.jvm=… overrides what the bundle was built with.

4. When the file's presence matters

wonder-slim takes a build.properties in the directory an application starts in as the sign that it's running from its project folder, in development, rather than from a built bundle. It turns on development mode, which among other things shows source code on the exception page, and has NSBundle load the application, and the framework projects open alongside it, from their project folders. The console says which it found:

== build.properties found. Setting development mode. Setting NSProjectBundleEnabled=true ==

A built .woa contains no build.properties, and its launch script starts the application inside the bundle, so a deployed application runs in production mode without any configuration.

5. Legacy keys

Everything else comes from WOLips' Ant builds, the wolifecycle Maven plugin, or Project Wonder's own build scripts. WOLips writes most of these into every project it creates, which is why they're everywhere. Nothing in a modern project reads them, and each can be removed, or, where it has one, replaced by its current equivalent.

KeyRead byWhat it didToday
jvm
jvmOptions
vermilingua (with a warning), wolifecycle, WOLips' Ant buildThe JVM and its arguments for the launch script.Renamed launch.jvm and launch.jvmOptions.
jdb
jdbOptions
wolifecycleRunning the application under the command-line debugger.Removed from vermilingua; debug through JDWP from your IDE.
framework.name
application.name
ERFoundation, WOLipsThe name and the type in one key.project.name and project.type.
classes.dirWOLips, its Ant buildWhere compiled classes go: WOLips' own build output, and the Ant build's.Maven's target/classes. Keep only if you still build with WOLips.
project.name.lowercaseWOLips' Ant buildThe project name in lower case, which WOLips keeps next to project.name for its Ant build.Remove.
cfBundleID
cfBundleVersion
cfBundleShortVersion
WOLips' Ant buildThe identifier and versions written into the built bundle's Info.plist.The version comes from the pom; nothing reads the identifier. Remove.
javaVersionWOLips' Ant buildThe Java version the Ant build records for the bundle, typically 1.5+.The pom's maven.compiler.release decides what the code is compiled for. Remove.
customInfoPListContentWOLips' Ant build, wolifecycleExtra entries appended to the generated Info.plist.vermilingua generates a minimal Info.plist and doesn't use it. Almost always empty; remove.
eoAdaptorClassNameWOLips' Ant build, wolifecycle, ERFoundationFor a framework providing an EOF adaptor, the adaptor's class, recorded in its Info.plist.vermilingua doesn't carry it. Almost always empty; remove.
webXML
webXML_CustomContent
WOLips' Ant buildGenerating a web.xml, and extra content for it, to deploy the application as a servlet in a .war.vermilingua doesn't build .war files. Remove.
embed.Local
embed.System
embed.User
embed.Network
embed.Project
WOLipsWOLips' "Embed Frameworks" setting: whether frameworks from each of WebObjects' framework locations are copied into the built application.Frameworks are Maven dependencies, packaged with the application. Remove.
project.principal.classProject Wonder's Ant buildThe principal class, as Wonder's own build scripts name it. Found in frameworks that started from Wonder's.principalClass, where one is needed at all. Remove.
dependenciesERFoundationA comma-separated list of the bundles the project requires, for a project running from its folder.The pom's dependencies. Remove.
servletDeployment
javaClient
javaWebStart
eogeneratorArgs
version
wo.version
projectFrameworkFolder
WOLipsProject settings WOLips keeps: servlet deployment, Java Client and Web Start, EOGenerator's arguments, the project's and WebObjects' versions, a folder of project frameworks.Remove.

ERFoundation also reads a woantbuild.properties in place of build.properties when a project has one, a leftover from older Ant setups. A project that has both should keep only build.properties.

6. Bringing a project up to date

  1. Make sure the four required keys are there: project.base, project.name, project.type and, for an application, principalClass.
  2. Rename jvm and jvmOptions to launch.jvm and launch.jvmOptions, and drop jdb and jdbOptions.
  3. Remove the component.* keys that are set to their defaults.
  4. Remove every legacy key, keeping classes.dir only if the project is still built with WOLips.
  5. Build with vermilingua and launch from Eclipse once, and check that the bundle is named as before.

The result is usually four lines where there were fifteen.