Introduction

We have already seen AnvilJ's architecture definitions before in the Getting Started guide. An architecture definition is an XML file called architecture.xml which tells the AnvilJ refactoring engine the following things:
  • The target architecture, in terms of nodes (JVMs) and the communications channels between them
  • The AnvilJ Instances of the source application
  • Where to place each AnvilJ Instance
  • The main class of the application and which node to place this on

It is this file which is edited by the programmer to quickly test different distributions of their software and to expose the full power of AnvilJ. The architecture.xml file is a plain text file which should be placed into the root of your Java project in Eclipse as shown below:
archinroot.jpg
When AnvilJ's refactoring is started (by right-clicking on the project and selecting AnvilJ - Perform Refactoring) the refactoring engine will read this file.

Format

The architecture definition is an XML file, so standard XML format rules apply. Elements are declared as follows:
<element parameter1="value" parameter2="value">
 <subelement parameter="value">
   <elementWithNoSubElements parameter="value" />
 </subelement>
 <anotherSubElement />
</element>
Note that elements can be opened and closed on the same line by preceding the closing tag with a forward slash.

The top-level element in an architecture definition is the architecture element which has the following parameters:
  • name: A textual name that describes the architecture. This is not currently used by the refactoring process.
  • mainclass: The main class of the Java application in dot-notation. For example, the class Main in the package example is example.Main.
  • maincpuid: An integer ID of the node that should host the main class. In other words, which node will start executing the application first.

An example of these values is as follows:
<architecture name="Minimal Architecture" mainclass="example.Main" maincpuid="0">
 <cpu name="cpu1" id="0">
 </cpu>
</architecture>
This minimal architecture definition defines a single node with ID 0, and places the main class on it.

Nodes

Each node (JVM) of the system is defined as a cpu element, which are subelements of the architecture element. cpu elements have the following parameters:
  • name: A textual name for referencing the node. This must be unique from all other nodes, and must confirm to Eclipse's restrictions on project names. The reason for this is that output projects (the projects created by the refactoring engine are named <input project name>-<node name>. Use only characters, spaces, the hypen and the underscore.
  • id: An integer ID of the node. Node IDs must be unique.
  • hostname: (Optional, default = "localhost"). When AnvilJ's refactoring engine has first been executed, the output programs use a TCP sockets-based communications layer that is suitable for debugging on standard operating systems and for distributing over a TCP-based network (for more information see here). The IP addresses or hostname of each node can be set up with this attribute.

To assign AnvilJ instances to a node, define either a thread or sharedobject element inside the target cpu element, as detailed in the following section.

AnvilJ Instances

Recall from this page that an AnvilJ application has two defined sets of static final object instances:
  • AnvilJ Threads
  • AnvilJ Shared Objects

Collectively these are called AnvilJ Instances. The refactoring engine needs to be told which elements in the source code should be tagged as AnvilJ Instances, and to which node they should be allocated. This is done by creating thread and sharedobject elements in the architecture definition. See the following example:
<cpu name="cpu1" id="0">
 <thread binding="Lexample/Main;.quantizeThread)Lexample/QuantizeThread;"/>
 <sharedobject binding="Lexample/Main;.outputStage)Lexample/OutputStage;"/>
</cpu>
In the above architecture definition fragment, a thread and a shared object are defined and allocated to a node called cpu1. The corresponding source code may look like this:
package example;
 
public class Main {
 public static final QuantizeThread quantizeThread = new QuantizeThread();
 public static final OutputStage outputStage = new OutputStage(QUALITY);
 
 //Rest of class definition...
}
The thread and sharedobject elements both have an attribute called binding. This is a string which is used to uniquely identify source code items. To find out the binding key of a field you can use the following method:
  1. Place the edit cursor at the name of the instance for which the binding is required. For example in the code Thread myThread = new Thread, place the cursor inside the word myThread.
  2. Right-click the mouse and from the pop-up menu select "AnvilJ - Get Binding Information".

A dialog box will pop up with the binding information and a button which you can click to copy it to the clipboard.
binding.jpg
These bindings can then be used in the architecture definition.

Channels

The final aspect of the architecture definition is the description of the communications networks of the target architecture. This is done using channel elements. A channel element contains a set of endpoint elements. Each endpoint element connects a cpu element to a channel. For example:
<architecture name="Simple Dual Core Architecture" mainclass="example.Main" maincpuid="0">
 <cpu name="cpu1" id="1" hostname="localhost">
  <thread binding="Lradarprocessor/Main;.dataAcquisition)Lradarprocessor/DataAcquisition;"/>
 </cpu>
 
 <cpu name="cpu0" id="0" hostname="localhost">
  <sharedobject binding="Lradarprocessor/Main;.dop)Lradarprocessor/workers/Worker;"/>
  <thread binding="Lradarprocessor/Main;.controller)Lradarprocessor/Controller;"/>
 </cpu>
 
 <channel name="ethernet">
  <endpoint cpu="cpu0"/>
  <endpoint cpu="cpu1"/>
 </channel>
</architecture>
In this architecture, two nodes are defined (cpu0 and cpu1) and they are assigned some AnvilJ threads and shared objects. A single communications channel is then created and both nodes are attached to it by declaring the two endpoint elements inside the channel element.

Channel elements have a single attribute name which is a textual description of the channel. This is not used internally and can be any value. Endpoint elements have a single attribute cpu which must be the name of a cpu element elsewhere in the architecture definition.