.. _Getting_Started_with_GNAT-AJIS:

******************************
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.

.. _Getting_Started_With_GNAT_AJIS_Introduction:

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:

1. 
  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);

1. 
  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``

  .. index:: 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.


``javastub``

  .. index:: javastub

  Takes a Java classfile and produces an Ada package spec for the native
  methods found in these files.
  This allows you to implement Java native methods in Ada.

.. _GNAT-AJIS_Installation_Structure:

GNAT-AJIS Installation Structure
================================

.. index:: Installation of GNAT-AJIS

Installing the GNAT-AJIS tools results in the following
directory structure. [#]_


::

  $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
  

.. _GNAT-AJIS_/_GNAT_Compatibility:

GNAT-AJIS / GNAT Compatibility
==============================

.. index:: Compatibility (of GNAT-AJIS and GNAT)

.. index:: ASIS

``ada2java`` is based on ASIS and requires a compatible version of the
GNAT compiler.
To check the status of your installation, run ``ada2java`` with the
``-v`` switch; this will indicate the version of the GNAT compiler that
was used to build the GNAT-AJIS suite.
Your GNAT-AJIS installation is compatible with that GNAT version:

* 
  Running ``ada2java`` requires using that specific GNAT version;

* 
  On the other hand, the generated Ada files may be compiled with that version
  or any later one.

The ``gnatjni`` and ``ajis`` libraries have been prebuilt for a specific
version of GNAT. If you need to compile them for some other version of GNAT,
you can rebuild the libraries manually:


::

  gprbuild -P ajis.gpr -XExternal_Build=false -XObject_Dir=<some-dir>
  

where <*some-dir*> is a local directory where the temporary objects will be
placed.

.. _A_Simple_Example:_Calling_Ada_from_Java:

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 ``ada2java`` on 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 libname`` switch will cause a project file to
  be generated, which will help to automate some of the processing.

* 
  Invoke the Java compiler ``javac`` on the Java source files;

* 
  Invoke ``gprbuild`` on the project file generated by ``ada2java``;
  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.

.. _Environment_Setup:

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*

  .. index:: PATH environment variable

  Must contain the directories for the GNAT tools and for the GNAT-AJIS tools.
  The latter will be in the
  ``$GNATAJIS_INSTALL_DIR/bin`` directory. On Windows, it needs to contain
  the directory where the shared libraries are generated, typically ``./lib``
  although you can override this.


*LD_LIBRARY_PATH*

  .. index::`LD_LIBRARY_PATH` environment variable

  On Solaris and Linux, must contain the directories where your native libraries
  will reside (generally the ``./lib`` subdirectory).
  This variable is not needed on Windows.


*CLASSPATH*
 
  .. index:: CLASSPATH environment variable

  Must contain ``$GNATAJIS_INSTALL_DIR/lib/ajis.jar``, which is the parent
  directory of the ``com.adacore.ajis`` Java package.


*ADA_PROJECT_PATH*

  .. index:: ADA_PROJECT_PATH environment variable

  Must contain ``$GNATAJIS_INSTALL_DIR/lib/gnat``, the directory
  that holds the GNAT project files needed for building applications
  with GNAT-AJIS.

.. _An_Ada_Package:

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;
  

.. _Invoking_ada2java:

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, ``ada2java`` creates 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``
  ``ada2java`` generates a Java source file with native method(s)
  corresponding to the visible subprogram(s) in the Ada package.
  (In general ``ada2java`` may 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 ``_Package`` appended (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 ``Integer`` corresponds
  to the Java type ``int``.

  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``
 
  .. index:: Ada2Java directory

  .. index:: Library.java file

  ``ada2java`` generates the boilerplate file ``Library.java``
  to 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.


Specs and bodies for the ``JNI_Binding`` package 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 ``Hello`` procedure supplied in the original
  ``Hello_Pkg`` package.

.. _Compiling_the_Java_class:

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.

.. _Building_the_Application:

Building the Application
------------------------

Run ``gprbuild``, using the project file generated by *ada2java*
at an earlier step:

.. index:: gprbuild usage



::

  $ 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.

.. _Getting_Started_With_GNAT_AJIS_Running_the_Program:

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.

-------------------------------------------------------------------------------

.. rubric:: 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.