Software Builder Factories

One options set. Two factories. Apps that can sync.

What is a software builder factory?

One options set. Two chassis. Apps that can sync.

A software factory is a production line for applications. It is a repeatable build process, not a software-engineering process you run by hand each time.

As a car buyer, you do not design the car from scratch. You trust the engineering already in the factory. You pick make, model, and color. The factory stamps a working product from a shared chassis, a standard build process, and a short list of options.

SW-Builder works the same way. The software-engineering work went into building the factory. The customer gets a standardized product: pick the type of application, fill in options, and stamp it.

SW-Builder runs two factories from that idea. Droid Builder stamps native Android apps. WildFly Builder stamps Java EE / WildFly apps.

What makes the line unusual is that both factories read mostly the same option files. Shared options mean the apps share a data domain, so they can talk to each other and sync. That data is more than database characters. Take a picture or video on the phone, share it with the website, then share it with other phones running the same app.

Why call it a factory

Most generators emit one stack or one type of application. A wizard asks twenty questions and writes one project. A large language model scaffolds a repo that you then own by hand. A factory is narrower and more repeatable.

One product line. A few option files. A complete application.

The options file is the contract. It names entities, field types, and relationships. The template is the chassis: navigation, persistence, build files, the structure every app in that line needs. The snippet library is the parts bin. The extender is the station on the line that welds the optional pieces onto this particular car.

You keep the source. Build and deploy stay in the generated app repo. This is not a hosted low-code canvas. After the stamp, the app is a normal Android or WildFly project.

You can still extend it. Put custom work in Extender/ — logos, extra copy steps — and know that later factory upgrades can conflict with edits outside that directory. A future goal is an Apple phone app from the same option files.

The two chassis

Droid Builder and WildFly Builder share a domain vocabulary so the same product idea can exist on a phone and on a server without becoming two unrelated models.

When those apps are built from close to the same options, they can sync. Booklet on Android and Booklet on WildFly are cousins, not ports after the fact.

That is the point of putting both factories on one site. The App Store is not a random list of side projects. It is the showroom for one recipe run twice.

A worked example: Captain’s Log

The simplest way to show the contract is a small app. In Java that is Hello World. Here it is Captain’s Log: one table, log text and a log picture.

Live demo: https://sw-builder.com/captainsLog/do?op=Home (guest / guest).

WildFly roles on the demo: Admin, User, and Guest. Guest can see data and cannot change it.

Copy APP_ENUMS.xml, APP_NAMES.xml, and APP_TABLES.xml between the Android app and the WildFly app.
That is how the two products stay cousins.

Android layout

Clone Droid Builder and the app as siblings. Every Android catalog app uses the same factory. Clone the factory once.

~android/
├── droid-builder/
└── android-captains-log-app/
mkdir -p ~/android
cd ~/android
git clone [email protected]:Gator-Go/droid-builder.git

Place android-captains-log-app next to it. The stamp script assumes this layout because it overlays engineering from droid-builder/ into the app repo.

cd ~/android/android-captains-log-app
git pull
./android-captains-log-build.sh

Skip git pull on a fresh clone.

android-captains-log-app/
├── android-captains-log-build.sh
├── Extender/
│   ├── CaptainsLogExtender.groovy
│   ├── logo.png
│   ├── ldpi-logo.png
│   ├── mdpi-logo.png
│   ├── hdpi-logo.png
│   ├── xhdpi-logo.png
│   └── xxhdpi-logo.png
└── options/
    ├── APP_ENUMS.xml
    ├── APP_NAMES.xml
    └── APP_TABLES.xml

CaptainsLogExtender.groovy copies the density-specific logos. Android wants the same mark at several resolutions.

Options the Android stamp reads

Contents of APP_ENUMS.xml:

<appEnums>
</appEnums>

APP_ENUMS.xml is empty for this app. Topics for a log would live there if you added them.
Use this same APP_ENUMS.xml on the WildFly side.

Contents of APP_NAMES.xml:

<appNames>
  <appName newName="captainsLog" oldName="xxxxx"/>
  <appName newName="CaptainsLog" oldName="Xxxxx"/>
  <appName newName="CAPTAINS_LOG" oldName="XXXXX"/>
  <appName newName="Captains Log" oldName="XDXDXDXDX"/>
  <appName newName="CAPTAINS_LOG_APP" oldName="XSXSX"/>
  <appName newName="captainsLogApp" oldName="xsxsx"/>
  <appPackage newPackage="com.swBuilder.captainsLog.app" oldPackage="ppp.ppp.ppp"/>
  <appPackage newPackage="com/swBuilder/captainsLog/app" oldPackage="PPPsPPPsPPP"/>
  <appPackage newPackage="com_swBuilder_captainsLog_app" oldPackage="PPP_PPP_PPP"/>
  <appAuthor newAuthor="Ron Kanengieter" oldAuthor="Aaaaa"/>
  <appAuthor newAuthor="[email protected]" oldAuthor="aaaaa@ddddd"/>
  <appCopyright 
    newCopyright="Copyright (c) 2026 Ron Kanengieter\n * Licensed under the MIT License[](https://opensource.org/licenses/MIT)\n * Developed by sw-builder.com" 
    oldCopyright="Lllll"/>
</appNames>

APP_NAMES.xml rewrites the names Java, Android, and the database require. Package, author, email, and copyright are yours to change. Use your domain in the package if you have one. Use this same file under wildfly-captains-log-app/options/.
Use this same APP_NAMES.xml on the WildFly side.

Contents of APP_TABLES.xml:

<appTables>
  <appTable displayName='Captain's Log' objPlural='captainsLogs' classPlural='CaptainsLogs' objName='captainsLog' className='CaptainsLog' dbName='CAPTAINS_LOG' fileName='captainsLog'>
    <appField displayName='Log Picture' dbName='LOG_PICTURE' classFieldName='LogPicture' objFieldName='logPicture' fieldType='Integer' fieldSize='1' codeType='Camera' listFlag='no' listOrder='1' blobNameFld='' scale='' format='%d' classPlural=''/>
    <appField displayName='Log Notes' dbName='LOG_NOTES' classFieldName='LogNotes' objFieldName='logNotes' fieldType='String' fieldSize='255' codeType='Clob' listFlag='yes' listOrder='2' blobNameFld='' scale='' format='%s' classPlural=''/>
  </appTable>
</appTables>

APP_TABLES.xml is the domain contract. appTable is the entity. appField is a column.

LogPicture uses fieldType Integer because the factory versions pictures so it knows when an image changed. codeType Camera is the widget.

LogNotes uses codeType Clob for long text.

Use this same APP_TABLES.xml on the WildFly side.

WildFly layout

Git, Groovy, a JDK, Maven, and a running WildFly. The WildFly stamp deploys to the server. Have WildFly up when you run the script.

~/wildfly/
 ├── wildfly-builder/
 ├── wildfly-captains-log-app/
 └── Share/
mkdir -p ~/wildfly ~/Share
cd ~/wildfly
git clone [email protected]:Gator-Go/wildfly-builder.git

Place wildfly-captains-log-app next to it.

Share/ tracks apps on this machine. The stamp writes the app URL there as XML so a home page can list running products.

cd ~/wildfly/wildfly-captains-log-app
git pull
./wildfly-captains-log-build-deploy.sh

Use the script name that ships in the app repo. Skip git pull on a fresh clone.

wildfly-captains-log-app/
├── wildfly-captains-log-build-deploy.sh
├── Extender/
│   └── CaptainsLogExtender.groovy
├── options/
│   ├── APP_CODE_TYPES.xml
│   ├── APP_ENUMS.xml
│   ├── APP_EVENTS.xml
│   ├── APP_HOME.xml
│   ├── APP_NAMES.xml
│   └── APP_TABLES.xml
└── captains_log_logo.png

APP_ENUMS.xml, APP_NAMES.xml, and APP_TABLES.xml are the Android files. Do not fork them. The extender copies the logo into place.

Options only the WildFly stamp adds

Contents of APP_CODE_TYPES.xml:

<appCodeTypes>
  <appCodeType codeType='Code'/>
</appCodeTypes>

APP_CODE_TYPES.xml has no extra widgets here. Add a Report code type if you want generated reports.
See the wildfly-booklet-app notes for a fuller case.

Contents of APP_CODE_TYPES.xml:

<appEvents>
</appEvents>

APP_EVENTS.xml is empty in this app. The stamped WildFly app supports an event-based architecture: create, fire, and schedule events; subscribe to send email or SMS. See the wildfly-security-app notes for a fuller case.

Contents of APP_CODE_TYPES.xml:

<appHome>
  <home appName="captainsLog" appDesc="Captain's Log" appPng="captains_log_logo.png" appHomeURL="&lt;%= httpRoot %&gt;/captainsLog/do?op=Home"/>
</appHome>

APP_HOME.xml is what ~/Share uses to list and link the app: name, description, logo, and home URL.

After the stamp

Install the Android app with adb. Register the phone with the WildFly server (domain, user code, password). Once registered, the two apps can share and sync data.

If the script fails after sources appear, stay in the generated repo. From there it is a normal Android or WildFly problem: SDK path, datasource, Java version, port in use.

Do not start by rewriting the template. The template is the factory floor. Custom marks and copy steps belong in Extender/.

What this site is for

Show the factories, not only the apps they emit.

Keep setup notes and source next to a running demo.

Grow a shared vocabulary for metadata-driven generation.

Make the line understandable enough to copy.

What to read next

Stamp a phone app: Getting started with Droid Builder

Stamp a server app: Getting started with WildFly Builder

Chassis features in the current catalog: What the factories stamp

Walk a finished product: the live Booklet demo at https://sw-builder.com/booklet/do?op=Home (guest / guest) and the Booklet pages in the App Store.