Skip to content
Levi Starrett edited this page Jan 26, 2020 · 8 revisions

Build

Quick word about Maven

Ciera is built using Maven itself 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 strongly recommend taking a couple hours to read and learn the basics — you will lose at least a couple hours to pulling at your hair if you don’t.

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 here. Specific details about the pre-builder feature can be seen here. 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 the preferred pre-build solution for Ciera projects because of the benefits listed above, 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>1.1.11</version>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>io.ciera</groupId>
        <artifactId>ciera-maven-plugin</artifactId>
        <version>1.1.11</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>1.1.11</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>1.1.11</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>1.1.11</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 sucked 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

Building without Maven

Running projects

Using the Ciera "nightly build"

Snapshot repo (nightly build)

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

Clone this wiki locally