.. _Using_ada2java_to_Generate_Java_Classes:

*****************************************
Using ada2java to Generate Java Classes
*****************************************

.. index:: ada2java command

The ``ada2java`` tool takes one or more Ada package specs
and produces as output a Java 'binding' to these packages, implemented
through JNI.
The binding consists of a set of Java classes, with methods that access
the Ada package's visible entities.

More specifically, ``ada2java`` generates two sets of source files
as output:

* 
  The Java classes that make up the binding, and
* 
  The necessary Ada 'glue code'
  that hides the details of how JNI is used for interfacing between
  Ada and Java.

You will need to compile the Java files to bytecodes for execution
on a JVM, and you will need to compile the Ada files to native code
in a dynamic library.

This chapter explains how to use the ``ada2java`` tool and
describes the mapping from package spec contents to Java classes.

.. _Using_the_Tool:

Using the Tool
==============

The ``ada2java`` tool is invoked with at least one input file,
and any number of switches, in any order:


::

  $ ada2java {<switch> | <input-file>} <input-file> {<switch> | <input-file>}
  

Each ``<input-file>`` must be the name of a source
file for an Ada package spec (including the extension).

The following ``<switch>`` values are allowed:



``-h``

  .. index:: -h option (for ada2java)

  Display help


``-c <JavaClassOutputDirectory>``

  .. index:: -c option (for ada2java)

  The root directory used as the destination for the output classes.
  The directory will be created if it does not already exist.
  In the absence of this switch, the current directory is used.
  See below for the relationship with the ``-b`` switch.


``-b <BaseJavaBindingPackage>``

  .. index:: -b option (for ada2java)

  The base package for the generated Java classes; this will be
  relative to the directory specified in the ``-c`` switch,
  or relative to the current directory if no ``-c`` switch was supplied.


``-o <AdaGlueOutputDirectory>``

  .. index:: -o option (for ada2java)

  The destination directory for the 'glue' packages
  (``ads`` and ``adb`` files) generated by ``ada2java``.
  The current directory will be used if this switch is not supplied.
  The generated packages will need to be compiled into a dynamic library.


``-P <ProjectFile>``

  .. index:: -P option (for ada2java)

  The project file that applies to the processing of the ``<input-file>`` s
  submitted to ``ada2java``.  This can specify compiler switches, source
  directories, etc.
  ``<ProjectFile>`` must be a 'flat' project
  (sources from 'with'ed projects are not yet supported).


``-L <LibraryName>``

  .. index:: -L option (for ada2java)

  A mechanism for automating the loading of the native Ada dynamic library
  in Java.
  This switch causes the generation of a project file ``<LibraryName>.gpr``
  in the directory specified by the ``-o`` switch (or in the current
  directory if the ``-o`` switch was not supplied).
  The resulting project file can be submitted to ``gprbuild``
  to build the dynamic library:


  ::

    $ gprbuild -p -P LibraryName.gpr
    

  which will generate a ``lib/`` subdirectory that contains the file
  ``lib<LibraryName>.so`` (Solaris, Linux) or ``<LibraryName>.dll``
  (Windows).  This library will be loaded automatically whenever one of
  the Java classes produced by ``ada2java`` is loaded; there is
  no need for the user to explicitly include an invocation of
  ``System.loadLibrary``.


``-M <MainName>``

  .. index:: -M option (for ada2java)

  A mechanism for automating the creation of an Ada main subprogram, embedding
  both the native code and a JVM. See :ref:`Compiling_as_an_Ada_Main_Subprogram`
  for more details. Implies ``-link-method=register_natives``.


``--main-class=<java main class>``

  .. index:: --main-class option (for ada2java)

  Changes the name of the java main class to use, in case the ``-M``
  switch is used.
  See :ref:`Compiling_as_an_Ada_Main_Subprogram` for more details.


``--link-mode=(export|register_natives)``

  .. index:: --link-mode option (for ada2java)

  The Java virtual machine has two ways of discovering the functions declared in
  the native environment. Either it checks the correspondence between the
  exported symbol and the Java native declaration name (``export`` mode), or the
  JNI code registers manually the symbols using the ``Register_Native``
  JNI function
  (``register_natives`` mode). Note that if the code is not in a shared library
  but compiled with a main native subprogram, then only ``register_natives`` mode
  will work.


``--library-kind=(dynamic|encapsulated)``

  .. index:: --library-kind option (for ada2java)

  Set the library generation method: normal or standalone (used by -L).
  Ada2Java can create two different kinds of library: dynamic or encapsulated.
  Dynamic is the default mode and generate a dynamic library which depends on
  GNATJNI and AJIS libraries on one hand, and the GNAT run-time on the other
  hand whereas an encapsulated library is autonomous: it contains all the
  necessary symbols from the three dependencies to be standalone.


``--bound-package-root=<root package name>``
  Set the name of the root glue Ada packages (default is JNI_Binding).


``--bound-package-suffix=<package suffix>``
  Set the suffix of the glue Ada packages (default is _JNI).


``--no-monitor[-finalize]``

``--monitor[-finalize]-(check|protect)``

  .. index:: --monitor option (for ada2java)

  .. index:: --no-monitor option (for ada2java)

  .. index:: --monitor-finalize option (for ada2java)

  .. index:: --no-monitor-finalize option (for ada2java)

  Sets the default monitor for subprograms. See :ref:`Thread_Safety`.


``--[no-]attach-(parameter|access|controlling|ada2005)``

  .. index:: --attach option (for ada2java)

  .. index:: --no-attach option (for ada2java)

  Sets the default attachment policy.
  See :ref:`Managing_Attachment_to_Java_Proxies`


``--[no-]assume-escaped``

  .. index:: --assume-escaped option (for ada2java)

  .. index:: --no-assume-escaped option (for ada2java)

  Controls whether checks for object ownership are enabled.
  See :ref:`Restrictions_on_Proxy-Owned_Objects_passed_to_Subprograms`


``--[no-]java-enum``

  .. index:: --java-enum option (for ada2java)

  .. index:: --no-java-enum option (for ada2java)

  Controls whether Java enumerations should be used to bind Ada enumerations,
  or if static integers should be used instead (Java enumerations are the default).


``--[no]unaliased-access``

  .. index:: --unaliased-access option (for ada2java)

  .. index:: --no-unaliased-access option (for ada2java)

  Controls whether ada2java is allowed to create proxies on unaliased data.
  ``--no-unaliased-access`` is default.
  See :ref:`Aliasing`

Example:


::

  $ ada2java -c mydir pack1.ads -b foo.bar
  

This results in the placement of the Java binding classes in the relative
directory ``mydir/foo/bar/``.

Note that the actual directory containing the generated Java classes will need
to be on the ``CLASSPATH`` environment variable in order to successfully
run a Java application that uses the binding.

.. _Compiling_and_Running_the_Generated_Code:

Compiling and Running the Generated Code
========================================


.. _Issues_with_the_Ada_Generated_Code:

Issues with the Ada Generated Code
----------------------------------

Two sets of Ada units need to be compiled -- the original
packages and the generated ''glue'' code.  The Ada
glue depends on the ``ajis`` project installed in the ``lib/gnat``
directory of the GNAT-AJIS installation.

It is highly recommended that you use the project generation switches
``-L`` (for a shared library) or ``-M`` (for an Ada main subprogram).
However, even if these switches handle most cases, you may
need to write your own build procedures to address more advanced usage.
In such a situation please note
that some compiler options may have an impact on the ajis library and thus
need to be taken into consideration:



``-O2 -O3``

  .. index:: -O option (for gcc)

  If you compile with a high optimization level, you should deactivate
  strict aliasing using the compiler switch ``-fno-strict-aliasing``.

  .. index:: -fno-strict-aliasing option (for gcc)


``-fstack-check``

  .. index:: -fstack-check option (for gcc)

  The stack checking mechanism is based on signals that are deactivated by the
  GNAT AJIS library, so this switch will have no effect and should not be used.


``-fPIC``

  .. index:: -fPIC option (for gcc)

  On Linux / Solaris, all the code has to be relocatable, which is specified
  through the ``-fPIC`` switch.
  If you are creating a shared library that integrates components compiled
  externally, you have to ensure that they have been compiled using the
  ``-fPIC`` switch.

.. _Compiling_as_an_Ada_Shared_Library:

Compiling as an Ada Shared Library
----------------------------------

.. index:: Shared libraries

The most common architecture of an Ada / Java program, and a Java / Native
program in general, is to compile the native code into a shared library, and
then load that shared library at run time. In this case, the main entry point
is a Java main method, written by the developer.

In order to implement this scheme, you will need to create a SAL
(Stand-Alone Library) project
containing the sources of the input packages plus the 'glue',
and use it to compile the library.

.. index:: SAL (Stand-Alone Library) project

A simple standalone library project is generated if you use the ``-L``
switch. The generated project can then be compiled with ``gprbuild``, for example:


::

  $ ada2java my_package.ads -o ada -c java -P my_project.gpr -b base -L my_lib
  $ gprbuild -p -P ada/my_lib.gpr
  

Note that the native library will then be loaded automatically by the generated
Java glue code.

.. _Compiling_as_an_Ada_Main_Subprogram:

Compiling as an Ada Main Subprogram
-----------------------------------

If compiling the native code into a shared
library is not practical, an alternative is to create an Ada main subprogram
embedding a Java Virtual Machine.

.. index:: -M option (for ada2java)

``ada2java`` provides an easy way to generate a project and an Ada main
subprogram, through the ``-M`` switch.
This switch takes the name of the
main as parameter and will generate an Ada main that will automatically create
a Java virtual machine, and then call a Java method defined as follows:


::

  package <base_package>;

  public class <main_name> {

     public static void main (String [] args) {
     }

  }
  

This class (and thus the method implementation) has to be provided by the
developer. If it is not present,
the main subprogram will fail with an error at run time.

The generated main will look into the CLASSPATH environment variable to find
the Java classes when initializing the Java virtual machine. So for
example, if that you provide the following class:


::

  package java_code;

  import java_code.Test.Test_Package;

  public class Main {

     public static void main () {
        Test_Package.Call_Something ();
     }

  }
  

using the following Ada API:


::

  package Test is
     procedure Call_Something;
  end Test;
  

with the appropriate ``test.gpr`` project referencing the ``Test`` code,
you will be able to compile and run the code as follows:


::

  $ ada2java test.ads -P test -b java_code -o ada -c java -M Main
  $ gnatmake -P ada/main.gpr
  $ CLASSPATH=`pwd`:`pwd`/java:$CLASSPATH
  $ export CLASSPATH
  $ javac java_code/Main.java
  $ ada/obj/main
  

You can explicitly specify the name of the Java main class to use, through the
``--main-class`` switch, e.g.:


::

  $ ada2java test.ads -P test -b java_code -o ada -c java \
  > -M Main --main-class=some.main.My_Main
  

In this case, the Ada main will look for a main subprogram in
``some.main.My_Main``, instead of ``java_code.Main``.

Note that you may need to define the ``LPATH``, ``LD_LIBRARY_PATH`` or
``PATH`` environment variables so that the code can be compiled against
``jvm.lib`` or ``libjvm.a``, and then run with ``jvm.dll`` or
``libjvm.so``.

.. _Compiling_the_Java_Generated_Classes:

Compiling the Java Generated Classes
------------------------------------

The Java application needs to load the library before any of the
Ada subprograms are invoked.
If you did not supply the ``-L`` switch to ``ada2java``,
then you will need to do this explicitly; conventional style is to
invoke ``System.loadLibrary ("<library-name>")``
in a static initializer in the main Java class.
This step is automated if you use the ``-L`` switch, as described above.

Before running the Java code, you need to ensure that the
``CLASSPATH`` environment variable contains both the directory
of the generated Java code, and the JAR for the GNAT-AJIS-related
predefined classes.  The latter archive exists as
``$GNATAJIS_INSTALL_DIR/lib/ajis.jar`` where
``GNATAJIS_INSTALL_DIR`` is the root directory for the GNAT-AJIS
installation.

.. _Debugging_an_Ada_/_Java_Application:

Debugging an Ada / Java Application
===================================

The Ada code embedded in a Java application can be debugged through the standard
GDB debugger. In order to do so, the following steps needs to be followed:


* 
  Start the Java Virtual Machine on the Java application containing the Ada code to debug.

* 
  Get the PID of the Java Virtual Machine. On Linux system, this is given by the ps command, on Windows, through the Task Manager.

* 
  Start GDB giving the Java Virtual Machine as argument.

* 
  Attach to the Java Virtual Machine, e.g.:


  ::

    $> attach <pid>
    

* 
  You can then run a regular GDB session. For example, the following will set the GDB environment in Ada mode, break on all Ada exception, and then continue the application:


  ::

    $> set lang ada
    $> break exceptions
    $> continue
    

.. _Pragma_Annotate_and_ada2java:

Pragma Annotate and ada2java
============================

.. index:: pragma Annotate

Pragma ``Annotate`` (see `GNAT Reference Manual`)
has several uses in conjunction with the GNAT-AJIS tools,
each with the form:


::

  pragma Annotate (AJIS, *AJIS_annotation_identifier* {, *argument*});
  

.. index:: AJIS.Annotations package

GNAT-AJIS annotation names are defined in the package ``AJIS.Annotations``,
which is a part of the ``ajis.gpr`` project installed with GNAT-AJIS. You
need to have visibility on this package using a ``with`` and possibly a
``use`` clause before being able to use these pragmas.

The following GNAT-AJIS annotation pragmas are supported:


* ``Annotation_Renaming`` -- :ref:`Dealing_with_Name_Clashes`

* ``Assume_Escaped`` --
  :ref:`Restrictions_on_Proxy-Owned_Objects_passed_to_Subprograms`

* ``Attached`` -- :ref:`Managing_Attachment_to_Java_Proxies`

* ``Bind`` :ref:`Removing_function_procedure_from_binding_layer`

* ``Monitor`` -- :ref:`Thread_Safety`

* ``Rename`` -- :ref:`Dealing_with_Name_Clashes`

* ``Resolve_Ambiguous_Expression``
  -- :ref:`Dealing_with_ambiguous_operand_in_conversion`
  


