Java 2 Ada

New debian repository with Ada packages

By Stephane Carrez 2014-04-06 15:54:30

I've created and setup a Debian repository to give access to several Debian packages for several Ada projects that I manage. The goal is to provide some easy and ready to use packages to simplify and help in the installation of various Ada libraries. The Debian repository includes the binary and development packages for Ada Utility Library, Ada EL, Ada Security, and Ada Server Faces.

Access to the repository

The repository packages are signed with PGP. To get the verification key and setup the apt-get tool, you should run the following command:

wget -O - http://apt.vacs.fr/apt.vacs.fr.gpg.key | sudo apt-key add -

Ubuntu 13.04 Raring

A first repository provides Debian packages targeted at Ubuntu 13.04 raring. They are built with the gnat-4.6 package and depend on libaws-2.10.2-4 and libxmlada4.1-dev. Add the following line to your /etc/apt/sources.list configuration:

deb http://apt.vacs.fr/ubuntu-raring raring main

Ubuntu 12.04 LTS Precise

A second repository contains the Debian packages for Ubuntu 12.04 precise. They are built with the gnat-4.6 package and depend on libaws-2.10.2-1and libxmlada4.1-dev. Add the following line to your /etc/apt/sources.list configuration:

deb http://apt.vacs.fr/ubuntu-precise precise main

Installation

Once you've added the configuration line, you can install the packages:

sudo apt-get update
sudo apt-get install libada-asf1.0

For the curious, you may browse the repository here.

Ada Server Faces 1.0.0 is available

By Stephane Carrez 2014-04-05 19:05:21

Ada Server Faces is a framework that allows to create Web applications using the same design patterns as the Java Server Faces (See JSR 252, JSR 314, or JSR 344). The presentation pages benefit from the Facelets Web template system and the runtime takes advantages of the Ada language safety and performance.

A new release is available with several features that help writing online applications:

  • Add support for Facebook and Google+ login
  • Javascript support for popup and editable fields
  • Added support to enable/disable mouseover effect in lists
  • New EL function util:iso8601
  • New component <w:autocomplete> for input text with autocompletion
  • New component <w:gravatar> to render a gravatar image
  • New component <w:like> to render a Facebook, Twitter or Google+ like button
  • New component <w:panel> to provide collapsible div panels
  • New components <w:tabView> and <w:tab> for tabs display
  • New component <w:accordion> to display accordion tabs
  • Add support for JSF <f:facet>, <f:convertDateTime>, <h:doctype>
  • Support for the creation of Debian packages

You can try the online demonstration of the new widget components and download this new release at http://download.vacs.fr/ada-asf/ada-asf-1.0.0.tar.gz

Ada Security 1.1.0 is available

By Stephane Carrez 2014-03-22 14:05:36

The Ada Security library provides a security framework which allows applications to define and enforce security policies. This framework allows users to authenticate by using OpenID Authentication 2.0, OAuth 2.0 or OpenID Connect protocols.

The new version brings the following improvements:

  • New authentication framework that supports OpenID, OpenID Connect, OAuth, Facebook login
  • AWS demo for a Google, Yahoo!, Facebook, Google+ authentication
  • Support to extract JSON Web Token (JWT)
  • Support for the creation of Debian packages

The library can be downloaded at http://download.vacs.fr/ada-security/ada-security-1.1.0.tar.gz

Ada EL 1.5.0 is available

By Stephane Carrez 2014-03-19 21:49:33

Ada EL is a library that implements an expression language similar to JSP and JSF Unified Expression Languages (EL). The expression language is the foundation used by Java Server Faces and Ada Server Faces to make the necessary binding between presentation pages in XML/HTML and the application code written in Java or Ada.

The presentation page uses an UEL expression to retrieve the value provided by some application object (Java or Ada). In the following expression:

#{questionInfo.question.rating}

the EL runtime will first retrieve the object registered under the name questionInfo and look for the question and then rating data members. The data value is then converted to a string.

The new release is available for download at http://download.vacs.fr/ada-el/ada-el-1.5.0.tar.gz

This version brings the following improvements:

  • EL parser optimization (20% to 30% speed up)
  • Support for the creation of Debian packages

Ada Utility Library 1.7.0 is available

By Stephane Carrez 2014-02-09 11:06:03

Ada Utility Library is a collection of utility packages for Ada 2005. A new version is available which provides:

  • Added a text and string builder
  • Added date helper operations to get the start of day, week or month time
  • Support XmlAda 2013
  • Added Objects.Datasets to provide list beans (lists of row/column objects)
  • Added support for shared library loading
  • Support for the creation of Debian packages
  • Update Ahven integration to 2.3
  • New option -r <test> option for the unit test harness to execute a single test
  • Port on FreeBSD

It has been compiled and ported on Linux, Windows, Netbsd, FreeBSD (gcc 4.6, GNAT 2013, gcc 4.7.3). You can download this new version at http://download.vacs.fr/ada-util/ada-util-1.7.0.tar.gz.

Installation of FreeBSD for a jenkins build node

By Stephane Carrez 2013-12-31 10:59:44

A few days ago, I did a fresh installation of my Jenkins build environment for my Ada projects (this was necessary after a disk crash on my OVH server). I took this opportunity to setup a FreeBSD build node. This article is probably incomplete but tends to collect a number of tips for the installation.

Virtual machine setup

The FreeBSD build node is running within a QEMU virtual machine. The choice of the host turns out to be important since not all versions of QEMU are able to run a FreeBSD/NetBSD or OpenBSD system. There is a bug in QEMU PCI emulation that prevents the NetBSD network driver to recognize the emulated network cards (See qemu-kvm 1.0 breaks openbsd, netbsd, freebsd). Ubuntu 12.04 and 12.10 provide a version of Qemu that has the problem. This is solved in Ubuntu 13.04, so this is the host linux distribution that I've installed.

For the virtual machine disk, I've setup some LVM partition on the host as follows:

sudo lvcreate -Z n -L 20G -n freebsd vg01

this creates a disk volume of 20G and label it freebsd.

The next step is to download the FreeBSD Installation CD (I've installed the FreeBSD-10.0-RC2). To manage the virtual machines, one can use the virsh command but the virt-manager graphical front-end provides an easier setup.

sudo virt-manager

The virtual machine is configured with:

  • CPU: x86_64
  • Memory: 1048576
  • Disk type: raw, source: /dev/vg01/freebsd
  • Network card model: e1000
  • Boot on the CD image

After the virtual machine starts, the FreeBSD installation proceeds (it was so simple that I took no screenshot at all).

Post installation

After the FreeBSD system is installed, it is almost ready to be used. Some additional packages are added by using the pkg install command (which is very close to the Debian apt-get command).

pkg install jed
pkg install sudo bash tcpdump

By default the /proc is not setup and some application like the OpenJDK need to access it. Edit the file /etc/fstab and add the following lines:

fdesc   /dev/fd         fdescfs         rw      0       0
proc    /proc           procfs          rw      0       0

and mount the new partitions with:

mount -a

GNAT installation

The FreeBSD repository provides some packages for Ada development. They are easily installed as follows:

pkg install gmake
pkg install gnat-aux-20130412_1 gprbuild-20120510
pkg install xmlada-4.4.0.0_1 zip-ada-45
pkg install aws-3.1.0.0
pkg install gdb-7.6.1_1

After the installation, change the path and setup the ADA_PROJECT_PATH variables to be able to use gnatmake:

export PATH=/usr/local/gcc-aux/bin:$PATH
export ADA_PROJECT_PATH=/usr/local/lib/gnat

Jenkins slave node installation

Jenkins uses a Java application that runs on each build node. It is necessary to install some Java JRE. To use subversion on the build node, we must make sure to install some 1.6 version since the 1.8 and 1.7 version have incompatibilities with the Jenkins master. The following packages are necessary:

pkg install openjdk6-jre-b28_7
pkg install subversion-1.6.23_2

Jenkins needs a user to connect to the build node. The user is created by the adduser command. The Jenkins user does not need any privilege.

Jenkins master will use SSH to connect to the slave node. During the first connection, it installs the slave.jarfile which manages the launch of remote builds on the slave. For the SSH connection, the password authentication is possible but I've setup a public key authentication that I've setup on the FreeBSD node by using ssh-copy-id.

At this stage, the FreeBSD build node is ready to be added on the Jenkins master node (through the Jenkins UI Manage Jenkins/Manage Nodes).

MySQL Installation

The MySQL installation is necessary for some of my projects. This is easily done as follows:

pkg install mysql55-server-5.5.35 mysql55-client-5.5.35

Then add the following line to /etc/rc.conf

mysql_enable="YES"

and start the server manyally:

/usr/local/etc/rc.d/mysql-server onestart

The database tables are setup during the first start.

Other packages

Some packages that are necessary for some projets:

pkg install autoconf-2.69 curl-7.33.0_1
pkg install ImageMagick-nox11-6.8.0.7_3

Jenkins jobs

The jenkins master is now building 7 projects automatically for FreeBSD 10: FreeBSD Ada Jobs

Ada Web Application 0.3.0 is available

By Stephane Carrez 2013-02-15 20:45:46

Ada Web Application is a framework to build web applications.

  • AWA uses Ada Server Faces for the web framework. This framework is using several patterns from the Java world such as Java Server Faces and Java Servlets.
  • AWA provides a set of ready to use and extendable modules that are common to many web application. This includes managing the login, authentication, users, permissions.
  • AWA uses an Object Relational Mapping that helps in writing Ada applications on top of MySQL or SQLite databases. The ADO framework allows to map database objects into Ada records and access them easily.
  • AWA is a model driven engineering framework that allows to design the application data model using UML and generate the corresponding Ada code.

Ada Web Application Architecture

The new version of AWA provides:

  • New jobs plugin to manage asynchronous jobs,
  • New storage plugin to manage a storage space for application documents,
  • New votes plugin to allow voting on items,
  • New question plugin to provide a general purpose Q&A.

AWA can be downloaded at http://code.google.com/p/ada-awa/downloads/list

A live demonstration of various features provided by AWA is available at http://demo.vacs.fr/atlas

Dynamo 0.6.0 is available

By Stephane Carrez 2013-02-10 21:57:02

Dynamo is a tool to help developers write some types of Ada Applications which use the Ada Server Faces or Ada Database Objects frameworks. Dynamo provides several commands to perform one specific task in the development process: creation of an application, generation of database model, generation of Ada model, creation of database.

The new version of Dynamo provides:

  • A new command build-doc to extract some documentation from the sources,
  • The generation of MySQL and SQLite schemas from UML models,
  • The generation of Ada database mappings from UML models,
  • The generation of Ada beans from the UML models,
  • A new project template for command line tools using ADO,
  • A new distribution command to merge the resource bundles.

The most important feature is probably the Ada code generation from a UML class diagram. With this, you can design the data model of an application using ArgoUML and generate the Ada model files that will be used to access the database easily through the Ada Database Objects library. The tool will also generate the SQL database schema so that everything is concistent from your UML model, to the Ada implementation and the database tables.

The short tutorial below indicates how to design a UML model with ArgoUML, generate the Ada model files, the SQL files and create the MySQL database.

The Dynamo tool is available at http://code.google.com/p/ada-gen.

To build Dynamo, you will need:

Ada Database Objects 0.4.0 is available

By Stephane Carrez 2013-02-10 21:38:42

The Ada Database Objects is an Object Relational Mapping for the Ada05 programming language. It allows to map database objects into Ada records and access databases easily. Most of the concepts developped for ADO come from the Java Hibernate ORM. ADO supports MySQL and SQLite databases.

The new version brings:

  • Support to reload query definitions,
  • It optimizes session factory implementation,
  • It allows to customize the MySQL database connection by using MySQL SET

This version can be downloaded at http://code.google.com/p/ada-ado/downloads/list.

Ada Server Faces 0.5.0 is available

By Stephane Carrez 2013-02-05 22:29:27

Ada Server Faces is an Ada implementation of several Java standard web frameworks.

  • The Java Servlet (JSR 315) defines the basis for a Java application to be plugged in Web servers. It standardizes the way an HTTP request and HTTP response are represented. It defines the mechanisms by which the requests and responses are passed from the Web server to the application possibly through some additional filters.
  • The Java Unified Expression Language (JSR 245) is a small expression language intended to be used in Web pages. Through the expressions, functions and methods it creates the link between the Web page template and the application data identified as beans.
  • The Java Server Faces (JSR 314 and JSR 344) is a component driven framework which provides a powerful mechanism for Web applications. Web pages are represented by facelet views (XHTML files) that are modelized as components when a request comes in. A lifecycle mechanism drives the request through converters and validators triggering events that are received by the application. Navigation rules define what result view must be rendered and returned.

Ada Server Faces gives to Ada developers a strong web framework which is frequently used in Java Web applications. On their hand, Java developers could benefit from the high performance that Ada brings: apart from the language, they will use the same design patterns.

Ada Server Faces

The new version of Ada Server Faces is available and brings the following changes:

  • The Security packages was moved in a separate project: Ada Security,
  • New demo to show OAuth and Facebook API integration,
  • Integrated jQuery 1.8.3 and jQuery UI 1.9.2,
  • New converter to display file sizes,
  • Javascript support was added for click-to-edit behavior,
  • Add support for JSF session beans,
  • Add support for servlet error page customization,
  • Allow navigation rules to handle exceptions raised by Ada bean actions,
  • Support the JSF 2.2 conditional navigation,
  • New functions fn:escapeXml and fn:replace.

The new version can be downloaded on the Ada Server Faces project page. A live demo is available at http://demo.vacs.fr/demo.

Ada Security 1.0.0 is available

By Stephane Carrez 2013-01-20 17:54:13

Ada Security is a security framework which allows web applications to define and enforce security policies. The framework allows users to authenticate by using OpenID Authentication 2.0. Ada Security also defines a set of client methods for using the OAuth 2.0 protocol.

Ada Security Framework

  • A security policy manager defines and implements the set of security rules that specify how to protect the system or the resources.
  • A user is authenticated in the application. Authentication can be based on OpenID or another system.
  • A security context holds the contextual information that allows the security policy manager to verify that the user is allowed to access the protected resource according to the policy rules.

The Ada Security framework can be downloaded at Ada Security project page.

The framework is the core security framework used by Ada Server Faces and Ada Web Application to protect access to resources.

Ada Utility Library 1.6.0 is available

By Stephane Carrez 2012-12-26 21:16:23

Ada Utility Library is a collection of utility packages for Ada 2005. A new version is available which provides:

  • Support for HTTP clients (curl, AWS, ...)
  • Support for REST APIs using JSON
  • New operations To_JSON and From_JSON for easy object map serialization
  • Added a listeners to help implementing the observer/listener design patterns
  • Added support for wildcard mapping in serialization framework
  • New option -d <dir> for the unit test harness to change the working directory,
  • New example facebook.adb to show the REST support.

It has been compiled and ported on Linux, Windows and Netbsd (gcc 4.4, GNAT 2011, gcc 4.6.3). You can download this new version at http://code.google.com/p/ada-util/downloads/list.

Atlas, the Ada Web Application demonstrator

By Stephane Carrez 2012-05-22 21:12:41

AWA is a framework to build web applications on top of various robust components.

  • AWA uses Ada Server Faces for the web framework. This framework is using several patterns from the Java world such as Java Server Faces and Java Servlets.
  • AWA is architectured arround modules and plugins that allow to build, re-use and extend modules made of Ada code, Web pages or Javascript.
  • AWA provides a set of ready to use and extendable plugins that are common to many web application. This includes managing the login, authentication, users, permissions, a mail plugin, a blog plugin, a Javascript light editor.
  • AWA uses an Object Relational Mapping that helps in writing Ada applications on top of MySQL or SQLite databases. The ADO framework allows to map database objects into Ada records and access them easily.
  • AWA integrates a configurable event service which allows plugins to easily interact and connect with each other (either synchronously or asynchronously). The event service provided by AWA is heavily inspired from the Java Message Service.

To learn more on how to create easily a web application using AWA, look at the 4 minutes video.

The Atlas Web Application Demonstrator is a demonstration of an application using this AWA framework.

Dynamo 0.5.0 is available

By Stephane Carrez 2012-05-20 19:48:13

Dynamo is a tool to help developers write an Ada Web Application using the Ada Server Faces and the Ada Database Objects frameworks. Dynamo provides several commands to perform one specific task in the development process: creation of an application, generation of database model, generation of Ada model, creation of database.

The new version of Dynamo provides:

  • Support multi-line comments in XML mappings,
  • Generate List_Bean types for the XML mapped queries,
  • Add support for Ada enum generation,
  • Add test template generation,
  • Add AWA service template generation,
  • Add support for blob model mapping,
  • New command 'add-ajax-form', 'add-query', 'dist', 'create-plugin'

The Dynamo tool is available at http://code.google.com/p/ada-gen. To build Dynamo, you will need:

Ada Database Objects 0.3.0 is available

By Stephane Carrez 2012-05-12 20:17:07

The Ada Database Objects is an Object Relational Mapping for the Ada05 programming language. It allows to map database objects into Ada records and access databases easily. Most of the concepts developped for ADO come from the Java Hibernate ORM. ADO supports MySQL and SQLite databases.

The new version brings:

  • Support to update database records when a field is really modified,
  • Customization of the SQLite database connection by using SQLite PRAGMAs,
  • Escape of MySQL or SQLite reserved keywords,
  • Support for blob type.

This version can be downloaded at http://code.google.com/p/ada-ado/downloads/list.

Ada Server Faces 0.4.0 is available

By Stephane Carrez 2012-05-11 21:12:36

Ada Server Faces is a web framework which uses the Java Server Faces design patterns (See JSR 252, JSR 314 or the latest one the JSR 344).

This new version brings a serious step ahead towards JSF compatibility. This new version provides:

  • Support for shared or static build configuration,
  • Support for file upload,
  • New components <h:inputFile>, <f:metadata>, <f:viewParam>, <f:viewAction>,
  • New EL function util:hasMessage,
  • ASF now Implements the JSF phase events and phase listeners,
  • Implements the JSF/Ruby on Rails flash context,
  • Adds the pre-defined JSF beans: initParam, flash,
  • Support for locales and honors the Accept-Language,
  • New demos are available in French and English

It has been compiled and ported on Linux, Windows and Netbsd (gcc 4.4, GNAT 2011, gcc 4.6.2). You can download this new version at http://code.google.com/p/ada-asf/downloads/list.

A live demo is available at: http://demo.vacs.fr.

Feel free to play with the OpenID stuff!!!

Ada Utility Library 1.5.0 is available

By Stephane Carrez 2012-05-09 20:30:36

Ada Utility Library is a collection of utility packages for Ada 2005. A new version is available which provides:

  • Concurrent fifo queues and arrays
  • Changed Objects.Maps to use a String instead of an Unbounded_String as the key
  • Support for shared or static build configuration
  • Implementation of input/output/error redirection to a file for process launch

It has been compiled and ported on Linux, Windows and Netbsd (gcc 4.4, GNAT 2011, gcc 4.6.2). You can download this new version at http://code.google.com/p/ada-util/downloads/list.

Process creation in Java and Ada

By Stephane Carrez 2012-03-16 20:06:26

When developping and integrating applications together it is often useful to launch an external program. By doing this, many integration and implementation details are simplified (this integration technic also avoids license issues for some open source software integration).

This article explains how to launch an external program in Java and Ada and be able to read the process output to get the result.

Java Process Creation

The process creation is managed by the ProcessBuilder Java class. An instance of this class holds the necessary information to create and launch a new process. This includes the command line and its arguments, the standard input and outputs, the environment variables and the working directory.

The process builder instance is created by specifying the command and its arguments. For this the constructor accepts a variable list of parameters of type String.

import java.lang.ProcessBuilder;
...
  final String cmd = "ls";
  final String arg1 = "-l";
  final ProcessBuilder pb = new ProcessBuilder(cmd, arg1);

When the process builder is initialized, we can invoke the start method to create a new process. Each process is then represented by an instance of the Process class. It is possible to invoke start serveral times and each call creates a new process. It is necessary to catch the IOExceptionwhich can be raised if the process cannot be created.

import java.lang.Process;
...
  try {
    final Process p = pb.start();
    ...

  } catch (final IOException ex) {
    System.err.println("IO error: " + ex.getLocalizedMessage());
  }

The Process class gives access to the process output through an input stream represented by the InputStream class. With this input stream, we can read what the process writes on its output. We will use a BufferedReader class to read that output line by line.

import java.io.*;
...
  final InputStream is = p.getInputStream();
  final BufferedReader reader = new BufferedReader(new InputStreamReader(is));

By using the readLine method, we can read a new line after each call. Once the whole stream is read, we have to close it. Closing the BufferedReader will close the InputStream associated with it.

  String line;
  while ((line = reader.readLine()) != null) {
    System.out.println(line);
  }
  reader.close();

Last step is to wait for the process termination and get the exit status: we can use the waitFor method. Since this method can be interrupted, we have to catch the InterruptedException.

  try {
    ...
    final int exit = p.waitFor();
    if (exit != 0) {
      System.err.printf("Command exited with status %d\n", exit);
    }
  }  catch (final InterruptedException ex) {
    System.err.println("Launch was interrupted...");
  }

You can get the complete source from the file: Launch.java

Ada Process Creation

For the Ada example, we will create an application that invokes the nslookup utility to resolve a set of host names. The list of host names is provided to nslookup by writing on its standard input and the result is collected by reading the output.

We will use the Pipe_Stream to launch the process, write on its input and read its output at the same time. The process is launched by calling the Open procedure and specifying the pipe redirection modes: READ is for reading the process output, WRITE is for writing to its input and READ_WRITEis for both.

with Util.Processes;
with Util.Streams.Pipes;
...
   Pipe    : aliased Util.Streams.Pipes.Pipe_Stream;

   Pipe.Open ("nslookup", Util.Processes.READ_WRITE);

We can read or write on the pipe directly but using a Print_Stream to write the text and the Buffered_Stream to read the result simplifies the implementation. Both of them are connected to the pipe: the Print_Stream will use the pipe output stream and the Buffered_Stream will use the pipe input stream.

with Util.Streams.Buffered;
with Util.Streams.Texts;
...
   Buffer  : Util.Streams.Buffered.Buffered_Stream;
   Print   : Util.Streams.Texts.Print_Stream;
begin
      --  Write on the process input stream
   Buffer.Initialize (null, Pipe'Unchecked_Access, 1024);
   Print.Initialize (Pipe'Unchecked_Access);

Before reading the process output, we send the input data to be solved by the process. By closing the print stream, we also close the pipe output stream, thus closing the process standard input.

   Print.Write ("www.google.com" & ASCII.LF);
   Print.Write ("set type=NS" & ASCII.LF);
   Print.Write ("www.google.com" & ASCII.LF);
   Print.Write ("set type=MX" & ASCII.LF);
   Print.Write ("www.google.com" & ASCII.LF);
   Print.Close;

We can now read the program output by using the Read procedure and get the result in the Content string. The Close procedure is invoked on the pipe to close the pipe (input and output) and wait for the application termination.

   Content : Unbounded_String;

   --  Read the 'nslookup' output.
   Buffer.Read (Content);
   Pipe.Close;

Once the process has terminated, we can get the exit status by using the Get_Exit_Status function.

   Ada.Text_IO.Put_Line ("Exit status: "
       & Integer'Image (Pipe.Get_Exit_Status));


References

launch.adb

util-streams-pipes.ads

util-streams-buffered.ads

util-streams-texts.ads

Ada Server Faces 0.3.0 is available

By Stephane Carrez 2012-02-14 21:09:39

Ada Server Faces is a web framework which uses the Java Server Faces design patterns (See JSR 252 and JSR 314).

JSF and ASF use a component-based model for the design and implementation of a web application. The presentation layer is implemented using XML or XHTML files and the component layer is implemented in Ada 05 for ASF and in Java for JSF.

A new version of ASF is available which provides:

  • New components used in HTML forms (textarea, select, label, hidden),
  • New components for the AJAX framework,
  • Support for dialog boxes with jQuery UI,
  • Pre-defined beans in ASF contexts: param, header,
  • A complete set of example and documentation for each tag.

It has been compiled and ported on Linux, Windows and Netbsd (gcc 4.4, GNAT 2011, gcc 4.6.2). You can download this new version at http://code.google.com/p/ada-asf/downloads/list.

A live demo is available at: http://demo.vacs.fr.

Ada perfect hash generation with gperfhash

By Stephane Carrez 2012-01-16 21:31:23

A perfect hash function is a function that returns a distinct hash number for each keyword of a well defined set. gperf is famous and well known perfect hash generator used for C or C++ languages. Ada is not supported.

The gperfhash is a sample from the Ada Utility Library which generates an Ada package that implements such perfect hash operation. It is not as complete as gperf but allows to easily get a hash operation. The gperfhash tool uses the GNAT package GNAT.Perfect_Hash_Generators.

Pre requisite

Since the gperfhash tool is provided by the Ada Util samples, you must build these samples with the following command:

$ gnatmake -Psamples

Define a keyword file

First, create a file which contains one keyword on each line. For example, let's write a keywords.txt file which contains the following three keywords:

int
select
print

Generate the package

Run the gperfhash tool and give it the package name.

$ gperfhash -p Hashing keywords.txt

The package defines a Hash and an Is_Keyword function. The Hash function returns a hash number for each string passed as argument. The hash number will be different for each string that matches one of our keyword. You can give a string not in the keyword list, in that case the hash function will return a number that collides with a hash number of one or our keyword.

The Is_Keyword function allows to check whether a string is a keyword of the list. This is very useful when you just want to know whether a string is a reserved keyword in some application.

The package specification is the following:

--  Generated by gperfhash
package Hashing is

   function Hash (S : String) return Natural;

   --  Returns true if the string <b>S</b> is a keyword.
   function Is_Keyword (S : in String) return Boolean;

   type Name_Access is access constant String;
   type Keyword_Array is array (Natural range <>) of Name_Access;
   Keywords : constant Keyword_Array;
private
...
end Hashing;

How to use the hash

Using the perfect hash generator is simple:

with Hashing;

  if Hashing.Is_Keyword (S) then
     -- 'S' is one of our keyword
  else
     -- No, it's not a keyword
  end if;

Ada Utility Library 1.4.0 is available

By Stephane Carrez 2012-01-15 19:32:22

Ada Utility Library is a collection of utility packages for Ada 2005. A new version is available which provides:

  • Support for localized date format,
  • Support for process creation and pipe streams (on Unix and Windows),
  • Support for CSV in the serialization framework,
  • Integration of Ahven 2.1 for the unit tests (activate with --enable-ahven),
  • A tool to generate perfect hash function

It has been compiled and ported on Linux, Windows and Netbsd (gcc 4.4, GNAT 2011, gcc 4.6.2). You can download this new version at http://code.google.com/p/ada-util/downloads/list.

Aunit vs Ahven

By Stephane Carrez 2011-11-27 17:25:44

AUnit and Ahven are two testing frameworks for Ada. Both of them are inspired from the well known JUnit Java framework. Having some issues with the Aunit testing framework, I wanted to explore the use of Ahven. This article gives some comparison elements between the two unit test frameworks. I do not pretend to list all the differences since both frameworks are excellent.

Writing a unit test is equally simple in both frameworks. They however have some differences that may not be visible at the first glance.

AUnit

AUnit is a unit test framework developped by Ed Falis and maintained by AdaCore. It is distributed under the GNU GPL License.

Some good points:

  • AUnit has a good support to report where a test failed. Indeed, the Assert procedures will report the source file and line number where the assertion failed.
  • AUnit is also able to dump the exception stack trace in symbolic form. This is useful to find out quickly the source of a problem.

Some bad points:

  • AUnit has several memory leaks which is quite annoying when you want to track memory links with valgrind.
  • AUnit does not integrate easily with JUnit-based XML tools. In particular the XML file it creates can be invalid in some cases (special characters in names). More annoying is the fact that the XML format is not compatible with JUnit XML format.

Ahven

Ahven is another unit test framework developped by Tero Koskinen. It is distributed under the permissive ISC License.

Some good points:

  • Ahven license is a better model for proprietary unit tests.
  • Ahven generates XML result files which are compatible with Junit XML result files. Integration with automatic build tools such as Jenkins is easier.
  • Ahven XML result files can integrate the test output (as in JUnit). This is useful to analyze a problem.
  • Ahven has a test case timeout which is useful to detect and stop blocking tests.

Some bad points:

  • The lack of precise information in message (source line, exception trace) can be annoying to find out why a test failed.

Don't choose and be prepared to use both with Ada Util

The unit tests I've written were done for AUnit and I had arround 329 tests to migrate. To help the migration to Ahven, I wrote a Util.XUnit package which exposes a common interface on top of AUnit or Ahven. It turns out that this is easy and quite small. The package has one specific implementation (spec+body) for both frameworks. All the unit tests have to use it instead of the AUnit or Ahven packages.

The Aunit implementation (util-xunit.ads) defines several types which are also defined in the Ahven implementation.

package Util.XUnit is
...
   subtype Status is AUnit.Status;

   Success : constant Status := AUnit.Success;
   Failure : constant Status := AUnit.Failure;

   subtype Message_String is AUnit.Message_String;
   subtype Test_Suite is AUnit.Test_Suites.Test_Suite;
   subtype Access_Test_Suite is AUnit.Test_Suites.Access_Test_Suite;

   type Test_Case is abstract new AUnit.Simple_Test_Cases.Test_Case with null record;
   type Test is abstract new AUnit.Test_Fixtures.Test_Fixture with null record;
...
end Util.XUnit;

The XUnit implementation for Ahven is a little bit more complex because all my tests were using AUnit interface, I decided to keep almost that API and thus I had to simulate what is missing or is different.

Ahven implementation: util-xunit.ads

package Util.XUnit is
...
   type Status is (Success, Failure);

   subtype Message_String is String;
   subtype Test_Suite is Ahven.Framework.Test_Suite;
   type Access_Test_Suite is access all Test_Suite;

   type Test_Case is abstract new Ahven.Framework.Test_Case with null record;
   type Test is new Ahven.Framework.Test_Case with null record;
...
end Util.XUnit;

The choice of the unit test framework is done when the Ada Utility library is configured.

Thread safe object pool to manage scarce resource in application servers

By Stephane Carrez 2011-05-29 19:47:39

Problem Description

In application servers some resources are expensive and they must be shared. This is the case for a database connection, a frame buffer used for image processing, a connection to a remote server, and so on. The problem is to make available these scarce resources in such a way that:

  • a resource is used by only one thread at a time,
  • we can control the maximum number of resources used at a time,
  • we have some flexibility to define such maximum when configuring the application server,
  • and of course the final solution is thread safe.

The common pattern used in such situation is to use a thread-safe pool of objects. Objects are picked from the pool when needed and restored back to the pool when they are no longer used.

Java thread safe object pool

Let's see how to implement our object pool in Java. We will use a generic class declaration into which we define a fixed array of objects. The pool array is allocated by the constructor and we will assume it will never change (hence the final keyword).

public class Pool<T> {
  private final T[] objects;
 
  public Pool<T>(int size) {
     objects = new T[size];
  }
  ...
}

First, we need a getInstance method that picks an object from the pool. The method must be thread safe and it is protected by the synchronized keyword. It there is no object, it has to wait until an object is available. For this, the method invokes wait to sleep until another thread releases an object. To keep track of the number of available objects, we will use an available counter that is decremented each time an object is used.

  private int available = 0;
  private int waiting = 0;
  public synchronized T getInstance() {
     while (available == 0) {
        waiting++;
        wait();
        waiting--;
     }
     available--;
     return objects[available];
  }

To know when to wakeup a thread, we keep track of the number of waiters in the waiting counter. A loop is also necessary to make sure we have an available object after being wakeup. Indeed, there is no guarantee that after being notified, we have an available object to return. The call to wait will release the lock on the pool and puts the thread is wait mode.

Releasing the object is provided by release. The object is put backed in the pool array and the available counter incremented. If some threads are waiting, one of them is awaken by calling notify.

  public synchronized void release(T obj) {
     objects[available] = obj;
     available++;
     if (waiting) {
        notify();
     }
  }

When the application is started, the pool is initialized and some pre-defined objects are inserted.

   class Item { ... };
...
   Pool<Item> pool = new Pool<Item>(10);
   for (int i = 0; i < 10; i++) {
       pool.release(new Item());
   }

Ada thread safe pool

The Ada object pool will be defined in a generic package and we will use a protected type. The protected type will guarantee the thread safe behavior of the implementation by making sure that only one thread executes the procedures.

generic
   type Element_Type is private;
package Util.Concurrent.Pools is
     type Element_Array_Access is private;
     Null_Element_Array : constant Element_Array_Access;
  ...
private
    type Element_Array is array (Positive range <>) of Element_Type;
    type Element_Array_Access is access all Element_Array;
     Null_Element_Array : constant Element_Array_Access := null;
end Util.Concurrent.Pools;   

The Ada protected type is simple with three procedures, we get the Get_Instanceand Release as in the Java implementation. The Set_Size will take care of allocating the pool array (a job done by the Java pool constructor).

protected type Pool is
  entry Get_Instance (Item : out Element_Type);
  procedure Release (Item : in Element_Type);
  procedure Set_Size (Capacity : in Positive);
private
  Available     : Natural := 0;
  Elements      : Element_Array_Access := Null_Element_Array;
end Pool;

First, the Get_Instance procedure is defined as an entry so that we can define a condition to enter in it. Indeed, we need at least one object in the pool. Since we keep track of the number of available objects, we will use it as the entry condition. Thanks to this entry condition, the Ada implementation is a lot easier.

protected body Pool is
  entry Get_Instance (Item : out Element_Type) when Available > 0 is
  begin
     Item := Elements (Available);
     Available := Available - 1;
  end Get_Instance;
...
end Pool;

The Release operation is also easier as there is no need to wakeup any thread: the Ada runtime will do that for us.

protected body Pool is
   procedure Release (Item : in Element_Type) is
   begin
      Available := Available + 1;
      Elements (Available) := Item;
   end Release;
end Pool;

The pool is instantiated:

type Connection is ...;
package Connection_Pool is new Util.Concurrent.Pools (Connection);

And a pool object can be declared and initialized with some default object:

P : Connection_Pool.Pool;
C : Connection;
...
   P.Set_Size (Capacity => 10);
   for I in 1 .. 10 loop
         ...
         P.Release (C);
   end loop;

References

util-concurrent-pools.ads

util-concurrent-pools.adb

Ada Server Faces Application Example part 3: the action bean

By Stephane Carrez 2011-05-02 21:01:32

In a previous article, I presented in the cylinder volume example the Ada Server Faces presentation layer and then the Ada beans that link the presentation and ASF components together. This article explains how to implement an action bean and have a procedure executed when a button is pressed.

Command buttons and method expression

We have seen in the presentation layer how to create a form and have a submit button. This submit button can be associated with an action that will be executed when the button is pressed. The EL expression is the mechanism by which we create a binding between the XHTML presentation page and the component implemented in Java or Ada. A method expression is a simple EL expression that represents a bean and a method to invoke on that bean. This method expression represent our action.

A typical use is on the h:commandButton component where we can specify an action to invoke when the button is pressed. This is written as:

<h:commandButton id='run' value='Compute'
       action="#{compute.run}"/>

The method expression #{compute.run} indicates to execute the method run of the bean identified by compute.

Method Bean Declaration

Java implements method expressions by using reflection. It is able to look at the methods implemented by an object and then invoke one of these method with some parameters. Since we cannot do this in Ada, some developer help is necessary.

For this an Ada bean that implements an action must implement the Method_Bean interface. If we take the Compute_Bean type defined in the Ada beans previous article, we just have to extend that interface and implement the Get_Method_Bindings function. This function will indicate the methods which are available for an EL expression and somehow how they can be called.

with Util.Beans.Methods;
...
   type Compute_Bean is new Util.Beans.Basic.Bean
          and Util.Beans.Methods.Method_Bean with record
      Height : My_Float := -1.0;
      Radius : My_Float := -1.0;
      Volume: My_Float := -1.0;
   end record;
   --  This bean provides some methods that can be used in a Method_Expression
   overriding
   function Get_Method_Bindings (From : in Compute_Bean)
      return Util.Beans.Methods.Method_Binding_Array_Access;

Our Ada type can now define a method that can be invoked through a method expression. The action bean always receives the bean object as an in out first parameter and it must return the action outcome as an Unbounded_String also as in out.

 procedure Run (From    : in out Compute_Bean;
                         Outcome : in out Unbounded_String);

Implement the action

The implementation of our action is quite simple. The Radius and Height parameters submitted in the form have been set on the bean before the action is called. We can use them to compute the cylinder volume.

procedure Run (From    : in out Compute_Bean;
                        Outcome : in out Unbounded_String) is
      V : My_Float;
   begin
      V := (From.Radius * From.Radius);
      V := V * From.Height;
      From.Volume := V * 3.141;
      Outcome := To_Unbounded_String ("compute");
   end Run;

Define the action binding

To be able to call the Run procedure from an EL method expression, we have to create a binding object. This binding object will hold the method name as well as a small procedure stub that will somehow tie the method expression to the procedure. This step is easily done by instantiating the ASF.Events.Actions.Action_Method.Bind package.

with ASF.Events.Actions;
...
   package Run_Binding is
     new ASF.Events.Actions.Action_Method.Bind
        (Bean  => Compute_Bean,
         Method => Run,
         Name    => "run");

Register and expose the action bindings

The last step is to implement the Get_Method_Bindings function. Basically it has to return an array of method bindings which indicate the methods provided by the Ada bean.

Binding_Array : aliased constant Util.Beans.Methods.Method_Binding_Array
  := (Run_Binding.Proxy'Unchecked_Access, Run_Binding.Proxy'Unchecked_Access);

overriding
function Get_Method_Bindings (From : in Compute_Bean)
   return Util.Beans.Methods.Method_Binding_Array_Access is
begin
   return Binding_Array'Unchecked_Access;
end Get_Method_Bindings;

What happens now?

When the user presses the Compute button, the brower will submit the form and the ASF framework will do the following:

  • It will check the validity of input parameters,
  • It will save the input parameters on the compute bean,
  • It will execute the method expression #{compute.run}:
  • It calls the Get_Method_Bindings function to get a list of valid method,
  • Having found the right binding, it calls the binding procedure
  • The binding procedure invokes the Run procedure on the object.

Next time...

We have seen the presentation layer, how to implement the Ada bean and this article explained how to implement an action that is called when a button is pressed. The next article will explain how to initialize and build the web application.

Ada Server Faces Application Example part 4: the server

By Stephane Carrez 2011-04-18 20:35:58

In previous articles, we have seen that an Ada Server Faces application has a presentation layer composed of XHTML and CSS files. Similar to Java Server Faces, Ada Server Faces is a component-based model and we saw how to write the Ada beans used by the application. Later, we also learnt how an action bean can have a procedure executed when a button is pressed. Now, how can all these stuff fit together?

Well, to finish our cylinder volume example, we will see how to put everything together and get our running web application.

Application Initialization

An Ada Server Faces Application is represented by the Application type which holds all the information to process and dispatch requests. First, let's declare a variable that represents our application.

Note: for the purpose of this article, we will assume that every variable is declared at some package level scope. If those variables are declared in another scope, the Access attribute should be replaced by Unchecked_Access.

with ASF.Applications.Main;
...
   App : aliased ASF.Applications.Main.Application;

To initialize the application, we will also need some configuration properties and a factory object. The configuration properties are used to configure the various components used by ASF. The factory allows to customize some behavior of Ada Server Faces. For now, we will use the default factory.

with ASF.Applications;
...
   C        : ASF.Applications.Config;
   Factory : ASF.Applications.Main.Application_Factory;

The initialization requires to define some configuration properties. The VIEW_EXT property indicates the URI extension that are recognized by ASF to associate an XHTML file (the compute.html corresponds to the XHTML file compute.xhtml). The VIEW_DIR property defines the root directory where the XHTML files are stored.

C.Set (ASF.Applications.VIEW_EXT, ".html");
C.Set (ASF.Applications.VIEW_DIR, "samples/web");
C.Set ("web.dir", "samples/web");
App.Initialize (C, Factory);

Servlets

Ada Server Faces uses the Ada Servlet framework to receive and dispatch web requests. It provides a Faces_Servlet servlet which can be plugged in the servlet container. This servlet is the entry point for ASF to process incoming requests. We will also need a File_Servlet to process the static files. Note that these servlets are implemented using tagged records and you can easily override the entry points (Do_Get or Do_Post) to implement specific behaviors.

with ASF.Servlets.Faces;
with ASF.Servlets.Files;
...
   Faces : aliased ASF.Servlets.Faces.Faces_Servlet;
   Files   : aliased ASF.Servlets.Files.File_Servlet;

The servlet instances are registered in the application.

App.Add_Servlet (Name => "faces", Server => Faces'Access);
App.Add_Servlet (Name => "files", Server => Files'Access);

Once registered, we have to define a mapping that tells which URI path is mapped to the servlet.

App.Add_Mapping (Name => "faces", Pattern => "*.html");
App.Add_Mapping (Name => "files", Pattern => "*.css");

For the purpose of debugging, ASF provides a servlet filter that can be plugged in the request processing flow. The Dump_Filter will produce a dump of the request with the headers and parameters.

with ASF.Filters.Dump;
...
   Dump    : aliased ASF.Filters.Dump.Dump_Filter;

The filter instance is registered as follows:

App.Add_Filter (Name => "dump", Filter => Dump'Access);

And a mapping is defined to tell which URL will trigger the filter.

App.Add_Filter_Mapping (Name => "dump", Pattern => "*.html");

Application and Web Container

The application object that we created is similar to a Java Web Application packaged in a WAR file. It represents the application and it must be deployed in a Web Container. With Ada Server Faces this is almost the same, the application needs a Web container. By default, ASF provides a web container based on the excellent Ada Web Server implementation (other web containers could be provided in the future based on other web servers).

with ASF.Server.Web;
...
   WS : ASF.Server.Web.AWS_Container;

To register the application, we indicate the URI context path to which the application is associated. Several applications can be registered, each of them having a unique URI context path.

CONTEXT_PATH : constant String := "/volume";
...
WS.Register_Application (CONTEXT_PATH, App'Access);

Global Objects

An application can provide some global objects which will be available during the request processing through the EL expression. First, we will expose the application context path which allows to write links in the XHTML page that match the URI used for registering the application in the web container.

App.Set_Global ("contextPath", CONTEXT_PATH);

Below is an example of use of this contextPath variable:

<link media="screen" type="text/css" rel="stylesheet"
      href="#{contextPath}/themes/main.css"/>

Now, we will register the bean that we created for our application! This was explained in the Ada beans previous article.

with Volume;
...
   Bean    : aliased Volume.Compute_Bean;
...
   App.Set_Global ("compute", Util.Beans.Objects.To_Object (Bean'Access));

Note: For the purpose of this example, the Compute_Bean is registered as a global object. This means that it will be shared by every request. A future article will explain how to get a session or a request bean as in Java Server Faces.

Starting the server

Once the application is registered, we can start our server. Note that since Ada Web Server starts several threads that listen to requests, the Start procedure does not block and returns as soon as the server is started. The delay is necessary to let the server wait for requests during some time.

WS.Start;
delay 1000.0;

What happens to a request?

Let's say the server receives a HTTP GET request on /volume/compute.html. Here is what happens:

Volume ASF Flow

  • Ada Web Server receives the HTTP request
  • It identifies the application that matches /volume (our context path) and gives the control to it
  • The application identifies the servlet that processes the remaining URI, which is compute.html
  • It gives the control to the Dump_Filter filter and then to the Faces_Servlet servlet,
  • The faces servlet identifies the XHTML facelet file and reads the compute.xhtml file
  • ASF builds the component tree that describes the page and invokes the render response phase
  • While rendering, the EL expressions such as #{compute.radius} are evaluated and the value is obtained on our Bean global instance.
  • The HTML content is produced as part of the rendering process and returned by AWS.

References

asf_volume_server.adb

volume.ads

volume.adb

compute.xhtml

Ada Server Faces Application Example part 2: the Ada beans

By Stephane Carrez 2011-04-10 19:46:24

The first article explained how to design the presentation page of an Ada Server Faces application. This article presents the Ada beans that are behind the presentation page.

Ada Bean and presentation layer

We have seen that the presentation page contains components that make references to Ada beans with an EL expression.

<h:inputText id='height' size='10' value='#{compute.height}'>
        <f:converter converterId="float" />
</h:inputText>

The #{compute.height} is an EL expression that refers to the height property of the Ada bean identified as compute.

Writing the Cylinder Ada Bean

The Ada bean is a instance of an Ada tagged record that must implement a getter and a setter operation. These operations are invoked through an EL expression. Basically the getter is called when the view is rendered and the setter is called when the form is submitted and validated. The Bean interface defines the two operations that must be implemented by the Ada type:

with Util.Beans.Basic;
with Util.Beans.Objects;
...
   type Compute_Bean is new Util.Beans.Basic.Bean with record
      Height : My_Float := -1.0;
      Radius : My_Float := -1.0;
   end record;

   --  Get the value identified by the name.
   overriding
   function Get_Value (From : Compute_Bean;
                       Name : String) return Util.Beans.Objects.Object;

   --  Set the value identified by the name.
   overriding
   procedure Set_Value (From  : in out Compute_Bean;
                        Name  : in String;
                        Value : in Util.Beans.Objects.Object);

The getter and setter will identify the property to get or set through a name. The value is represented by an Object type that can hold several data types (boolean, integer, floats, strings, dates, ...). The getter looks for the name and returns the corresponding value in an Object record. Several To_Object functions helps in creating the result value.

   function Get_Value (From : Compute_Bean;
                       Name : String) return Util.Beans.Objects.Object is
   begin
      if Name = "radius" and From.Radius >= 0.0 then
         return Util.Beans.Objects.To_Object (Float (From.Radius));

      elsif Name = "height" and From.Height >= 0.0 then
         return Util.Beans.Objects.To_Object (Float (From.Height));

      else
         return Util.Beans.Objects.Null_Object;
      end if;
   end Get_Value;

The setter is similar.

   procedure Set_Value (From  : in out Compute_Bean;
                        Name  : in String;
                        Value : in Util.Beans.Objects.Object) is
   begin
      if Name = "radius" then
         From.Radius := My_Float (Util.Beans.Objects.To_Float (Value));
      elsif Name = "height" then
         From.Height := My_Float (Util.Beans.Objects.To_Float (Value));
      end if;
   end Set_Value;

Register the Cylinder Ada Bean

The next step is to register the cylinder bean and associate it with the compute name. There are several ways to do that but for the purpose of this example, there will be a global instance of the bean. That instance must be aliased so that we can use the Access attributes.

 Bean  : aliased Compute_Bean;

The Ada bean is registered on the application object by using the Set_Global procedure. This creates a global binding between a name and an Object record. In our case, the object will hold a reference to the Ada bean.

App : aliased ASF.Applications.Main.Application;
...
   App.Set_Global ("compute", Util.Beans.Objects.To_Object (Bean'Unchecked_Access));

Next Time...

We have seen how the presentation layer and the Ada beans are associated. The next article will present the action binding that links the form submission action to an Ada bean method.

Thread safe cache updates in Java and Ada

By Stephane Carrez 2011-04-07 19:44:57

Problem Description

The problem is to update a cache that is almost never modified and only read in multi-threaded context. The read performance is critical and the goal is to reduce the thread contention as much as possible to obtain a fast and non-blocking path when reading the cache.

Cache Declaration

Java Implementation

Let's define the cache using the HashMap class.

public class Cache {
   private HashMap<String,String> map = new HashMap<String, String>();
}

Ada Implementation

In Ada, let's instantiate the Indefinite_Hashed_Maps package for the cache.

with Ada.Strings.Hash;
with Ada.Containers.Indefinite_Hashed_Maps;
...
  package Hash_Map is
    new Ada.Containers.Indefinite_Hashed_Maps (Key_Type => String,
                       Element_Type => String,
                       Hash => Hash,
                       "=" => "=");

  Map : Hash_Map.Map;

Solution 1: safe and concurrent implementation

This solution is a straightforward solution using the language thread safe constructs. In Java this solution does not allow several threads to look at the cache at the same time. The cache access will be serialized. This is not a problem with Ada, where multiple concurrent readers are allowed. Only writing locks the cache object

Java Implementation

The thread safe implementation is protected by the synchronized keyword. It guarantees mutual exclusions of threads invoking the getCacheand addCache methods.

   public synchronized String getCache(String key) {
      return map.get(key);
   }
   public synchronized void addCache(String key, String value) {
      map.put(key, value);
   }

Ada Implementation

In Ada, we can use the protected type. The cache could be declared as follows:

  protected type Cache is
    function Get(Key : in String) return String;
    procedure Put(Key, Value: in String);
  private
    Map : Hash_Map.Map;
  end Cache;

and the implementation is straightforward:

  protected body Cache is
    function Get(Key : in String) return String is
    begin
       return Map.Element (Key);
    end Get;
    procedure Put(Key, Value: in String) is
    begin
       Map.Insert (Key, Value);
    end Put;
  end Cache;

Pros and Cons

+: This implementation is thread safe.

-: In Java, thread contention is high as only one thread can look in the cache at a time.

-: In Ada, thread contention occurs only if another thread updates the cache (which is far better than Java but could be annoying for realtime performance if the Put operation takes time).

-: Thread contention is high as only one thread can look in the cache at a time.

Solution 2: weak but efficient implementation

The Solution 1 does not allow multiple threads to access the cache at the same time, thus providing a contention point. The second solution proposed here, removes this contention point by relaxing some thread safety condition at the expense of cache behavior.

In this second solution, several threads can read the cache at the same time. The cache can be updated by one or several threads but the update does not guarantee that all entries added will be present in the cache. In other words, if two threads update the cache at the same time, the updated cache will contain only one of the new entry. This behavior can be acceptable in some cases and it may not fit for all uses. It must be used with great care.

Java Implementation

A cache entry can be added in a thread-safe manner using the following code:

   private volatile HashMap<String, String> map = new HashMap<String, String>();
   public String getCache(String key) {
      return map.get(key);
   }
   public void addCache(String key, String value) {
      HashMap<String, String> newMap = new HashMap<String, String>(map);

      newMap.put(newKey, newValue);
      map = newMap;
   }

This implementation is thread safe because the hash map is never modified. If a modification is made, it is done on a separate hash map object. The new hash map is then installed by the map = newMap assignment operation which is atomic. Again this code extract does not guarantee that all the cache entries added will be part of the cache.

Ada Implementation

The Ada implementation is slightly more complex basically because there is no garbage collector. If we allocate a new hash map and update the access pointer, we still have to free the old hash map when no other thread is accessing it.

The first step is to use a reference counter to automatically release the hash table when the last thread finishes its work. The reference counter will handle memory management issues for us. An implementation of thread-safe reference counter is provided by Ada Util. In this implementation, counters are updated using specific instruction (See Showing multiprocessor issue when updating a shared counter).

with Util.Refs;
...
   type Cache is new Util.Refs.Ref_Entity with record
      Map : Hash_Map.Map;
   end record;
   type Cache_Access is access all Cache;

   package Cache_Ref is new Util.Refs.References (Element_Type => Cache,
                Element_Access => Cache_Access);

  C : Cache_Ref.Atomic_Ref;

Source: Util.Refs.ads, Util.Refs.adb

The References package defines a Ref type representing the reference to a Cache instance. To be able to replace a reference by another one in an atomic manner, it is necessary to use the Atomic_Ref type. This is necessary because the Ada assignment of an Ref type is not atomic (the assignment copy and the call to the Adjust operation to update the reference counter are not atomic). The Atomic_Ref type is a protected type that provides a getter and a setter. Their use guarantees the atomicity.

    function Get(Key : in String) return String is
      R : constant Cache_Ref.Ref := C.Get;
    begin
       return R.Value.Map.Element (Key); -- concurrent access
    end Get;
    procedure Put(Key, Value: in String) is
       R : constant Cache_Ref.Ref := C.Get;
       N : constant Cache_Ref.Ref := Cache_Ref.Create;
    begin
       N.Value.all.Map := R.Value.Map;
       N.Value.all.Insert (Key, Value);
       C.Set (N); -- install the new map atomically
    end Put;

Pros and Cons

+: high performance in SMP environments

+: no thread contention in Java

-: cache update can loose some entries

-: still some thread contention in Ada but limited to copying a reference (C.Set)

Ada Server Faces Application Example part 1: the presentation

By Stephane Carrez 2011-03-21 21:25:30

Ada Server Faces is a framework which allows to write and build web applications. This article presents through a simple example how to use ASF to write a simple web application.

ASF Overview

Ada Server Faces uses a model which is very close to Java Server Faces. JSF and ASF use a component-based model for the design and implementation of a web application. Like traditional MVC models, the presentation layer is separated from the control and model parts. Unlike the MVC model, JSF and ASF are not request-based meaning there is not a specific controller associated with the request. Instead, each component that is part of the page (view) participate in the control and each component brings a piece of the model.

This first article will focus on the presentation layer through a simple example.

Cylinder Volume Example

The example computes the volume of a cylinder. A simple form with two input fields allows to enter the cylinder dimensions (the unit does not matter).

Volume form

ASF Templating

The presentation part is implemented by a facelet file and a CSS file. The facelet file is an XML file which contains XHTML elements as well as facelets and JSF/ASF components. The facelets and ASF components are specified in their own XML namespace. The ASF components form a tree of components (UIComponent) which is then used for displaying and processing form submissions.

At the root of the XML file is an f:view component which represents the root of the component tree. The typical page layout looks as follows. Note the #{contextPath} notation in the link reference. This is an EL expression that will be evaluated when the view is displayed (rendered in JSF terminology).

<f:view contentType="text/html"
        xmlns:ui="http://java.sun.com/jsf/facelets"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:c="http://java.sun.com/jstl/core"
	xmlns:u="http://code.google.com/p/ada-asf/util"
        xmlns:h="http://java.sun.com/jsf/html">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <link media="screen" type="text/css" rel="stylesheet"
      href="#{contextPath}/themes/main.css"/>
    <title>Volume Cylinder</title>
</head>
<body>
  <div>
     <h1>Compute the volume of a cylinder</h1>
     ...
  </div>
</body>
</html>
</f:view>

The form, input fields and submit buttons have to be specified using a JSF/ASF component. The JSF/ASF component will make the link between the presentation (view) and the controller (beans). The h:form is the JSF/ASF component that represents our form. Note that there is no need to specify any form action attribute: the form action will be managed by JSF/ASF.

The input fields are identified by the h:input components. The input field is linked to the bean through the value EL expression. This expression specifies the bean name and attribute. When rendering the view, JSF/ASF will fetch the value from the named bean. On form submission, JSF/ASF will populate the bean with the submitted value.

The h:input component can contain a f:converter element which indicates a conversion operation to call when displaying or before populating the bean value.

<h:form id='compute'>
  <dl>
    <dt>Height</dt>
    <dd>
      <h:inputText id='height' size='10' value='#{compute.height}'>
        <f:converter converterId="float" />
      </h:inputText>
    </dd>
    <dt>Radius</dt>
    <dd>
        <h:inputText id='radius' size='10' value='#{compute.radius}'>
           <f:converter converterId="float"/>
        </h:inputText>
    </dd>
    <dt></dt>
    <dd>
        <h:commandButton id='run' value='Compute'
       action="#{compute.run}"/>
    </dd>
  </dl>
</h:form>

At the form end, the h:commandButton represents the submit button and the controller action to invoke on form submission. The method to invoke is defined with an EL method expression in the action attribute. Before invoking the method, JSF/ASF will verify the submitted values, convert them according to associated converters, populate the beans with the values.

Style

The page style is provided by a specific CSS file. The dl/dt/dd list is rendered as a table using the following CSS definitions. By changing the CSS file, a new presentation can be provided to users.

dl {
  float: left;
  width: 500px;
  border: 1px solid #bcd;
  background-color: #ffffff;
  padding: 10px;
  -moz-border-radius: 6px;
  -webkit-border-radius: 6px 6px;
}
dt {
  clear: left;
  float: left;
  font-weight: bold;
  width: 20%;
  height: 20px;
  line-height: 24px;
  padding: 5px;
}
dd {
  float: left;
  padding: 5px;
}

Next time...

In this article, I've shown how to write the presentation and style part of an Ada Server Faces application. The next article will present the Ada beans that are associated with this example.

Integrating the project subversion revision in an Ada application log

By Stephane Carrez 2011-03-05 21:47:21

In software development it is often necessary to know the revision number that was used to build an application or a library. This is specially useful when a problem occurred to get and look at the good sources. Integrating this information automatically in the build process is a common practice. This article explains how an Ada application can report the subversion repository and revision in an application log.

Subversion keyword substitution

Subversion provides a substitution feature which allows to replace some pre-defined keywords by the file revision, the last modified date or the last author. In an Ada source, we could declare the following string variables:

package Version is
   Revision : constant String := "$Rev$";
   Head_URL : constant String := "$HeadURL$";
end Version;

To activate the keyword substitution you have to set some subversion property on the file:

$ svn propset svn:keywords "Revision HeadURL" version.ads

Each time the file is committed, the keywords will be replaced to integrate the new value. The expanded string will look like:

$Rev: 318 $
$HeadURL: https://ada-util.googlecode.com/svn/trunk $

The issue with subversion keyword substitution is that the information reported only concerns the file changed not the revision of the project (as returned by svnversion for example). In other words, it is necessary to change the version.ads file to get an updated revision number.

Keyword substitution with gnatprep

The gnatprep tool is a pre-processor provided by the GNAT Ada compiler. It reads an input file, evaluates some conditions and expressions (similar to cpp but slightly different) and produces an output file with substituted values. The file to pre-process is an Ada file that will have the .gpb extension to differentiate it from regular Ada files. For our concern we will use gnatprep to substitute some variables, a String and a number. The declaration could be the following:

package Version is
   Head_URL : constant String := $URL;
   Revision : constant Positive := $REVISION;
end Version;

To produce the expanded .ads file, we will invoke gnatprep and give it the URL and REVISION variables. The manual command would look like:

$ gnatprep -DREVISION=23 -DURL="https://..." \
    src/version.gpb src/version.ads

Running such command by hand can be cumbersome. It is easy to use a Makefile with a make target that will do the full job of extracting the latest revision and invoke gnatprep. The make target is the following (make sure to have a tab as first character in the gnatprep command):

version:
        gnatprep `svn info | grep '^[UR][eR][Lv]' | sed -e 's,URL: \(.*\),-DURL="\1",' -e 's,Revision: ,-DREVISION=,'` \
                  src/version.gpb src/version.ads

This make target could be run manually or be integrated as part of the build process so that it is executed each time a release build is performed.

Writing the log

The easy part is to report the application revision number either in a log or on the standard output.

with Ada.Text_IO;
...
   Ada.Text_IO.Put_Line ("Revision " & Positive'Image (Revision));

References

Subversion Keyword Substitution

Preprocessing Using gnatprep

Showing multiprocessor issue when updating a shared counter

By Stephane Carrez 2011-01-31 22:25:31

When working on several Ada concurrent counter implementations, I was interested to point out the concurrent issue that exists in multi-processor environment. This article explains why you really have to take this issue seriously in multi-tasks applications, specially because multi-core processors are now quite common.

What's the issue

Let's say we have a simple integer shared by several tasks:

Counter : Integer;

And several tasks will use the following statement to increment the counter:

  Counter := Counter + 1;

We will see that this implementation is wrong (even if a single instruction is used).

Multi task increment sample

To show up the issue, let's define two counters. One not protected and another protected from concurrent accesses by using a specific data structure provided by the Ada Util library.

with Util.Concurrent.Counters;
..
  Unsafe  : Integer := 0;
  Counter : Util.Concurrent.Counters.Counter;

In our testing procedure, let's declare a task type that will increment both versions of our counters. Several tasks will run concurrently so that the shared counter variables will experience a lot of concurrent accesses. The task type is declared in a declare block inside our procedure so that we will benefit from task synchronisation at the end of the block (See RM 7.6, and RM 9.3).

Each task will increment both counters in a loop. We should expect the two counters to get the same value at the end. We will see this is not the case in multi-processor environments.

declare
  task type Worker is
    entry Start (Count : in Natural);
  end Worker;

  task body Worker is
    Cnt : Natural;
  begin
      accept Start (Count : in Natural) do
        Cnt := Count;
      end;
      for I in 1 .. Cnt loop
        Util.Concurrent.Counters.Increment (Counter);
        Unsafe := Unsafe + 1;
      end loop;
  end Worker;

Now, in the same declaration block, we will define an array of tasks to show up the concurrency.

   type Worker_Array is array (1 .. Task_Count) of Worker;
   Tasks : Worker_Array;

Our tasks are activated and they are waiting to get the counter. Let's make our tasks count 10 million times.

begin
  for I in Tasks'Range loop
    Tasks (I).Start (10_000_000);
  end loop;
end;

Before leaving the declare scope, Ada will wait until the tasks have finished. (yes, there is no need to write any pthread_join code). After this block, we can just print out the value stored in the two counters and compare them:

Log.Info ("Counter value at the end       : " & Integer'Image (Value (Counter)));
Log.Info ("Unprotected counter at the end : " & Integer'Image (Unsafe));

The complete source is available in the Ada Util project in multipro.adb.

The Results

With one task, everything is Ok (Indeed!):

Starting  1 tasks
Expected value at the end      :  10000000
Counter value at the end       :  10000000
Unprotected counter at the end :  10000000

With two tasks, the problem appears:

Starting  2 tasks
Expected value at the end      :  10000000
Counter value at the end       :  10000000
Unprotected counter at the end :  8033821

And it aggravates as the number of tasks increases.

Starting  16 tasks
Expected value at the end      :  10000000
Counter value at the end       :  10000000
Unprotected counter at the end :  2496811

(The above results have been produced on an Intel Core Quad; Similar problems show up on Atom processors as well)

Explanation

On x86 processors, the compiler can use an incl instruction for the unsafe counter increment. So, one instruction for our increment. You thought it was thread safe. Big mistake!

  incl %(eax)

This instruction is atomic in a mono-processor environment meaning that it cannot be interrupted. However, in a multi-processor environment, each processor has its own memory cache (L1 cache) and will read and increment the value into its own cache. Caches are synchronized but this is almost always too late. Indeed, two processors can read their L1 cache, increment the value and save it at the same time (thus, loosing one increment). This is what is happening with the unprotected counter.

Let's see how to do the protection.

Protection with specific assembly instruction

To avoid this, it is necessary to use special instructions that will force the memory location to be synchronized and locked until the instruction completes. On x86, this is achieved by the lock instruction prefix. The following is guaranteed to be atomic on multi-processors:

  lock
  incl %(eax)

The lock instruction prefix introduces a delay to the execution of the instruction it protects. This delay increases slightly when concurrency occurs but it remains acceptable (up to 10 times slower).

For Sparc, Mips and other processors, the implementation requires to loop until either a lock is get (Spinlock) or it is guaranteed that no other processor has modified the counter at the same time.

Source: Util.Concurrent.Counters.ads, Util.Concurrent.Counters.adb

Protection with an Ada protected type

A safe and portable counter implementation can be made by using Ada protected types. The protected type allows to define a protected procedure Increment which provides an exclusive read-write access to the data (RM 9.5.1). The protected function Value will offer a concurrent read-only access to the data.

package Util.Concurrent.Counters is
    type Counter is limited private;
    procedure Increment (C : in out Counter);
    function Value (C : in Counter) return Integer;
private
  protected type Cnt is
      procedure Increment;
      function Get return Integer;
   private
      N : Integer := 0;
   end Cnt;
   type Counter is limited record
      Value : Cnt;
   end record;
end Util.Concurrent.Counters;

Source: Util.Concurrent.Counters.ads, Util.Concurrent.Counters.adb

Ada Servlet Example

By Stephane Carrez 2010-11-11 22:21:38

To write a web application, Java developers can use the servlet API. The servlet technology, created around 1997, is a simple and powerful framework on top of which many web applications and higher web frameworks have been created. This article shows how to write the same kind of web application in Ada.

Ada Servlet Framework

The Ada Servlet framework is provided by Ada Server Faces. It is an adaptation and implementation of the JSR 315 (Java Servlet Specification) for the Ada 05 language. The Ada API is very close to the Java API as it provides the Servlet, Filter, Request, Responseand Session types with quite the same methods. It should be quite easy for someone who is familiar with Java servlets to write an Ada servlet.

The Ada Servlet implementation uses the Ada Web Server as a web server. In the future other other web servers such as Apache or Lighthttpd could be used.

Servlet Declaration

The servlet API is represented by the Servlet tagged type which represents the root of all servlets. A servlet must extend this Servlet tagged type and it can override one of the Do_Get, Do_Post, Do_HeadDo_Delete, Do_Put, Do_Options or Do_Trace procedure. Each Do_XXX procedure receives a request object and a response object.

with ASF.Servlets;
with ASF.Requests;
with ASF.Responses;

package Volume_Servlet is
   use ASF;
   type Servlet is new Servlets.Servlet with null record;

   --  Called by the servlet container when a GET request is received.
   procedure Do_Get (Server   : in Servlet;
                     Request  : in out Requests.Request'Class;
                     Response : in out Responses.Response'Class);
end Volume_Servlet;

Servlet Implementation

The Do_Get procedure receives the request and response as parameter. Both objects are in outparameters because the servlet implementation can modify them. Indeed, the Java servlet API allows the servlet developer to set specific attributes on the request object (This allows to associate any kind of data to the request for later use when rendering the response).

Similar to the Java API, the response is written by using the Print_Stream object that is returned by the Get_Output_Stream function.

with ASF.Streams;
package body Volume_Servlet is
   procedure Do_Get (Server   : in Servlet;
                     Request  : in out Requests.Request'Class;
                     Response : in out Responses.Response'Class) is
      Output : Streams.Print_Stream := Response.Get_Output_Stream;
   begin
      Output.Write ("...");
      Response.Set_Status (Responses.SC_OK);
   end Do_Get;
end Volume_Servlet;

Note: the complete content is omitted for the clarity of this post.

Servlet Registration

With Java servlet 2.5 specification, servlets are registered exclusively through the web.xmlapplication descriptor file. Since Java servlet 3.0, one can register servlets programmatically. With our Ada servlet, this is was we will do with the use of the Add_Servlet method.

Since the Ada runtime is not able to create dynamically an instance of any class (such as the Java newInstance method of the Java Class class), we have to create ourselves the servlet instance object and register it. The servlet instance is associated with a name.

Once registered, we have to define a mapping that tells which URL path is mapped to the servlet. This is done by the call to Add_Mapping: every URL that ends in .htmlwill be handled by the servlet.

The Ada Server Faces framework provides a Web container in which the application must be registered (similar to the Java Web container). The registration is done by the Register_Application call which also specifies the URL prefix for the web application (Every URL starting with /volume will be served by this application).

with ASF.Server.Web;
with ASF.Servlets;
with Volume_Servlet;

procedure Volume_Server is
   Compute : aliased Volume_Servlet.Servlet;
   App     : aliased ASF.Servlets.Servlet_Registry;
   WS      : ASF.Server.Web.AWS_Container;
begin
   --  Register the servlets and filters
   App.Add_Servlet (Name => "compute",
                    Server => Compute'Unchecked_Access);

   --  Define servlet mappings
   App.Add_Mapping (Name => "compute",
                    Pattern => "*.html");

   WS.Register_Application ("/volume",
                            App'Unchecked_Access);

   WS.Start;

   delay 600.0;

end Volume_Server;

Compilation and Execution

The compilation of the Ada servlet example is done using a GNAT project file.

$ gnatmake -Psamples

It produces the volume_server which is our web server.

$ bin/volume_server

After the server is started, point your browser to http://localhost:8080/volume/index.htmlto look at the result.

References

volume_servlet.ads

volume_servlet.adb

volume_server.adb

HttpServlet

HttpServletResponse

HttpServletRequest

How to fix GNAT symbolic traceback crash on Ubuntu

By Stephane Carrez 2010-09-19 17:34:00

When you use the GNAT symbolic traceback feature with gcc 4.4 on Ubuntu 10.04, a segmentation fault occurs. This article explains why and proposes a workaround until the problem is fixed in the distribution.

Symbolic Traceback

The GNU Ada Compiler provides a support package to dump the exception traceback with symbols.

with Ada.Exceptions;
  use Ada.Exceptions;
with GNAT.Traceback.Symbolic;
  use GNAT.Traceback.Symbolic;
with Ada.Text_IO; use Ada.Text_IO;
...
exception
  when E : others =>
    Put_Line ("Exception: " & Exception_Name (E));
    Put_Line (Symbolic_Traceback (E));

GNAT Symbolic Traceback crash

On Ubuntu 10.04 and probably on other Debian distributions, the symbolic traceback crashes in convert_addresses:

Program received signal SIGSEGV, Segmentation fault.
0xb7ab20a6 in convert_addresses () from /usr/lib/libgnat-4.4.so.1
(gdb) where
#0  0xb7ab20a6 in convert_addresses () from /usr/lib/libgnat-4.4.so.1
#1  0xb7ab1f2c in gnat__traceback__symbolic__symbolic_traceback () from /usr/lib/libgnat-4.4.so.1
#2  0xb7ab2054 in gnat__traceback__symbolic__symbolic_traceback__2 () from /usr/lib/libgnat-4.4.so.1

The problem is caused by a patch that was applied on GCC 4.4 sources and which introduces a bug in convert_addresses function. Basically, the function is missing a filename argument which causes other arguments to be incorrect.

void convert_addresses (const char* filename,
         void* addrs[], int n_addr,
         char* buf, int*  len)

Since convert_addresses is provided by the libgnat-4.4.so dynamic library, we can easily replace this function by linking our program with the correct implementation. Get the convert_addresses.c, compile it and add it when you link your program:

$ gcc -c convert_addresses.c
$ gnatmake -Pproject -largs convert_addresses.o