A project made with WOLips' wizards has the "Fluffy Bunny" layout, Sources, Components, Resources and WebServerResources at the top, and is built by Ant from build.xml, the woproject pattern sets and the WOFramework/… containers in .classpath. This guide moves it to a Maven build with vermilingua. The folders can stay where they are. Moving them to the standard Maven layout is a separate, optional step (section 6).

It started as a 2021 walk-through by Hugi Thordarson and Paul Hoadley, written for wolifecycle and Wonder 7.3. Everything here was checked on a fresh project from WOLips' Wonder Application template, with Wonder 7.4 and 7.5-SNAPSHOT, vermilingua 1.2.0 and JDK 25. Each setup was built and run both as a .woa and from the project folder.

1. Remove the Ant build

In Eclipse, delete the project from the workspace but leave the files on disk. Then, from the project folder:

git rm -r woproject build.xml .classpath .project
rm -rf bin build dist

The jars in Libraries become dependencies in the pom, next step. Delete the folder once they're there.

2. Add a pom

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>MyApp</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>woapplication</packaging>
  <properties>
    <maven.compiler.release>25</maven.compiler.release>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
    <dependency>
      <groupId>wonder.core</groupId>
      <artifactId>ERExtensions</artifactId>
      <version>7.4</version>
    </dependency>
    <dependency>
      <groupId>is.rebbi.slim</groupId>
      <artifactId>ERProjectLayout</artifactId>
      <version>8.1.3</version>
    </dependency>
  </dependencies>
  <build>
    <finalName>${project.artifactId}</finalName>
    <sourceDirectory>Sources</sourceDirectory>
    <plugins>
      <plugin>
        <groupId>is.rebbi</groupId>
        <artifactId>vermilingua-maven-plugin</artifactId>
        <version>1.2.0</version>
        <extensions>true</extensions>
      </plugin>
    </plugins>
  </build>
</project>

Every WOFramework/… entry in the old .classpath becomes a dependency. ERExtensions brings WebObjects itself, JavaWOExtensions, ERFoundation and ERWebObjects, so those need no entries of their own. Wonder's other frameworks are in the WOCommunity repository under the same names, most of them in wonder.core; Ajax is in wonder.ajax. Maven has to be pointed at that repository; the vermilingua guide shows how. A test folder, if there is one, goes in as <testSourceDirectory>Tests</testSourceDirectory>.

3. Rewrite build.properties

project.name=MyApp
project.type=application
principalClass=com.example.Application
dir.components=Components
dir.woresources=Resources
dir.webserverResources=WebServerResources

Keep the component.inlineBinding… and component.wellFormedTemplateRequired keys if your project sets them; the editor reads them. Everything else the wizard wrote (classes.dir, project.name.lowercase, embed.*, webXML, customInfoPListContent) is read only by the Ant build. The build.properties guide covers each key.

4. Register ERProjectLayout

public class Application extends ERXApplication {

	static {
		ERXProjectLayout.register();
	}
	…

It reads the dir.* keys, so in development the application finds its components and resources in the same folders vermilingua packages from. Without it, development depends on your Eclipse natures, and on Wonder 7.4 that goes wrong (section 7). wonder-slim registers it itself.

JDK 24 and later. WebObjects' NSTimeZone uses sun.security.action.GetPropertyAction, which the JDK no longer has. Wonder 7.4 then fails at start-up with NoClassDefFoundError: sun/security/action/GetPropertyAction, and 7.5-SNAPSHOT doesn't include the class either. Copy wonder-slim's replacement into Sources/sun/security/action/.

5. Build, import, launch

mvn package
./target/MyApp.woa/MyApp -WOPort 1200

Once that runs, use File → Import → Maven → Existing Maven Projects in Eclipse, and launch the application as a Java Application, as the launching guide describes. On Wonder 7.4, add -Dwebobjects.user.dir pointing at a built bundle to the VM arguments, for example the target/MyApp.woa that mvn package builds. Without it, start-up fails with a NullPointerException in ERXApplication$Loader.collectMainProps. 7.5-SNAPSHOT needs no arguments.

6. Optional: the standard Maven layout

mkdir -p src/main
git mv Sources src/main/java
git mv Components src/main/components
git mv Resources src/main/woresources
git mv WebServerResources src/main/webserver-resources
git mv Tests src/test/java

Then remove <sourceDirectory> and <testSourceDirectory> from the pom, and the three dir.* keys from build.properties, since these folders are the defaults. Note src/main/woresources: vermilingua packages bundle resources from there. src/main/resources, where wolifecycle and the old walk-through put them, is for the classpath, and a model there ends up in the jar, not in the bundle. If you use EOGenerator, update the model paths in your .eogen files.

7. Why ERProjectLayout

Without ERProjectLayout, the code that finds a project's resources in development is ERFoundation's, and ERFoundation decides the layout from the natures in .project. Wonder 7.4's ERFoundation 1.0 only recognises org.maven.ide.eclipse.maven2Nature, the m2eclipse nature from before m2e, which is why the old walk-through's .project had it. Even with that nature, it looks for models only in src/main/resources. 7.5-SNAPSHOT brings ERFoundation 1.2, which recognises the current m2e nature and both folders. Results from the test project, run from the project folder:

WonderLayout, without ERProjectLayoutIn development
7.4Fluffy BunnyWorks, as long as .project doesn't have the old nature.
7.4standardBlank pages, and No template found for component Main in the debug log.
7.4standard, old nature addedRuns, but a model in src/main/woresources isn't loaded, with no error. The built application loads it.
7.5-SNAPSHOTstandardWorks.

With ERProjectLayout registered, every one of these works, on 7.4 included. Development no longer depends on .project.

8. What the old walk-through needed that this doesn't

  • Hand-written .classpath and .project, and turning off automatic builds while you write them. The Maven import generates both from the pom.
  • The woproject pattern sets. vermilingua ignores them and packages the declared folders.
  • flattenComponents. vermilingua always flattens components, and a component in a subfolder was found both in development and in the bundle.
  • WOLips' Generate bundles. On Wonder 7.4, the bundle webobjects.user.dir points at comes from mvn package.
  • Overriding _sessionClass(), and ERXPatcher.setClassForName for Main. Didn't happen: Session and Main in their own packages were found in every run.