Foundations
Project Structure & Build
Everything you need to go from an empty folder to a running Kestros project: start an instance with Docker, install the Java and Maven tooling, scaffold a project with the Kestros Maven archetype, and build and deploy it. This page covers the generated module layout and the build profiles that push each part of a project to your instance.
Running Kestros
The quickest way to run Kestros locally is with Docker and Docker Compose. Install Docker and Docker Compose first. On an Apple Silicon Mac, OrbStack is a good alternative Docker runtime.
Create an empty folder and add a file named kestros.yaml with the following contents:
services:
kestros:
image: kestros/kestros-pro-dev:0.9.0 # or desired version
container_name: kestros-pro-dev # or desired tier
restart: unless-stopped
volumes:
- ./launcher:/opt/kestros/launcher # optional
- ./logs:/opt/kestros/launcher/logs
ports:
- 8080:8080
Then start the instance from that folder:
$ docker compose -f kestros.yaml up
platform: linux/amd64 under the service. The first build can take a minute or two while images are pulled, so give it a moment before assuming something is wrong.Debug mode
To run the instance with a remote debugger attached, add a JAVA_OPTS environment variable to the service:
environment:
JAVA_OPTS: "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:30303"
Installing Maven and Java
Building a Kestros project needs a Java Development Kit and Maven. Kestros supports the following versions:
- Java version 11 or higher
- Maven version 3.x
Any Java IDE works for development. If you use IntelliJ IDEA, you can attach the debugger using the same JVM arguments shown in the Debug mode section above.
Creating a project
Kestros projects are scaffolded from a Maven archetype. Run archetype:generate against the Kestros project archetype to generate a new project interactively:
$ mvn archetype:generate \
-DarchetypeGroupId=io.kestros.cms \
-DarchetypeArtifactId=kestros-project-archetype \
-DarchetypeVersion=0.9.0 -U
Maven then prompts for each project parameter. To run the same generation non-interactively, pass every parameter on the command line, including two that are easy to miss: artifactIdNoSpecialCharacters and artifactIdShorthand.
$ mvn -B archetype:generate \
-DarchetypeGroupId=io.kestros.cms -DarchetypeArtifactId=kestros-project-archetype \
-DarchetypeVersion=0.9.0 \
-DgroupId=com.example -DartifactId=mysite -Dversion=0.0.1-SNAPSHOT \
-DartifactName=mysite -DartifactDescription=mysite -DorganizationName=Example \
-DartifactIdNoSpecialCharacters=mysite -DartifactIdShorthand=ms \
-DhasParentProject=n -DhashSymbol="#"
Archetype parameters
Each parameter the archetype asks for is described below.
| Parameter | Description |
|---|---|
groupId | Root level package name. No spaces and no special characters. |
artifactId | Unique ID for the project, used to name the project and compiled files. No spaces and no special characters; hyphens are allowed. |
artifactIdNoSpecialCharacters | The artifactId with any special characters, such as hyphens, removed. Defaults to artifactId. |
artifactIdShorthand | Short project ID used to name the initial UI Libraries and UI Frameworks. No spaces and no special characters. |
version | Initial Maven project version. Can be left blank; defaults to 1.0-SNAPSHOT. A value like 1.0.0-SNAPSHOT or 0.0.1-SNAPSHOT is recommended. |
package | Java package. Can be left blank; defaults to the groupId value. Leave it at the default (see the note above). |
artifactName | Project title for metadata. Defaults to artifactId. |
artifactDescription | Project description for metadata. |
organizationName | Organization name for metadata. |
hasParentProject | Whether the generated modules nest under an existing parent project. Defaults to false. |
hashSymbol | A literal # for the generated templates (Velocity reserves #). Defaults to #; leave it at the default. |
Generated project modules
The archetype generates a parent project with four modules. Each module has a clear responsibility, which keeps interfaces, logic, UI, and sample content separated:
| Module | Contents |
|---|---|
api | Java interfaces and exceptions. Keeping these separate lets you change an implementation without touching every dependent. |
core | Services and their implementations, and general-purpose Sling Model implementations. (Component and datasource Sling Models live with their components in application, not here.) Core does not depend on the component libraries. |
application | The UI Frameworks, UI Libraries (Vendor Libraries), custom components and their component views and Sling Models, the datasource models, and page templates. |
content | Sample site content for reference. |
How they depend on each other: api is the base (interfaces only); both core and application depend on api; content holds no Java at all, just JCR content. So a change to an interface in api can ripple into both core and application, which is exactly why the interfaces are kept in their own module.
application module ships some things twice on purpose, as examples of both styles: an unversioned form and a versioned form of the UI Framework, the UI Library, and the sample component’s view (for example <artifactId>-framework alongside <artifactId>-versioned-framework). The sample site wires up the unversioned ones; the versioned copies are there to show the managed/versioned layout (see UI Libraries and UI Frameworks & Themes for the difference). You can delete whichever style you are not using.For more on what lives in the application module, see Components and UI Frameworks & Themes.
Building and deploying
A plain mvn clean install only builds the project; it does not deploy anything to a running instance. To deploy, activate the install profiles with Maven's -P flag. A full deploy of every part of a project looks like this:
$ mvn clean install -PinstallBundle,installPackage,installContent
You can activate a single profile the same way, for example to deploy only the bundles:
$ mvn clean install -PinstallBundle
The available build profiles are:
| Profile | Description |
|---|---|
installBundle | Installs the api and core bundles. |
installPackage | Installs the application package and bundle. |
installContent | Installs the content package. |
strict | Runs the build with Kestros strict checks, including checkstyle, SpotBugs, code coverage, and license-header checks. |
BUILD SUCCESS means the package was uploaded and the install job was queued; the actual import runs a moment later on a background thread. Check that content exists a few seconds after the build finishes, not the instant it reports success.-Dvault.bundleStatusWaitLimit=1 to cap the wait at one second and skip the delay.Overriding build parameters
The install profiles target a local instance by default. Override any of the connection settings with the corresponding -D property:
| Property | Usage | Default |
|---|---|---|
sling.host | -Dsling.host= | localhost |
sling.port | -Dsling.port= | 8080 |
sling.protocol | -Dsling.protocol= | http |
sling.username | -Dsling.username= | admin |
sling.password | -Dsling.password= | admin |