Skip to content

Maven Build Process

Frank Wienberg edited this page Sep 2, 2013 · 17 revisions

Jangaroo Maven Build Process

This page describes the Maven build process for Jangaroo 1. In Jangaroo 2, some source paths
and paths inside the JAR have changed, and the dependency type jangaroo must no longer be used.

A Jangaroo application is a Web application comprised of several library modules, aggregated by one application module. Library modules contain reusable code and resources that are added to the application. Library modules cannot be run on their own, but only as part of a Jangaroo application. If you come from Flash, think of a library as an SWC, and the application as an SWF. If you come from Java, think of a library as a JAR, and the (Web) application as a WAR.

The setup of a simple Jangaroo application via Maven using only predefined library modules is described in the Jangaroo Tutorial and on the Jangaroo Maven introduction page and suffices for getting started. The following description goes much deeper and you should consider reading it to gain a deeper understanding, especially when building multi-module applications or when integrating Jangaroo into another tool.

Maven

Jangaroo uses Maven 3 to handle libraries and applications (which are both just special modules) and dependencies between these. Maven calls the result of building a module an “artifact”. A module always has one primary artifact that should contain everything you need to use it. There are additional artifact with so-called classifiers (“-sources”, “-asdoc”), which contain e.g. source code or documentation.

A Maven module is named by a groupId (e.g. for vendor / product, a namespace for the module name) and an artifactId (the actual module name). Modules are available in different versions. Each release results in a new (higher) version number, and a dependency to another module always states which version(s) of that other module can be used. To be able to use an intermediate state of a module during development, without increasing the version number on every round-trip, there are so-called SNAPSHOT versions. A released module must never have any SNAPSHOT dependencies.

Maven comes from the Java world, so it has a standard build process for Java modules and Java Web applications. However, when dealing with complex JavaScript / ActionScript applications, the problems we face are the same, and Maven is not fixed on Java. Actually, many people use Maven to build Flex applications! Maven is very flexible, because it is extensible through plugins.

For Jangaroo, we created a Maven plugin that takes care of the Jangaroo-specific build process, described in the following.

All the information needed to build a module as well as to use the module when building another one is contained in an XML file Maven calls Project Object Model (POM, pom.xml). Essentially, the POM specifies the module’s

  • artifactId and groupId
  • packaging type: jangaroo for modules, war (“Web archive”) for applications
  • dependencies on other modules
    The POM may specify many more aspects which Maven can handle, e.g. version, release management, or test information.

Let’s take a look into the structure of a Jangaroo Maven project. As an example, we use a minimal project consisting of a Jangaroo library module and a Jangaroo application module. The sources of the complete project can be downloaded or cloned from the jangaroo-quickstart git repository.

We first start with things both kinds of modules have in common, then we proceed with Jangaroo modules (because they are simpler), wrapping up with a Jangaroo application module.

Common Module Structure

The pom.xml, described above, is always located in the module root directory. Maven organizes a module by defining default paths for different kinds of files. While you can change these defaults, it is best practice to keep them, unless you know what you are doing and have good reasons for a custom setup.

Maven Module
│   pom.xml
├───src
│   └───main
└───target

All sources go into sub-directories of src/main. The following sub-directory name stands for the type of files: java, resources, webapp are source directories predefined by Maven. For Jangaroo, we added joo as the default directory to contain AS3 source files that are to be compiled by Jangaroo. We did not use as, as3 or flex, since these are reserved by the “real” AS3 compiler by Adobe that targets the FlashPlayer.

There are two kinds of resources: those that are to be compiled (in Jangaroo, *.properties files and *.exml files), and those that are copied as-is to your Web application. The former go under src/main/joo (because they are treated as AS3 classes written in another input format), the latter under src/main/resources (module) or src/main/webapp (application).

All Jangaroo modules must activate Jangaroo’s Maven lifecycle extension and dependency management through the jangaroo-maven-plugin in their pom.xml like so:

<build>
  <plugins>
    <plugin>
      <groupId>net.jangaroo</groupId>
      <artifactId>jangaroo-maven-plugin</artifactId>
      <extensions>true</extensions>
      <version>1.0.1</version>
    </plugin>
  </plugins>
</build>

The parent directory of all build output is called target in Maven. That directory contains the primary artifact and several sub-directories that mainly contain temporary files to produce the module’s artifact(s).

The target folder is filled when invoking mvn install.

To make sure no temporary files are left behind and unintentionally change the resulting artifact, get rid of all files under target using the command mvn clean. You can also chain goals and invoke mvn clean install.

Library Modules

A Jangaroo Maven module has the packaging type jangaroo, defined as a Maven extension by the jangaroo-maven-plugin. Using this packaging type, Maven and the Jangaroo Maven plugin ease writing the POM a lot. In the simplest case, all you need to do is set the source directory and declare a dependency on the Jangaroo Runtime. So a minimal Jangaroo module POM looks like this:

<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>com.acme</groupId>
  <artifactId>my-joo-lib</artifactId>
  <version>0.1-SNAPSHOT</version>
  <packaging>jangaroo</packaging>
  <name>my-joo-lib</name>
  <description>A Hello World Jangaroo Module</description>

  <build>
    <sourceDirectory>src/main/joo</sourceDirectory>
    <plugins>
      <plugin>
        <groupId>net.jangaroo</groupId>
        <artifactId>jangaroo-maven-plugin</artifactId>
        <extensions>true</extensions>
        <version>1.0.1</version>
      </plugin>
    </plugins>
  </build>
  <dependencies>
    <dependency>
      <groupId>net.jangaroo</groupId>
      <artifactId>jangaroo-runtime</artifactId>
      <version>1.0.1</version>
      <type>jangaroo</type>
    </dependency>
  </dependencies>
</project>

Sources

Consider the following example. The module “my-joo-lib” contains a HelloWorld ActionScript class, a properties file to use in ActionScript, and a CSS file to package as a resource. These files have to be located like so:

my-joo-lib
│   pom.xml
└───src
    └───main
        ├───joo
        │   └───com
        │       └───acme
        │               HelloWorld.as
        │               HelloWorld.properties
        └───resources
            └───css
                    main.css

Artifact Content

For Jangaroo modules with packaging type jangaroo, the primary artifact is named <artifactId>-<version>.jar (e.g. my-joo-lib-0.1-SNAPSHOT.jar).

For the example library module, this artifact contains the following files:

my-joo-lib-0.1-SNAPSHOT.jar
├───css
│       main.css
├───joo
│   │   com.acme.my-joo-lib.classes.js
│   │   my-joo-lib.module.js
│   └───classes
│       └───com
│           └───acme
│                   HelloWorld.js
│                   HelloWorld_properties.js
└───META-INF
    │   MANIFEST.MF
    ├───joo-api
    │   └───com
    │       └───acme
    │               HelloWorld.as
    │               HelloWorld_properties.as
    └───maven
        └───com.acme
            └───my-joo-lib
                    pom.xml

The JAR contains several items:

  • the Jangaroo ActionScript code compiled to JavaScript, in two flavors:
    • as one big JavaScript file called joo/<groupId>.<artifactId>.classes.js, containing all generated JavaScript code, without white-space and comments
    • as separate JavaScript files, one for each source file, containing white-space and comments, sorted into sub-directories corresponding to their package
  • AS3 source stubs, under META-INF/joo-api/, that define the AS3 API of this module
  • A MANIFEST.MF containing module meta information, also under META-INF
  • all resources from src/main/resources (or whatever else has been configured in your POM)
  • an optional module loader JavaScript file called joo/<artifactId>.module.js

All types of files are explained in section “Jangaroo Library Build Lifecycle”.

Temporary Output

To build the final artifact, Jangaroo creates several temporary files. While you usually do not have to care about where these files are, it may be helpful to understand the process and is documented here for the sake of completeness.

Jangaroo uses Maven’s outputDirectory (defaults to target/classes) for collecting everything that goes into the JAR.

Considering the example, the following files are created when performing the command mvn install:

my-joo-lib
└───target
    │   my-joo-lib-0.1-SNAPSHOT.jar
    │   my-joo-lib-0.1-SNAPSHOT-sources.jar
    ├───classes
    │   └───... // content of my-joo-lib-0.1-SNAPSHOT.jar
    ├───generated-sources
    │   └───joo
    │       └───com
    │           └───acme
    │                   HelloWorld_properties.as
    └───temp
        └───jangaroo-output
            └───classes
                └───com
                    └───acme
                            HelloWorld.js
                            HelloWorld_properties.js

Jangaroo Library Build Lifecycle

This section offers a detailed description of all file processing taking place during the Jangaroo library module build process.

A file processing is a step in the build process, in Maven called a goal execution. Goals are defined by Maven plugins. They usually copy or transform / compile files from one location (source) to another (temporary output). You also find information on where in the primary artifact a file will be placed.

The Maven build process is organized in phases, and each goal has a default phase in which it is executed.

ActionScript Generated from Properties Files

Phase Plugin Goal
generate-sources jangaroo-maven-plugin properties
Standard source file path /src/main/joo/<package>/<class>.properties
  Example /src/main/joo/com/acme/HelloWorld.properties
Temporary output file path /target/generated-sources/joo/<package>/<class>_properties.as
  Example /target/generated-sources/joo/com/acme/HelloWorld_properties.as

Resources

Phase Plugin Goal
process-resources maven-resources-plugin resources

Additional resource mappings can be configured in the POM via <resources> element.

Standard source file path /src/main/resources/*
  Example /src/main/resources/css/main.css
Temporary output file path /target/classes/*
  Example /target/classes/css/main.css
Artifact path /*
  Example /css/main.css

All resources are added to the JAR using their relative path from the source directory.

Debuggable JavaScript Compiled from ActionScript

Phase Plugin Goal
compile jangaroo-maven-plugin compile

Jangaroo ActionScript code is compiled to JavaScript containing white-space and comments and keeping the exact line numbers of the AS3 source code for easy debugging.

Standard source file paths /src/main/joo/<package>/<class>.as
/target/generated-sources/joo/<package>/<class>.as
  Examples /src/main/joo/com/acme/HelloWorld.as
/target/generated-sources/joo/com/acme/HelloWorld_properties.as
Temporary output file path /target/classes/joo/classes/<package>/<class>.js
  Examples /target/classes/joo/classes/com/acme/HelloWorld.js
/target/classes/joo/classes/com/acme/HelloWorld_properties.js
Artifact path /joo/classes/<package>/<class>.js
  Examples /joo/classes/com/acme/HelloWorld.js
/joo/classes/com/acme/HelloWorld_properties.js

Minified JavaScript Compiled from ActionScript

Phase Plugin Goal
compile jangaroo-maven-plugin compile

Jangaroo ActionScript code is compiled to “minified” JavaScript, i.e. without white-space and comments to save space / bandwidth / parsing time. The files are placed under temp, not added to the artifact directly, because they are are concatenated into one big JS file during packaging (see next section).

Standard source file paths /src/main/joo/<package>/<class>.as
/target/generated-sources/joo/<package>/<class>.as
  Examples /src/main/joo/com/acme/HelloWorld.as
/target/generated-sources/joo/com/acme/HelloWorld_properties.as
Temporary output file path /target/temp/jangaroo-output/classes/<package>/<class>.js
  Examples /target/temp/jangaroo-output/classes/com/acme/HelloWorld.js
/target/temp/jangaroo-output/classes/com/acme/HelloWorld_properties.js

ActionScript Source Stubs

Phase Plugin Goal
compile jangaroo-maven-plugin compile

The compiler is also instructed to create source stubs of all ActionScript classes. Source stubs only contain non-private class members, and only their signature, not their implementation / value. These stubs are parsed by future compiler runs, when another module has a dependency on this module, to figure out which classes, fields and methods exist.
The AS3 source stubs are also helpful for IDEs and for ASDoc, since they are more lightweight than the full sources, and you don’t always want to hand out your implementation code.

Standard source file paths /src/main/joo/<package>/<class>.as
/target/generated-sources/joo/<package>/<class>.as
  Examples /src/main/joo/com/acme/HelloWorld.as
/target/generated-sources/joo/com/acme/HelloWorld_properties.as
Temporary output file path /target/classes/META-INF/joo-api/<package>/<class>.as
  Examples /target/classes/META-INF/joo-api/com/acme/HelloWorld.as
/target/classes/META-INF/joo-api/com/acme/HelloWorld_properties.as
Artifact path /META-INF/joo-api/<package>/<class>.as
  Examples /META-INF/joo-api/com/acme/HelloWorld.as
/META-INF/joo-api/com/acme/HelloWorld_properties.as

Aggregated JavaScript from Compiled ActionScript

Phase Plugin Goal
package jangaroo-maven-plugin package

All minified JavaScript files are concatenated to create a single, aggregated JavaScript file to load with one request (unless in debug mode). The module loader script takes care of loading this file.

Standard source file path /target/temp/jangaroo-output/classes/<package>/<class>.js
  Examples /target/temp/jangaroo-output/classes/com/acme/HelloWorld.js
/target/temp/jangaroo-output/classes/com/acme/HelloWorld_properties.js
Temporary output file path /target/classes/joo/<groupId>.<artifactId>.classes.js
  Example /target/classes/joo/com.acme.my-joo-lib.classes.js
Artifact path /joo/<groupId>.<artifactId>.classes.js
  Example /joo/com.acme.my-joo-lib.classes.js

Module Loader Script

Phase Plugin Goal
package jangaroo-maven-plugin package

The module loader script is needed when assembling an application using this module (see below). It contains JavaScript code to initialize or “bootstrap” your module’s Jangaroo or JavaScript code.

If you do not provide a file according to the naming convention given above (in our example you would have to place it in /src/main/resources/joo/my-joo-lib.module.js), it is created with the content joo.loadModule("<groupId>", "<artifactId>");, here joo.loadModule("com.acme", "my-joo-lib");. This lets the Jangaroo runtime load all generated JavaScript code of your module (see above) in one request (unless in debug mode).

Standard source file path /src/main/resources/joo/<artifactId>.module.js
  Example /src/main/resources/joo/my-joo-lib.module.js
Temporary output file paths /target/classes/joo/<artifactId>.module.js
  Example /target/classes/joo/my-joo-lib.module.js
Artifact path /joo/<artifactId>.module.js
  Example /joo/my-joo-lib.module.js

Library Module Main Artifact

Phase Plugin Goal
package jangaroo-maven-plugin package

All files under target/classes are zipped into the primary artifact JAR.

Standard source file paths /target/classes/*
  Examples /target/classes/...
Output file path /<artifactId>-<version>.jar
  Example /my-joo-lib-0.1-SNAPSHOT.jar

Library Module Source Artifact

Phase Plugin Goal
verify maven-source-plugin jar

As a secondary artifact, a standard Maven plugin packs all source files into a JAR.

Standard source file paths /src/main/joo/<package>/<class>.as
/target/generated-sources/joo/<package>/<class>.as
  Examples /src/main/joo/com/acme/HelloWorld.as
/target/generated-sources/joo/com/acme/HelloWorld_properties.as
Output file path /<artifactId>-<version>-sources.jar
  Example /my-joo-lib-0.1-SNAPSHOT-sources.jar

Install in Local Maven Repository

Phase Plugin Goal
install maven-install-plugin install

A standard step in Maven is to install the artifacts in the local Maven repository.
This is where artifacts of dependencies are looked up.

Deploy to Remote Maven Repository

Phase Plugin Goal
deploy maven-deploy-plugin deploy

Maven can deploy the artifacts to a remote Maven repository, so that they can be used by others.

To execute this lifecycle phase, instead of mvn install, you have to invoke the command mvn deploy.

Application Modules

For Jangaroo applications, we decided to reuse the standard Maven packaging type war. For those not familiar with Java, a WAR is actually an archive of Web resources in ZIP format. The advantage is that you can easily complement a Java Web application with a Jangaroo client side. Maven supports so-called overlays to combine two or more WARs.

The main difference between a library module and an application module is in the POM. The pom.xml of our example application looks like so:

<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>com.acme</groupId>
  <artifactId>my-joo-app</artifactId>
  <version>0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>my-joo-app</name>
  <description>A Modular Hello World Jangaroo Application</description>

  <build>
    <sourceDirectory>src/main/joo</sourceDirectory>
    <plugins>
      <plugin>
        <groupId>net.jangaroo</groupId>
        <artifactId>jangaroo-maven-plugin</artifactId>
        <extensions>true</extensions>
        <version>1.0.1</version>
        <executions>
          <execution>
            <goals>
              <goal>compile</goal>
              <goal>war-package</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.2</version>
        <configuration>
          <failOnMissingWebXml>false</failOnMissingWebXml>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <dependencies>
    <dependency>
      <groupId>net.jangaroo</groupId>
      <artifactId>jangaroo-browser</artifactId>
      <version>1.0.2</version>
      <type>jangaroo</type>
    </dependency>
    <dependency>
      <groupId>com.acme</groupId>
      <artifactId>my-joo-lib</artifactId>
      <version>0.1-SNAPSHOT</version>
      <type>jangaroo</type>
    </dependency>
  </dependencies>
</project>

Like said above, it uses packaging war, which is defined by the standard Maven plugin maven-war-plugin. Unfortunately, the WAR plugin has to be configured not to complain about a missing web.xml (after all, it comes from the Java world).

As for library modules, we use the jangaroo-maven-plugin with <extensions>true</extensions>. Even though the Jangaroo build lifecycle is not used, we use dependencies of type @jangaroo, which are also a Maven extension defined by the Jangaroo Maven plugin. Since the WAR, not the Jangaroo build lifecycle is used, you have to invoke Jangaroo goals explicitly, here compile and war-package.

The POM defines a dependency on the Jangaroo module my-joo-lib defined above, and another on the Jangaroo standard library net.jangaroo.jangaroo-browser, which is the standard browser API (DOM and BOM) written down as ActionScript.

Sources

While the primary goal of a Jangaroo application module is to assemble the Web application using library modules, it also allows adding some Jangaroo glue code. In our example, we define a single class com.acme.main.Main, which contains a main method that bootstraps the application. Like in library modules, ActionScript source files go into src/main/joo.

As documented on the Jangaroo Web site, you always need an HTML page that loads and runs the Jangaroo application. Here, it is simply called index.html and placed in src/main/webapp.

my-joo-app
│   pom.xml
│
└───src
    └───main
        ├───joo
        │   └───com
        │       └───acme
        │           └───main
        │                   Main.as
        │
        └───webapp
                index.html

Again, the module is built by invoking the command mvn install in the module root folder.

Artifact Content

For Jangaroo applications (packaging type war), the primary artifact is named <artifactId>-<version>.war (here: my-joo-lib-0.1-SNAPSHOT.jar).

For the example application module, this artifact contains the following files:

my-joo-app-0.1-SNAPSHOT.war
│   index.html
├───css
│       main.css
├───joo
│   │   jangaroo-runtime.module.js
│   │   jangaroo-browser.module.js
│   │   my-joo-lib.module.js
│   │   jangaroo-application.js
│   │   net.jangaroo.jangaroo-runtime.classes.js
│   │   net.jangaroo.jangaroo-browser.classes.js
│   │   com.acme.my-joo-app.classes.js
│   │   com.acme.my-joo-lib.classes.js
│   └───classes
│       │   ...
│       ├───com
│       │   └───acme
│       │       │   HelloWorld.js
│       │       │   HelloWorld_properties.js
│       │       │
│       │       └───main
│       │               Main.js
│       ├───joo
│       │       ...
│       └───js
│               ...
└───META-INF
    │   MANIFEST.MF
    └───maven
        └───com.acme
            └───my-joo-app
                    pom.properties
                    pom.xml

The files contained in this Web archive are used for different purposes:

  • The HTML file index.html loads and starts the Jangaroo application in a browser.
  • Other resources like images, CSS, or sounds (here: @/css/main.css) are added from all dependent modules.
  • jangaroo-application.js is the main script loaded by index.html, which bootstraps the application.
  • For all transitive dependencies, the *.module.js and *.classes.js files are collected and placed under /joo. Concatenated in order of dependency, the *.module.js files, which usually load the *.classes.js files, form jangaroo-application.js.
  • For all transitive dependencies, the debuggable *.js files are collected under /joo/classes. At runtime, these are loaded if debug mode is enabled (index.html#joo.debug). See [Jangaroo Debugging|http://www.jangaroo.net/debugging].
  • Maven by default adds some meta information to the primary artifact under /META-INF.

Temporary Output

The so-called “exploded” Web app, i.e. everything that will be packaged into the WAR, is assembled in target/<artifactId>-<version>.

my-joo-app
└───target
    │   my-joo-app-0.1-SNAPSHOT.war
    ├───jangaroo-output
    │   └───joo
    │       │   com.acme.my-joo-app.classes.js
    │       │
    │       └───classes
    │           └───com
    │               └───acme
    │                   └───main
    │                           Main.js
    ├───maven-archiver
    │       pom.properties
    ├───my-joo-app-0.1-SNAPSHOT
    │   └───... // content of my-joo-app-0.1-SNAPSHOT.war
    └───temp
        └───jangaroo-output
            └───classes
                └───com
                    └───acme
                        └───main
                                Main.js

Jangaroo Application Build Lifecycle

Though similar to the library build lifecycle, the application build life needs a detailed description, too.

Actually, there is no Jangaroo application build lifecycle—-we reuse Maven’s built-in Web archive (WAR) packaging type and lifecycle. However, the POM above shows how the Jangaroo Maven plugin contributes to the WAR lifecycle to result in a Jangaroo application build. For reader unfamiliar with Maven, we repeat parts of the WAR lifecycle here that are essential for Jangaroo applications.

ActionScript Generated from Properties Files

Usually, property files are not needed for application glue code. If you still want to place properties files into an application module, all you have to do is add the goal properties to the jangaroo-maven-plugin’s goals, and everything will work as in library modules.

Resources

Phase Plugin Goal
package maven-war-plugin war

Unlike /src/main/resources in library modules, application resources are located under /src/main/webapp.

Standard source file path /src/main/webapp/*
  Example /src/main/webapp/index.html
Temporary output file path /target/<artifactId>-<version>/*
  Example /target/my-joo-app-0.1-SNAPSHOT/index.html
Artifact path /*
  Example /index.html

All resources are added to the WAR using their relative path from the source directory.

Debuggable JavaScript Compiled from ActionScript

Phase Plugin Goal
compile jangaroo-maven-plugin compile

Jangaroo ActionScript code is compiled to JavaScript containing white-space and comments and keeping the exact line numbers of the AS3 source code for easy debugging.

This goal behaves like in library modules, only that it has to be activated explicitly in the POM, and in order not to interfere with Java compilation results, the standard temporary output path is /target/jangaroo-output instead of /target/classes.

Standard source file paths /src/main/joo/<package>/<class>.as
/target/generated-sources/joo/<package>/<class>.as
  Example /src/main/joo/com/acme/main/Main.as
Temporary output file path /target/jangaroo-output/joo/classes/<package>/<class>.js
  Example /target/jangaroo-output/joo/classes/com/acme/main/Main.js
Artifact path /joo/classes/<package>/<class>.js
  Example /joo/classes/com/acme/main/Main.js

Minified JavaScript Compiled from ActionScript

Phase Plugin Goal
compile jangaroo-maven-plugin compile

Jangaroo ActionScript code is compiled to “minified” JavaScript, i.e. without white-space and comments to save space / bandwidth / parsing time. The files are placed under temp, not added to the artifact directly, because they are are concatenated into one big JS file during packaging (see next section).

This goal behaves like in library modules, only that it has to be activated explicitly in the POM.

Standard source file paths /src/main/joo/<package>/<class>.as
/target/generated-sources/joo/<package>/<class>.as
  Example /src/main/joo/com/acme/main/Main.as
Temporary output file path /target/temp/jangaroo-output/classes/<package>/<class>.js
  Example /target/temp/jangaroo-output/classes/com/acme/main/Main.js

Aggregated JavaScript from Compiled ActionScript

Phase Plugin Goal
prepare-package jangaroo-maven-plugin war-package

All minified JavaScript files are concatenated to create a single, aggregated JavaScript file to load with one request (unless in debug mode). The module loader script takes care of loading this file.

This goal behaves like package in library modules, only that it has to be activated explicitly in the POM and creates the file in the “exploded” WAR folder.

Standard source file path /target/temp/jangaroo-output/classes/<package>/<class>.js
  Examples /target/temp/jangaroo-output/classes/com/acme/main/Main.js
Temporary output file path /target/<artifactId>-<version>/joo/<groupId>.<artifactId>.classes.js
  Example /target/my-joo-app-0.1-SNAPSHOT/joo/com.acme.my-joo-app.classes.js
Artifact path /joo/<groupId>.<artifactId>.classes.js
  Example /joo/com.acme.my-joo-app.classes.js

Module Loader Script

Phase Plugin Goal
prepare-package jangaroo-maven-plugin war-package

Like all module loader scripts from all dependent modules, this file is concatenated to jangaroo-application.js. It contains JavaScript code to initialize or “bootstrap” your module’s Jangaroo or JavaScript code.

If you do not provide a file according to the naming convention given above (for the example, you would have to place it in /src/main/resources/joo/my-joo-lib.module.js), it is created with the content joo.loadModule("<groupId>", "<artifactId>");, here joo.loadModule("com.acme", "my-joo-lib");. This lets the Jangaroo Runtime load all generated JavaScript code of your module (see above) in one request (unless in debug mode).

Standard source file path /src/main/resources/joo/<artifactId>.module.js
  Example /src/main/resources/joo/my-joo-lib.module.js
Temporary output file paths /target/classes/joo/<artifactId>.module.js
  Example /target/classes/joo/my-joo-lib.module.js
Artifact path /joo/<artifactId>.module.js
  Example /joo/my-joo-lib.module.js

Dependent Modules Scripts

Phase Plugin Goal
prepare-package jangaroo-maven-plugin war-package

For all transitive dependencies of type jangaroo, the corresponding module loader scripts (*.module.js), aggregated scripts (*.classes.js), and debuggable scripts (classes/*.js) are collected under /target/<artifactId>-<version>/joo (example: /target/my-joo-app-0.1-SNAPSHOT/joo).

The module loader files are concatenated into the application script (see next section), so in fact they are not needed in the artifact, but only kept for reference or for other tools that e.g. want to update the application script incrementally.

Application Script

Phase Plugin Goal
prepare-package jangaroo-maven-plugin war-package

The file joo/jangaroo-application.js is created by assembling all module loader scripts of all dependent modules.

The module loader files of all Jangaroo modules that the application has a direct or indirect dependency on are concatenated respecting dependency order, so that a “base” module contributes its module loader code before any module that depends on it.

Library Module Main Artifact

Phase Plugin Goal
package maven-war-plugin war

All files under target/<artifactId>-<version> are zipped into the primary artifact WAR, and some meta information is added.

Standard source file paths /target/<artifactId>-<version>/*
  Examples /target/my-joo-app-0.1-SNAPSHOT/...
Output file path /<artifactId>-<version>.war
  Example /my-joo-app-0.1-SNAPSHOT.war

EXML

Jangaroo supports the development of Ext JS applications by generating ActionScript sources from an XML dialect called EXML. EXML is Jangaroo’s equivalent of Flex’s MXML. It provides a source file syntax that is well supported by IDEs and allows to describe graphical user interface in a declarative fashion. See [Ext AS] and [Developing Ext AS Applications with IntelliJ IDEA] for details on the technology and IDE support, respectively. In the following, you find documentation on how the Jangaroo Maven build process is extended by the EXML Maven plugin.

The exml-maven-plugin also defines the packaging type jangaroo, extending it to automatically handle EXML compilation and XSD generation. To activate the extended jangaroo lifecycle, specify the exml-maven-plugin with <extensions>true</extensions>, and remove the extensions flag from the jangaroo-maven-plugin.
With any other packaging type, e.g. in a Jangaroo application using war packaging, the plugin can be activated explicitly in the pom.xml like this:

<build>
  <plugins>
    <plugin>
      <groupId>net.jangaroo</groupId>
      <artifactId>exml-maven-plugin</artifactId>
      <version>1.0.1</version>
      <executions>
        <execution>
          <goals>
            <goal>exml</goal>
            <goal>exml-xsd</goal>
          </goals>
        </execution>
      </executions>
      <configuration>
        <configClassPackage>com.acme.config</configClassPackage>
      </configuration>
    </plugin>
  </plugins>
</build>

If you also want to generate test sources, you have to add an execution for the goal test-exml, too.

EXML sources are placed in the same directory as ActionScript files. Like properties files (see above), they are first compiled to ActionScript classes placed below directory target/generated-sources/joo before they are further compiled to JavaScript and follow the path of the other files from then on.

my-joo-lib
│   pom.xml
├───src
│   └───main
│       └───joo
│           └───com
│               └───acme
│                       HelloWorldComponent.exml
└───target
    ├───generated-resources
    │       my-joo-lib.xsd
    └───generated-sources
        └───joo
            └───com
                └───acme
                        HelloWorldComponent.as

In addition to generating ActionScript classes, one XML Schema is generated into the file target/generated-resources/<artifactId>.xsd, here target/generated-resources/my-joo-lib.xsd. This XML Schema is used as a dictionary of all components of one Jangaroo EXML module and to validate EXML files.

Temporary Output

ActionScript Generated from EXML Files

Phase Plugin Goal
generate-sources ext-xml-maven-plugin extxml
Standard source file path /src/main/joo/<package>/<class>.exml
  Example /src/main/joo/com/acme/HelloWorldComponent.exml
Temporary output file path /target/generated-sources/joo/<package>/<class>.as
  Example /target/generated-sources/joo/com/acme/HelloWorldComponent.as
Phase Plugin Goal
generate-test-sources ext-xml-maven-plugin test-extxml
Standard source file path /src/test/joo/<package>/<class>.exml
  Example /src/test/joo/com/acme/HelloWorldTestView.exml
Temporary output file path /target/generated-test-sources/joo/<package>/<class>.as
  Example /target/generated-test-sources/joo/com/acme/HelloWorldTestView.as

Unit Testing

The jangaroo-maven-plugin integrates with phantomjs (at least version 1.7.0) or selenium (at least version 1.0.1) to execute unit tests. The plugin gives phantomjs priority over selenium, so if both phantomjs and selenium are available, it uses phantomjs to execute the tests. If phantomjs is not available, selenium is used. Jetty is used to serve a tests.html file. The test configuration supports the following parameters:

Param name Description Applies to
testOutputDirectory where to store the files to test both
testSourceDirectory where to find the test sources both
testResultOutputDirectory test results go here both
testResultFileName name of the test results file both
testFailureIgnore whether or not to tear down maven if tests fail both
testsHtml name of html file to load selenium
jooUnitSeleniumRCHost the selenium RC host selenium
jooUnitSeleniumRCPort the selenium RC port selenium
jooUnitSeleniumBrowserStartCommand the browser to run with selenium selenium
jooUnitJettyPortUpperBound selenium
jooUnitJettyPortLowerBound selenium
jooUnitTestExecutionTimeout test timeout both 1
phantomBin path to phantomjs executable (defaults to /usr/local/bin/phantomjs) phantomjs

1 Since 0.9.8. In earlier versions, jooUnitTestExecutionTimeout applies to selenium only.

Phase Plugin Goal
test jangaroo-maven-plugin test

Example configuration:

<build>
  <plugins>
    <plugin>
      <groupId>net.jangaroo</groupId>
      <artifactId>jangaroo-maven-plugin</artifactId>
      <configuration>
        <jooUnitTestExecutionTimeout>120000</jooUnitTestExecutionTimeout>
      </configuration>
    </plugin>
  </plugins>
</build>

Note that test output files are not generated if maven.test.skip is set to true.

Clone this wiki locally