Skip to content

Facilities and platforms

Facilities are the way JoinedWorkz bundles everything that is needed to use one or more platforms in a project.

A platform defines what is generated: target architecture, conventions, mappings, project structure and any platform-specific helpers or libraries. A facility defines how this platform becomes available: profiles, cartridges, generators, CMN support, stereotypes and utilities.

A facility is a Maven module that contains:

  • one or more profiles (.profile) with stereotypes, properties, outlets, cartridges and platforms
  • shared CMN models (.cmn) such as base types or method types
  • generator and cartridge implementations
  • optional additional helpers (strategies, utilities, …)

Your application project only needs to add the facility as a Maven dependency. The JoinedWorkz generator plugin discovers the profiles, CMN models and implementations on the classpath and uses them during parsing, validation and generation.

For an overview of how DSLs and platforms fit together, see:


1. Stable facilities

The main facilities that are intended for regular use are:

  • common-base – provides the Base platform
    • basic simple types (String, Integer, Date, …)
    • resource method types (create, read, update, query, raw HTTP helpers, …)
    • OpenAPI and diagram cartridges
  • common-java – provides the Java platform (extends Base)
    • Java-specific properties and strategies (javaType, naming rules, …)
    • cartridges for Java-centric artefacts
  • spring-boot – provides the SpringBoot platform (extends Java)
    • Spring Boot specific mappings and conventions
    • cartridges for controllers, configuration, etc.

All of these facilities live in the GitLab repository. The source baseline for this documentation is:

The corresponding artifacts are published to Maven Central and are free to use.


2. Using a facility in your project

To use a facility, add it as a dependency to your model module. The Maven dependency brings the profile(s), CMN models and implementations onto the classpath.

A typical setup when you want to build Spring Boot services looks like this:

xml
<properties>
    <joinedworkz.version>1.3.80</joinedworkz.version>
</properties>

<dependencies>
    <!-- Spring Boot platform (includes Java and Base via transitive dependencies) -->
    <dependency>
        <groupId>org.joinedworkz.facilities</groupId>
        <artifactId>spring-boot</artifactId>
        <version>${joinedworkz.version}</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

You do not need to add common-java and common-base explicitly in this case: the spring-boot facility depends on common-java, and common-java depends on common-base. Maven will put all three on the classpath.

If you only want to use the Java platform without Spring Boot, you can depend on common-java directly; if you only need the Base platform, you can depend on common-base:

xml
<!-- only Base platform -->
<dependency>
    <groupId>org.joinedworkz.facilities</groupId>
    <artifactId>common-base</artifactId>
    <version>${joinedworkz.version}</version>
    <scope>provided</scope>
</dependency>

<!-- Base + Java platform -->
<dependency>
    <groupId>org.joinedworkz.facilities</groupId>
    <artifactId>common-java</artifactId>
    <version>${joinedworkz.version}</version>
    <scope>provided</scope>
</dependency>

General rule: If platform A in one facility depends on a platform or types from another facility B, then facility A declares a Maven dependency on B. You only need to add the top-level facility (the one you use directly) as a dependency in your project; Maven brings in the rest transitively.

The JoinedWorkz generator plugin is configured once in the build section (see the Quickstart and Create a project with Maven pages). It then automatically finds all profiles, platforms and cartridges provided by the facilities on the classpath.

In your CMN models you simply:

  1. import the CMN models from the facility, e.g.

    cmn
    import org.joinedworkz.facilities.common.base
    import org.joinedworkz.facilities.common.base.api
  2. select a platform in the header:

    cmn
    platform Base

    or, with Java/Spring Boot enabled:

    cmn
    platform Java
    cmn
    platform SpringBoot

3. Relationship between facilities, profiles and platforms

The layering looks like this:

  • Facility – Maven module that packages everything together.
  • Profile(s) – describe stereotypes, properties, outlets, cartridges and strategies used by one or more platforms.
  • Platform(s) – select which cartridges run and which properties are available for a given target stack.
  • CMN models – use platform X in the header and import base models from the facility.

For example:

  • common-base contains the Base profile and platform, plus CMN models with base types and resource method types.
  • common-java extends the Base platform with Java-specific behaviour.
  • spring-boot extends the Java platform with Spring Boot specifics.

You can think of a facility as a plug-in bundle: once it is on the classpath, all its platforms become available to your models.


4. Package overrides for helper libraries

Generated Java code can depend on small helper or “glue” libraries supplied by the selected facility. If you maintain a compatible copy under your own packages, JoinedWorkz 1.3.80 can rewrite the corresponding imports during generation.

Configure mappings in the model module's joinedworkz.properties:

properties
override-package.<original-package-prefix>=<target-package-prefix>

For example:

properties
override-package.org.iworkz.core=com.example.glue.core
override-package.org.iworkz.spring.persistence=com.example.glue.persistence

With these two non-overlapping mappings, generated imports such as:

java
import org.iworkz.core.query.QueryService;
import org.iworkz.spring.persistence.service.AbstractDataAccessService;

become:

java
import com.example.glue.core.query.QueryService;
import com.example.glue.persistence.service.AbstractDataAccessService;

This allows you to:

  1. copy the required helper classes into a module that you control;
  2. change their package declarations to your target packages;
  3. configure the corresponding override-package.* mappings;
  4. regenerate all replaceable Java output;
  5. compile and test the complete project against your glue-library copy;
  6. remove the original runtime dependency only after confirming that no generated or manual references remain;
  7. clean, regenerate, compile and test the complete project again without the original dependency.

4.1 Release 1.3.80 boundaries

  • Matching is case-sensitive and uses the original package text as a prefix. There is no wildcard syntax. Always specify a non-empty original package prefix and a non-empty target package.
  • The mechanism rewrites imports emitted through the common Java class generator. Do not assume that arbitrary text output or every custom generator applies the mapping.
  • Use one mapping or several non-overlapping original prefixes. Release 1.3.80 does not define deterministic precedence for overlapping prefixes. For example, do not configure both org.iworkz.core and org.iworkz.core.exception; whichever matching entry is encountered first would win.
  • Release 1.3.80 replaces every occurrence of the selected original prefix in the import after the leading prefix has matched. Use normal package roots that do not repeat later in the same fully qualified class name.
  • The mapping does not copy classes, update their package declarations or add Maven dependencies. Those remain owned by your project.
  • A clean regeneration and compilation are required after every mapping change; stale generated files can otherwise retain old imports.

The non-overlapping example above was generation-tested on 2026-07-25 with the published JoinedWorkz 1.3.80 artifacts. It rewrote the org.iworkz.core.query and org.iworkz.spring.persistence.service imports independently. The deterministic handling of overlapping prefixes remains a framework improvement for a later release.


5. Experimental facility

Quasar is currently experimental. It is useful for evaluating a generated web UI, but its API, generated project structure and behaviour may change without notice. Do not treat it as part of the stable compatibility surface.

For the public documentation and for most users, the recommended set is:

  • Base (from common-base) – always present; used by almost all models.
  • Java (from common-java) – when you generate Java-based artefacts.
  • SpringBoot (from spring-boot) – when you build Spring Boot services. → Spring Boot facility

This public overview deliberately does not list internal, deprecated or unpublished facilities.


6. Where to go next

  • To see how platforms are defined: → Profile reference

  • To understand how CMN models bind to platforms: → Modeling overview

  • To try it out in a working project: → Quickstart and example projects (see the Examples section).