2. Getting Started with GNAT-AJIS¶
This chapter summarizes GNAT-AJIS’s basic capabilities and illustrates how to use the GNAT-AJIS tools for some simple applications.
2.1. Introduction¶
GNAT-AJIS (GNAT Ada-Java Interfacing Suite) is a collection of GNAT add-on tools for developing mixed-language Ada / Java applications where the Java components run on a JVM and the Ada components are compiled natively. Through GNAT-AJIS you can realize the following scenarios:
In a Java application, invoke subprograms from natively-compiled Ada packages (i.e., either interface with an existing Ada API, or implement Java native methods in Ada);
In a natively compiled Ada program, access methods and fields from Java classes or objects.
GNAT-AJIS addresses these scenarios through an Ada binding to the JNI services and ‘binding generator’ tools that automate the generation of the necessary ‘glue code’:
ada2java
Takes an Ada package specification as input and produces one or more Java classes, with native methods corresponding to the Ada subprograms. This allows you to call Ada from Java.
2.2. GNAT-AJIS Installation Structure¶
Installing the GNAT-AJIS tools results in the following directory structure. 1
$GNATAJIS_INSTALL_DIR/
bin/
ada2java (Solaris, Linux) or ada2java.exe (Windows) -- executable
include/
ajis/
Various `.ads` and `.adb` files
gnatjni/
Various `.ads` and `.adb` files
lib/
libajis.so (Solaris, Linux) or ajis.dll (Windows)
libgnatjni.so (Solaris, Linux) or gnatjni.dll (Windows)
ajis.jar
ajis/
Various `.ali` files
gnat/
Various files
gnatjni/
Various `.ali` files
2.3. GNAT-AJIS / GNAT Compatibility¶
ada2java can be used with any GNAT compiler version 22.x or later.
The gnatjni and ajis libraries are automatically built at install time.
If you update GNAT, you need to rebuild these 2 libraries using buildajislibs.sh (or buildajislibs.cmd on windows) script located at <AJIS_INSTALL_PATH>/share/ajis/ajislibsbuilder directory.
As an alternative, you can uninstall/reinstall GNAT-AJIS.
If gnatjni and ``ajis``libraries are not built using installed GNAT, you will get
“compiled with different GNAT versions” errors when linking with them.
2.4. A Simple Example: Calling Ada from Java¶
This section illustrates how to invoke an Ada subprogram (compiled natively) from Java running on a JVM. In summary, the steps are as follows:
Make sure that the relevant environment variables are properly defined.
Write a package specification for the subprogram(s) to be called from Java, and a corresponding package body.
Invoke the GNAT-AJIS tool
ada2javaon the Ada package spec, to produce the corresponding Java classes (source files) and the necessary JNI ‘glue’ code (additional Ada source files). Providing the-L libnameswitch will cause a project file to be generated, which will help to automate some of the processing.Invoke the Java compiler
javacon the Java source files;Invoke
gprbuildon the project file generated byada2java; this will compile the Ada files into a shared library (Solaris, Linux) or dll (Windows);Invoke the Java interpreter to run a Java main class that invokes methods from the Java classes generated by
ada2java.
These steps will now be described in detail.
2.4.1. Environment Setup¶
Since you will be using both the Ada and Java toolsets, you need to
ensure that several environment variables are set.
You can automate this step by defining these variables in a
shell script / batch file.
For convenience you will also find it useful to define an environment
variable that ‘points to’ the root directory for the GNAT-AJIS
tool installation.
The description below assumes that GNATAJIS_INSTALL_DIR
has this role.
PATH
Must contain the directories for the GNAT tools and for the GNAT-AJIS tools. The latter will be in the
$GNATAJIS_INSTALL_DIR/bindirectory. On Windows, it needs to contain the directory where the shared libraries are generated, typically./libalthough you can override this.
LD_LIBRARY_PATH
On Solaris and Linux, must contain the directories where your native libraries will reside (generally the
./libsubdirectory). This variable is not needed on Windows.
CLASSPATH
Must contain
$GNATAJIS_INSTALL_DIR/lib/ajis.jar, which is the parent directory of thecom.adacore.ajisJava package.
ADA_PROJECT_PATH
Must contain
$GNATAJIS_INSTALL_DIR/lib/gnat, the directory that holds the GNAT project files needed for building applications with GNAT-AJIS.
2.4.2. An Ada Package¶
Assume that you would like to invoke an Ada procedure that displays
the text Hello from Ada, followed by an integer value passed
to Ada from Java.
Declare a procedure Hello in a package spec Hello_Pkg
(file hello_pkg.ads) and implement the body
(file hello_pkg.adb):
package Hello_Pkg is
procedure Hello (Item : in Integer);
end Hello_Pkg;
with Ada.Text_IO; use Ada.Text_IO;
package body Hello_Pkg is
procedure Hello (Item : in Integer) is
begin
Put_Line("Hello from Ada: " & Integer'Image(Item));
end Hello;
end Hello_Pkg;
2.4.3. Invoking ada2java¶
Change to the directory containing the Ada source files, and invoke the command
ada2java hello_pkg.ads -L hello_proj
This will generate a number of files and directories, including:
Hello_Pkg/
Hello_Pkg_Package.java
Ada2Java/
Library.java
hello_proj.gpr
Specs and bodies for the JNI_Binding package hierarchy
These have the following significance:
- Directory
Hello_Pkg In the absence of an option that specifies the output directory for the generated Java file,
ada2javacreates a new directory with the same name as the Ada input unit and places the Java file in this directory.- File
Hello_Pkg_Package.java ada2javagenerates a Java source file with native method(s) corresponding to the visible subprogram(s) in the Ada package. (In generalada2javamay generate several Java source files, based on the contents of the Ada package spec. In this example only one Java file is produced.) The name of this file is the same as the Ada unit, with_Packageappended (since the input file is a package, rather than a procedure or function). The casing of the file name is the same as that specified on the Ada unit declaration.Ada parameters are mapped to Java types; here Ada’s
Integercorresponds to the Java typeint.In skeletal form, here is the Java class that is generated:
package Hello_Pkg;
public final class Hello_Pkg_Package {
static public void Hello (int Item){...}
...
}
Directory Ada2Java and file Library.java
ada2javagenerates the boilerplate fileLibrary.javato automate the library load step.
- File
hello_proj.gpr This is a GNAT project file that automates building the application and loading the dynamic library.
ada2java generates also hello_proj.source_dirs.txt and
hello_proj.library_interface.txt files to allow building custom
hello_proj.gpr file when the generated file requires modifications.
- Specs and bodies for the
JNI_Bindingpackage hierarchy These files provide various ‘boilerplate’ packages as well as the package containing the ‘glue code’ procedure whose signature complies with the required JNI protocol and which invokes the
Helloprocedure supplied in the originalHello_Pkgpackage.
2.4.4. Compiling the Java class¶
Invoke the Java compiler on the generated Java class:
$ javac Hello_Pkg/Hello_Pkg_Package.java
This will generate the classfile Hello_Pkg_Package.class in
the Hello_Pkg directory.
2.4.5. Building the Application¶
Run gprbuild, using the project file generated by ada2java
at an earlier step:
$ gprbuild -p -P hello_proj.gpr
This will generate a dynamic library – libhello_proj.so (Solaris,
Linux) or hello_proj.dll – in the subdirectory ./lib of the
current directory, and will produce the necessary object files in the
./obj subdirectory. The two subdirectories will be created if
they do not already exist.
The dynamic library will be loaded automatically at run-time, by one of the generated Java classes.
2.4.6. Running the Program¶
Write a main Java class, for example a file Hello.java:
import Hello_Pkg.Hello_Pkg_Package;
public class Hello{
public static void main(String[] args){
Hello_Pkg_Package.Hello(100);
}
}
Compile this class:
$ javac Hello.java
Run the Java program:
$ java Hello
This will produce the following output:
Hello from Ada: 100
Note that the library produced earlier must be locatable when the program is executed. On Solaris and Linux the directory containing the library would be specified by LD_LIBRARY_PATH. On Windows, that directory would be specified by the PATH environment variable. However, for the purpose of this introduction, you could simply copy or move the library to the same location as the “Hello.class” file.
Footnotes
For simplicity, Unix-style notation is
used throughout this manual in depicting directories and other host system
conventions.
For Windows, please make the relevant transformations (e.g. \
for / in path names.