Interactive
Software Engineering
Eiffel to Java Interface

[ISE Home] Home ] Release Notes ] Technology Papers ] Installation Notes ] About Eiffel ]


Introduction

The Java interface allows you to call Java routines or attributes from your Eiffel code. It uses the Java Native Interface (JNI) provided by the Java Development Kit (JDK) 1.1.4. You can get more information about the JNI at:

http://java.sun.com/products/jdk/1.1/docs/guide/jni/index.html

Requirements

Limitations

  • In this version, you can only use one JNI environment.
  • Only one thread can interact with the Java Virtual Machine (JVM).
  • It is not possible to call Eiffel features from Java program.
  • The Eiffel side cannot deal with 'long' integer (64 bits)
  • The Eifffel feature `destroy_vm' of `JAVA_VM' calls a C function of the Java Native Interface that is not fully implemented in jdk 1.1.4. This function, called DestroyJavaVM, always returns -1 in jdk 1.1.4. For further information, go on the JNI pages at the address above. 

 

Interface classes

JNI_ENVIRONMENT

Holds information about JNI environment. Potentially many JNI environments can exists at once, but more than one was never tested. This class provide the facilities to interact with the JVM:

  • creation of instances of Java Classes
  • exceptions mechanism
  • destruction of the JVM

SHARED_JNI_ENVIRONMENT

Shared JNI environment. Since one JNI is needed per thread we limit  Eiffel to having one thread that deals with Java. The class that calls Java routines or attributes must inherit from this class. 

JAVA_VM

This class is used to initially load the JVM into the running program. This is the Eiffel representation of the JVM.

JAVA_CLASS

Access to Java classes. Static methods and attributes are accessed via this class.This is the Eiffel representation of a Java Class.

JAVA_OBJECT

This class gives Eiffel access to Java objects. You can use it directly or inherit from to and create a more convienient Eiffel class that makes the Java object look like an Eiffel object. The Eiffel representation of a Java Object. 

Warning: to access the static fields or routines of a Java Class, you have to use the features of a JAVA_CLASS instance!!

JAVA_EXTERNALS

JNI external declarations. Don't use this class directly.

JAVA_***_ARRAY

Access to Java array of "***". "***" can be all the usual types of Java (byte, short, int, float, double, char, boolean) or object if it is an array of Java Object (a String is considered as an object)

JAVA_ARGS

Class representing the arguments that can be passed to a Java method. See below about the signature of the methods

JAVA_OBJECT_TABLE

This class provides a mapping between Java and Eiffel objects

Mapping the Eiffel classes and the Java types:

The following table describes the mapping of Java primitive types and classes to Eiffel classes. 

Java type/class Eiffel class
boolean BOOLEAN
char, byte CHARACTER
short, int, long INTEGER
float REAL
double DOUBLE
String STRING
void Void

The interface does the mapping automatically. For example, if you call a Java method that returns a 'float', by using float_method you will get a 'REAL'.

 

The signature of Java methods and attributes:

When you want to call a Java method or access a field, you need to specify its signature. The Eiffel to Java interface follows the JNI specifications. The table below summarizes the encoding for the Java type signatures: 

Signature Java Type
Z boolean
B byte
C char
S short
I int
J long
F float
D double
V void
[type type []

The signature for a Java class has the following form:

L fully-qualified-class ;

For example, class String: Ljava/lang/String;

 

The signature for a method has the following form:

( arguments-types ) returned-types

For example, the signature of a method that takes as arguments an integer and a string and return void is:

(ILjava/lang/String;)V

 

An example

			## the Java Class ##
class test {
	test () {}
	public int my_integer;
	public static in my_static_integer;
	public void my_method (int arg_int, String arg_string) {
		...
	}
	...
}

			## the Eiffel Side ##
class 
	EIFFEL_TO_JAVA
		
inherit
	SHARED_JNI_ENVIRONMENT

creation
	make

feature -- Creation

	make is
		local
			class_test: JAVA_CLASS
			instance_of_class_test: JAVA_OBJECT
			fid: POINTER
			value: INTEGER
			j_args: JAVA_ARGS
		do
			--| Creation of the Java object

			class_test := jni.find_class ("test")
			create instance_of_class_test.create_instance (class_test, "()V", Void)
				
			--| Access to a public attribute

			fid := instance_of_class_test.field_id ("my_integer", "I")
				-- 'fid' contains the id of the field 'my_integer'

			value := instance_of_class_test.integer_attribute (fid)
				-- 'value' contains the value of the field referenced
				-- by 'fid'
			...

			--| Access to a static attribute using directly the JAVA_CLASS

			fid := class_test.field_id ("my_static_integer", "I")
			value := class_test.integer_attribute (fid)
			...

			--| Access to a static attribute using the attribute 'jclass'

			fid := instance_of_class_test.jclass.field_id ("my_static_integer", "I")
			value := instance_of_class_test.jclass.integer_attribute (fid)
			...

			--| Access to the method 'my_method'
			fid := instance_of_class_test.method_id ("my_method", "(ILjava/lang/String;)V")
				-- Get the id of 'my_method'

			create j_args.make(2)
			j_args.push_int (2)
			j_args.push_string("String test")
				-- Create the set of arguments for 'my_method'

			instance_of_class_test.void_method (fid, j_args)
				-- Call to the void method referenced by 'fid'
			...
			
		end -- make

end -- class EIFFEL_TO_JAVA