Skip to content
Levi Starrett edited this page Mar 14, 2020 · 8 revisions

Build

Quick word about Maven

Ciera itself is built using Maven and it is used extensively to build other Ciera-based applications. Maven is an incredibly useful tool, but it can be frustrating if you do not understand it. I recommend taking a couple hours to read and learn the basics.

Requirements for a Ciera build

Ciera requires three things for a successful build:

  1. An input model file with parsed OAL

  2. A set of application marks (and feature specification)

  3. An output location

The rest of the topics in this chapter will expound on how each of those three elements is configured and provided to the compiler.

Pre-build

First, Ciera requires clean, parsed model data with all proxies resolved, in a single file. This has historically been a task handled for model compilers by the BridgePoint tool itself. Ciera supports pre-built output from BridgePoint.

Ciera also supports ouptut from the pyxtuml pre-builder. pyxtuml is a Python based dynamic xtUML tool used as the model backend by the pyrsl RSL generator. Details about pyxtuml, its author and its history can be seen in the pyxtuml documentation. Specific details about the pre-builder feature can be seen in the OAL prebuilder section. Using pyxtuml allows Ciera to be free of build dependencies on BridgePoint. Ciera projects can be built and executed entirely on a system with no BridgePoint installation, making it much easier to integrate into server builds.

The pyxtuml pre-builder is significantly faster for small-medium sized projects, since it does not suffer the weight of Eclipse, however for very large projects, the BridgePoint pre-builder is actually faster. It should also be noted that the BridgePoint pre-builder remains the gold standard implementation for OAL parsers.

The pyxtuml pre-builder is the preferred pre-build solution for Ciera projects because of its light weight and portability, however it does introduces an external dependency. pyxtuml must be installed on the system:

pip install pyxtuml

Components of the pom.xml file

Let’s take a look at the pom.xml file for the MicrowaveOven example:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>io.ciera</groupId>
  <artifactId>MicrowaveOven</artifactId>
  <packaging>jar</packaging>
  <version>1.0.0-SNAPSHOT</version>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>
  <dependencies>
    <dependency>
      <groupId>io.ciera</groupId>
      <artifactId>runtime</artifactId>
      <version>2.1.0</version>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>io.ciera</groupId>
        <artifactId>ciera-maven-plugin</artifactId>
        <version>2.1.0</version>
        <executions>
          <execution>
            <id>pre-build</id>
            <goals>
              <goal>pyxtuml-pre-build</goal>
            </goals>
          </execution>
          <execution>
            <id>ciera-core</id>
            <goals>
              <goal>core</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
    <resources>
      <resource>
        <directory>${project.basedir}</directory>
        <filtering>true</filtering>
        <includes>
          <include>models/**/*.xtuml</include>
          <include>.project</include>
        </includes>
      </resource>
      <resource>
        <directory>${project.build.directory}/generated-sources/java</directory>
        <filtering>true</filtering>
        <includes>
          <include>**/*.properties</include>
        </includes>
      </resource>
    </resources>
  </build>
</project>

Let’s break this down section by section:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>io.ciera</groupId>
  <artifactId>MicrowaveOven</artifactId>
  <packaging>jar</packaging>
  <version>1.0.0-SNAPSHOT</version>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

This is the basic setup for a Maven project. We have group and artifact identifers, packaging scheme, version identifier and some properties which define our character set and Java compiler version.

<dependencies>
  <dependency>
    <groupId>io.ciera</groupId>
    <artifactId>runtime</artifactId>
    <version>2.1.0</version>
  </dependency>
</dependencies>

Next we have our dependency section. All Ciera-based projects depend on the Ciera runtime library included here. In this case, it is the only dependency.

<build>
  <plugins>
    <plugin>
      <groupId>io.ciera</groupId>
      <artifactId>ciera-maven-plugin</artifactId>
      <version>2.1.0</version>
      <executions>
        <execution>
          <id>pre-build</id>
          <goals>
            <goal>pyxtuml-pre-build</goal>
          </goals>
        </execution>
        <execution>
          <id>ciera-core</id>
          <goals>
            <goal>core</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>

The first part of the build section defines that this project uses the ciera-maven-plugin. This is the worker that actually handles the execution of the compiler. There are two execution units that we make use of: the pre-build and the core generation. The pre-build is done by pyxtuml and the core generation is done by the core model compiler. Other projects might also have executions for generating instance loaders/dumpers or template utilities. The pre-build section can be used to configure the BridgePoint pre-builder if that is preferred. See the ciera-maven-plugin in detail section for more on BridgePoint pre-builder.

<resources>
  <resource>
    <directory>${project.basedir}</directory>
    <filtering>true</filtering>
    <includes>
      <include>models/**/*.xtuml</include>
      <include>.project</include>
    </includes>
  </resource>

This section is standard for Ciera-based projects. It simply indicates to maven that all .xtuml files should be packaged into the output artifact (JAR). This allows Ciera-based xtUML "library" projects to be distributed as dependencies. See the next section for detail.

      <resource>
        <directory>${project.build.directory}/generated-sources/java</directory>
        <filtering>true</filtering>
        <includes>
          <include>**/*.properties</include>
        </includes>
      </resource>
    </resources>
  </build>
</project>

This final section is also standard for Ciera-based projects. It assues that .properties files are included as resources in the output artifact. This is used to store the version information for components.

Ciera dependency strategy

Ciera leans into the dependency mechanism of Maven and therefore utilizes the Maven dependency mechanism to specify other xtUML projects that need to be included for inter-project references. A major problem with including other projects is dealing with fragile filesystem relative paths to locate model elements. Eclipse solves this using their workspace model (virtual filesystem) to bring all imported projects together. Ciera needs to be independent of BridgePoint and Eclipse.

The ciera-maven-plugin automatically invokes the pyxtuml pre-builder and passes the path to artifacts listed as Maven dependencies. If an xtUML project was built and installed in the local Maven repository or exists on an accessible remote repository, it can be accessed and passed directly to pre-builder.

Consider the GPS Watch example:

<dependencies>
  <dependency>
    <groupId>io.ciera</groupId>
    <artifactId>runtime</artifactId>
    <version>2.1.0</version>
  </dependency>
  <dependency>
    <groupId>io.ciera</groupId>
    <artifactId>HeartRateMonitor</artifactId>
    <version>1.0.0-SNAPSHOT</version>
  </dependency>
  <dependency>
    <groupId>io.ciera</groupId>
    <artifactId>Location</artifactId>
    <version>1.0.0-SNAPSHOT</version>
  </dependency>
  <dependency>
    <groupId>io.ciera</groupId>
    <artifactId>Tracking</artifactId>
    <version>1.0.0-SNAPSHOT</version>
  </dependency>
  <dependency>
    <groupId>io.ciera</groupId>
    <artifactId>UI</artifactId>
    <version>1.0.0-SNAPSHOT</version>
  </dependency>
  <dependency>
    <groupId>com.googlecode.lanterna</groupId>
    <artifactId>lanterna</artifactId>
    <version>3.0.1</version>
  </dependency>
</dependencies>

The GPS Watch example is comprised of five separate projects. Each has its own pom.xml in which its .xtuml files are zipped up in the output JAR. The system deployment project that is translated with Ciera declares Maven dependencies on each of the four "library" projects and all of their xtUML modeled elements are pulled in automatically to the pre-build.

I see a future in which a widely used data model like the mcooa project is built with Maven and published and model compiler projects can easily access it in this way without even needing the project on their machine much less in their development folder.

(I see a further future where Ciera can reuse compiled implementations of components directly without re-translation, but that is not a reality now.)

ciera-maven-plugin in detail

Each of the "goals" the ciera-maven-plugin provides are documented below.

pyxtuml-pre-build

The pyxtuml pre-build goal takes input files and executes the pyxtuml pre-build utility to produce clean SQL input for a Ciera compiler. It has the following configuration parameters:

outputFile

The location of the output SQL file. The default value is <project_name>.sql in the project build directory (target/ is the default build directory for Maven, but can be configured differently in the main build section of the pom.xml file).

modelDirs (array)

This list of directories to look for input models. This option is typically only used to specify model dependencies by path instead of included as a dependency (described above). This has some benefit in flexibility especially of required projects are not built with Maven, but suffers in its reliance on consistent filesystem paths. This method of including dependency models is not recommended.

includeDependencyModels

If "true", models dependency artifacts are searched for model files. This is typically false if "modelDirs" is used. Default value is "true".

includeLocalModel

If "true", the models/ directory in the current project is searched for model files. This is typically false only if "modelDirs" is being used. Default value is "true".

pythonExecutable

Specifies the name/path of the Python executable to use for pyxtuml. The default value is "python" which will execute the default Python interpreter installed on the system. This value can be changed to use an alternate interpreter. For example, the Ciera projects themselves use the pypy interpreter because it parses the OAL almost three times faster than standard CPython.

Note
If you use a different Python interpreter, you may need to install pyxtuml again for that specific interpreter (e.g. pip3 install pyxtuml for python3)
Example

In addition to the MicrowaveOven example given above, consider the following pom.xml snippet from the Ciera core model compiler.

<execution>
  <id>pre-build</id>
  <goals>
    <goal>pyxtuml-pre-build</goal>
  </goals>
  <configuration>
    <includeDependencyModels>false</includeDependencyModels>
    <modelDirs>
      <param>${project.basedir}/../runtime/models</param>
      <param>${bpLoc}/src/org.xtuml.bp.ui.marking/models</param>
      <param>${mcLoc}/model/mcooa/models</param>
    </modelDirs>
  </configuration>
</execution>

In this example, models are not included from the dependency list, but paths are specified in the configuration of the pre-build itself.

This is done because Ciera is built with itself, and as such, the Ciera runtime library it requires as a runtime dependency is not the same as the one it needs as a build dependency (self-building compilers are confusing!).

bridgepoint-pre-build

The BridgePoint pre-build goal uses the BridgePoint CLI to pre-build a project in a pre-defined Eclipse workspace. It requires that BridgePoint be installed and a workspace be set up, however it does not require a window manager (it can still be part of a server build).

bpHome

The location of the BridgePoint installation. If no value for "bpHome" is specified, the build will fail.

workspace

The location of the BridgePoint workspace where the models are imported. The name of the Maven project is used to determine which project in the workspace to build. This implies that the name of the Maven project and the name of the BridgePoint project must match. If no value for "workspace" is specified, the build will fail. All models required for the build must be imported into the workspace including the Ciera runtime library. An easy way to check this is to run a "parse all" in the BridgePoint workspace and verify that there are no parse errors due to missing model elements.

Environment variables

The previous two options can be specified by environment variables BPHOME and WORKSPACE respecitively. This can be useful if you are working on multiple Ciera projects in the same workspace or if you prefer not to couple development workspace and tool paths with your project source code.

Example
<execution>
  <id>pre-build</id>
  <goals>
    <goal>bridgepoint-pre-build</goal>
  </goals>
  <configuration>
    <bpHome>/Users/levi/xtuml/m6190.2019-12-18-1004_nightly-build/BridgePoint.app/Contents/Eclipse</bpHome>
    <workspace>/var/folders/6n/ybm_82hn3wq4w972zjl90q9w0000gp/T/tmp.issCz64J</workspace>
  </configuration>
</execution>
Note
Since BridgePoint manages the acutal pre-build, the location of the output model file is determined by BridgePoint. You will have to refer to the BridgePoint project to confirm what this location is. As of this writing, BridgePoint outputs pre-built model files to gen/code_generation/<project_name>.sql where <project_name> is the name of the BridgePoint project.

core

The core goal is the main code generation tool. For most Ciera projects, one of the pre-build goals and the core goal are all that is necessary to build the project.

input

The location of the input pre-built model file for translation. The default value is the same as the default outputFile of the pyxtuml pre-build goal.

output

The location of an output file where instances of OOA of OOA and Ciera architectural models will be dumped. The default value is an empty string (which causes the compiler to skip dumping output). This option is used if there is a downstream compiler that you need to load the instance population to generate additional Java source files.

genDir

The location where the generated Java source will be output. The default value is generated-sources/java in the project build directory.

Example
<execution>
  <id>ciera-core</id>
  <goals>
    <goal>core</goal>
  </goals>
</execution>

sql

The SQL goal generates a SQL insert statement loader/dumper for the model. For more information, see the Persistence chapter. The configuration parameters are identical to the core goal.

template

The template goal parses a set of RSL templates and generates a template registry. It also processes RSL substitutions in literal strings within OAL. For more information, see the Templating chapter. The configuration parameters are identical to the core goal.

Building without Maven

Although it is not recommended, Ciera is not strictly dependent on Maven. This section will demonstrate step by step how to download the Ciera artifacts, build and run the MicrowaveOven example project.

Download the artifacts

The Ciera runtime library and core generation tool are needed. Download directly from Maven central with:

wget https://search.maven.org/remotecontent?filepath=io/ciera/runtime/2.1.0/runtime-2.1.0.jar -O runtime.jar
wget https://search.maven.org/remotecontent?filepath=io/ciera/tool-core/2.1.0/tool-core-2.1.0.jar -O core.jar
wget https://search.maven.org/remotecontent?filepath=org/antlr/antlr4-runtime/4.7.1/antlr4-runtime-4.7.1.jar -O antlr.jar

Pre-build

Pre-build the model with:

python -m bridgepoint.prebuild -o MicrowaveOven.sql runtime.jar models/

Alternatively, import the project into a BridgePoint workspace and import existing projects from the runtime.jar archive and run a pre-build within BridgePoint.

Generate code

Generate Java source with:

mkdir src-gen
java -cp runtime.jar:antlr.jar:core.jar io.ciera.tool.CoreTool -i MicrowaveOven.sql --gendir src-gen --cwd .

Compile the Java code

Compile Java with:

find src-gen/ -name *.java > sources.txt
javac -cp runtime.jar -d bin @sources.txt

Run the application

Run with:

java -cp runtime.jar:bin microwaveoven.MicrowaveOvenApplication

Ciera core generator CLI

As demonstrated above, it is possible to use Ciera without Maven — in fact, the Ciera compiler itself is only a small piece in a longer build chain including pre-build, generation, compilation, and execution. The code generator has its own command line interface and Maven simply maps configuration from the pom.xml file to existing CLI options.

The following is the output of passing -h to the Ciera tool:

$ java -cp runtime.jar:antlr.jar:core.jar io.ciera.tool.CoreTool -h
Usage:
  --cwd <root_dir>     : base working directory
  --gendir <gen_dir>   : generated output directory
  -i <input_file>      : input file
  -o <output_file>     : output file
  --use-version <use_version> : version identifier for generated components
  -h, --help           : Print usage information.

Running projects

When running projects generated with Ciera, in addition to the the compiled Java classes, some libraries must be in the classpath.

  • For all Ciera generated projects, the Ciera runtime library must be in the classpath. In general, the runtime library must have the same major version as the version of the code generation tool used to generate the code (for more details on the Maven versioning policy, see Maven version number policy).

  • For projects using JSON serialization for message passing, the JSON library found here is required.

  • For projects using SQL instance loading, the Antlr 4.7.1 runtime library is required.

  • Any other external libraries referenced in hand written code must be on the classpath.

If you are using Maven as your build tool, all of these dependencies will be downloaded in your local Maven repository which is a nice consistent place to reference them. The Ciera example projects each have a "run" bash script which builds the classpaths from the JARs installed in the local Maven repository.

Using the Ciera "nightly build"

Release versions of Ciera will be published to the Maven central repository. This is the default repository for Maven and artifacts hosted here will be downloaded automatically with no extra configuration.

Snapshot versions of Ciera (i.e. development versions/nightly builds) are hosted in the Sonatype snapshot repository. To access development versions of Ciera, you must add the following <repository> and <pluginRepository> definitions in your project pom.xml or in your Maven settings.xml. More information on declaring additional repositories can be found here.

<repository>
  <id>snapshot-repo</id>
  <url>http://oss.sonatype.org/content/repositories/snapshots</url>
  <releases><enabled>false</enabled></releases>
  <snapshots><enabled>true</enabled></snapshots>
</repository>
<pluginRepository>
  <id>snapshot-repo</id>
  <url>http://oss.sonatype.org/content/repositories/snapshots</url>
  <releases><enabled>false</enabled></releases>
  <snapshots><enabled>true</enabled></snapshots>
</pluginRepository>

Clone this wiki locally