Skip to content

CMN validation

CMN validation happens in layers. A model can parse successfully and still fail during reference resolution, semantic validation, platform-specific validation, or generation.

1. Syntax and reference resolution

The parser checks whether a .cmn file follows the grammar: declaration order, delimiters, keywords, and the shape of individual constructs.

Reference resolution then checks that referenced packages and elements are available and have the required kind. Examples include:

  • a field type resolving to a type;
  • a resource method resolving to a resource method type;
  • a component uses entry resolving to a type, service, or component;
  • an alias prefix matching an imported package alias.

Missing Maven dependencies, missing imports, ambiguous names, and references to the wrong element kind can therefore fail after the source has parsed.

2. Active core semantic rules

JoinedWorkz applies these explicit CMN validator rules:

DiagnosticRule
subpackageWithoutNamedParentA relative subpackage must have a named parent package. Use a named root or an absolute nested package declaration.
duplicateResourceMethodTypeA resource method type name must be unique within each model block: the root model and every nested package or subpackage.
fieldReferencesItselfA field include cannot use itself as its base field.
referenceTypeHasNoKeyFieldA reference field (-> or <>) must target a type with a key field.
combinationOfFieldsA property appendix cannot be applied to a combination of several fields; use a constraint appendix for a multi-field combination.

These rules report errors on the affected CMN element. They are grammar-level semantic checks and do not depend on a particular output cartridge.

Examples

A relative subpackage has a named parent:

cmn
package com.example.customer

subpackage api {
}

A reference target has a key:

cmn
package com.example.customer

import org.joinedworkz.facilities.common.base

platform Base

type Company {
    id**: Id
}

type Employee {
    employer -> Company
}

Resource method type uniqueness is scoped to each model block:

cmn
package com.example.api

subpackage raw {
    methodtype delete DELETE
}

subpackage opinionated {
    methodtype delete DELETE
}

Declaring both method types directly in the same package would be ambiguous and is rejected.

3. Build-wide package uniqueness

Every effective package name must be unique across all source and dependency models loaded by a Maven generation run. JoinedWorkz performs this check before cartridges generate output.

If two model locations declare the same effective package, the build stops with:

text
CMN_DUPLICATE_PACKAGE

The diagnostic reports the duplicate package and its conflicting locations. JoinedWorkz does not define merge or overwrite behavior for duplicate packages. Layers do not participate in package identity.

This is a Maven-wide check. An editor working incrementally on one resource cannot by itself prove uniqueness across every dependency that the later Maven build will load.

4. Profile and facility validation

The selected platform adds further rules. A profile can restrict:

  • which stereotypes apply to which element kinds;
  • which properties exist, their value types, and their propagation;
  • which cartridges and conventions interpret a model element.

Cartridges can validate requirements that only their target output knows. For example, a Java-generating cartridge validates a resolved operation method name as a Java identifier and rejects Java keywords. See Generated method names.

There is no complete global registry of facility validations in the CMN grammar. Other facilities can add their own profiles, properties, and cartridge checks. Consult the facility page for its supported model constructs and restrictions.

5. Imported models are separate validation units

A Cartridge validates only the current transformed model and the elements owned by it. It must not traverse imports or other cross-resource references to validate foreign elements. The generation pipeline processes eligible imported models as separate transformation, preparation, validation and Cartridge units.

When additional processing of an imported model fails, JoinedWorkz does not write the dependent importing model's output. This does not imply a transaction or rollback across unrelated model processing. The complete advanced behavior is documented in Imported model processing and diagnostics.

6. What each check proves

  • Parse: proves that the source follows CMN syntax. It does not prove that imports resolve or properties have defined semantics.
  • Link and core validation: proves that references resolve and active core semantic rules pass in the loaded model space. It does not prove that a particular cartridge accepts or generates the desired output.
  • Facility/cartridge validation: proves the rules implemented by the active generation path. It does not prove that generated sources compile or that the application starts.
  • Complete Maven build: proves the dependencies, build-wide validation, generation, and downstream compilation configured by that project. It does not prove runtime behavior that the build does not exercise.

A standalone snippet is not a replacement for a complete model in a buildable project. Use the examples for cross-file and generator behavior.

7. Reading diagnostics

Fix the earliest layer first:

  1. syntax errors;
  2. unresolved or wrong-kind references;
  3. core validation errors;
  4. profile or cartridge errors;
  5. generated-source compilation or runtime errors.

Later errors can be consequences of an earlier failure. The troubleshooting guide explains Maven and generation diagnostics beyond the CMN language itself.