Java-Zugriffsfunktionen

Bei den Java™-Zugriffsfunktionen handelt es sich um EGL-Systemfunktionen, die verwendet werden, um über den Java-Code auf lokale Java-Objekte und -Klassen zuzugreifen. Diese Funktionen greifen insbesondere auf die öffentlichen Methoden, Konstruktoren und Felder des lokalen Codes zu. Hierbei handelt es sich um ältere Funktionen, die aus Gründen der Kompatibilität mit früheren Versionen von EGL verwaltet werden. Verwenden Sie für neuen Code die leistungsfähigere ExternalType-Syntax. Weitere Informationen finden Sie in 'ExternalType (Abschnitt)'.

Dieses EGL-Feature kann in zur Ausführungszeit durch das Vorhandensein des EGL-Java-Objektbereichs genutzt werden. Dieser Objektbereich enthält eine Gruppe von Namen und die Objekte, auf die sich diese Namen beziehen. Für Ihr generiertes Programm und den gesamten generierten Java-Code, den Ihr Programm lokal aufruft (ob direkt oder oder über ein anderes lokales generiertes Java-Programm), steht nur ein Objektbereich zur Verfügung. Dies gilt für alle Aufrufebenen. Der Objektbereich ist nicht in lokalem Java-Code verfügbar.

Um Objekte im Objektbereich zu speichern und aus diesem abzurufen, müssen Sie die Java-Zugriffsfunktionen aufrufen. Ihre Aufrufe können Kennungen enthalten, bei denen es sich jeweils um eine Zeichenfolge handelt, die verwendet wird, um ein Objekt zu speichern oder um einen Namen abzugleichen, der im Objektbereich bereits vorhanden ist. Stimmt eine Kennung mit einem Namen überein, kann Ihr Code auf das Objekt zugreifen, das diesem Namen zugeordnet ist.

Jedes Argument, das Sie an eine Methode übergeben (und jeder Wert, den Sie einem Feld zuordnen), wird einem Java-Objekt oder -Basiselementtyp (primitiven Typ) zugeordnet. Siehe hierzu 'EGL-Basiselemente zu Java zuordnen'.

EGL-Code mit einer Java-Zugriffsfunktion kann nicht als COBOL-Programm generiert werden.

Beispiele

Dieser Abschnitt enthält Beispiele zur Verwendung von Java-Zugriffsfunktionen.

Systemeigenschaft testen

Das folgende Beispiel ruft eine Systemeigenschaft ab und überprüft diese auf das Nichtvorhandensein eines Wertes:
  // Ordnet den Namen einer Kennung zu einer Variablen vom Typ CHAR zu
  valueID = "osNameProperty"

  // Stellt den Wert der Eigenschaft 'os.name' in den 
  // Objektbereich und setzt diesen Wert (Java-Zeichenfolge) 
  // in Beziehung zur Kennung 'OSNameProperty'
  javaLib.store(valueId as "objID:java", "java.lang.System",
    "getProperty", "os.name");

  // Testet, ob der Eigenschaftswert nicht vorhanden ist,
  // und führt eine entsprechende Verarbeitung durch
  myNullFlag = javaLib.isNull( valueId as "objID:java" );
  
  if( myNullFlag == 1 )
    error = 27;
  end 

Mit Feldgruppen arbeiten

Verwenden Sie beim Arbeiten mit Java-Feldgruppen in EGL die Java-Klasse java.lang.reflect.Array wie in der Java-API-Dokumentation beschrieben. Sie können nicht 'javaLib.storeNew()' verwenden, um eine Java-Feldgruppe zu erstellen, da Java-Feldgruppen keine Konstruktoren aufweisen.

Verwenden Sie die statische Methode newInstance() von java.lang.reflect.Array, um die Feldgruppe im Objektbereich zu erstellen. Verwenden Sie nach dem Erstellen der Feldgruppe weitere Methoden in dieser Klasse, um auf die Elemente zuzugreifen.

Die Methode newInstance() erwartet zwei Argumente:
  • Ein Klassenobjekt (class) zur Festlegung des Typs der zu erstellenden Feldgruppe
  • eine Zahl, die angibt, wie viele Elemente die Feldgruppe enthält

Der Code zur Identifizierung des Klassenobjekts hängt davon ab, ob eine Feldgruppe aus Objekten oder eine Feldgruppe aus Basiselementen erstellt wird. Diese Variationen werden in den folgenden Abschnitten anhand von Beispielen veranschaulicht.

Feldgruppe aus Objekten verwenden

Das folgende Beispiel zeigt, wie eine Objektfeldgruppe mit fünf Elementen erstellt wird, auf die mit der Kennung 'myArray' zugegriffen werden kann:
  // Verweis auf die Klasse für 'newInstance()' abrufen
  javaLib.store( "objectClass" as "objID:java", "java.lang.Class",
    "forName", "java.lang.Object" );

  // Erstellen der Feldgruppe im Objektbereich
  javaLib.store( "myArray" as "objID:java", "java.lang.reflect.Array",
    "newInstance", "objectClass" as "objID:java", 5 );

Um eine Feldgruppe zu erstellen, die einen anderen Objekttyp enthält, müssen Sie den Klassennamen ändern, der an den ersten Aufruf von 'javaLib.store()' übergeben wird. Um beispielsweise eine Feldgruppe aus Zeichenfolgeobjekten (Typ 'string') zu erstellen, müssen Sie java.lang.String anstelle von java.lang.Object übergeben.

Verwenden Sie für den Zugriff auf ein Element in einer Objektfeldgruppe die Methoden 'get' und 'set' von java.lang.reflect.Array. Im folgenden Beispiel sind i und length numerische Variablen:
  length = javaLib.invoke( "java.lang.reflect.Array", 
    "getLength", "myArray" as "objID:java" );
  i = 0; 

  while ( i < length ) 
    javaLib.store( "element" as "objID:java", "java.lang.reflect.Array",
      "get", "myArray" as "objID:java", i );

    // Hier erfolgt die entsprechende Verarbeitung des Elements
    javaLib.invoke( "java.lang.reflect.Array", "set", 
      "myArray" as "objID:java", i, "element" as "objID:java" ); 
    i = i + 1; 
  end  
Das vorstehende Beispiel ist äquivalent zum folgenden Java-Code:
  int length = myArray.length; 
  
  for ( int i = 0; i < length; i++ ) 
  { 
    Object element = myArray[i]; 

    // Hier erfolgt die entsprechende Verarbeitung des Elements

    myArray[i] = element; 
  }  

Feldgruppe aus Java-Basiselementen verwenden

Wenn Sie eine Feldgruppe erstellen wollen, die kein Objekt, sondern ein Java-Basiselement speichert, müssen Sie für die Schritte vor der Verwendung von java.lang.reflect.Array einen anderen Mechanismus anwenden. Insbesondere müssen Sie das Argument 'Class' für newInstance() abrufen, indem Sie auf das statische Feld TYPE einer Basiselementtypklasse zugreifen.

Mit dem folgenden Beispiel wird 'myArray2' (eine Feldgruppe aus Ganzzahlen mit 30 Elementen) erstellt:
  // Verweis auf die Klasse für 'newInstance' abrufen
  javaLib.storeField( "intClass" as "objID:java", 
    "java.lang.Integer", "TYPE");

  // Erstellen der Feldgruppe im Objektbereich
  javaLib.store( "myArray2" as "objID:java", "java.lang.reflect.Array",
    "newInstance", "intClass"  as "objID:java", 30 );  

Um eine Feldgruppe zu erstellen, die einen anderen Basiselementtyp enthält, müssen Sie den Klassennamen ändern, der an den Aufruf von 'javaLib.storeField()' übergeben wird. Um beispielsweise eine Feldgruppe aus Zeichen (Typ 'character') zu erstellen, müssen Sie java.lang.Character anstelle von java.lang.Integer übergeben.

Verwenden Sie für den Zugriff auf ein Element in einer Feldgruppe aus Basiselementen die Methoden von java.lang.reflect.Array, die für einen Basiselementtyp spezifisch sind. Zu diesen Methoden gehören getInt(), setInt(), getFloat(), setFloat() usw. Im folgenden Beispiel sind length, element und i numerische Variablen:
  length = javaLib.invoke( "java.lang.reflect.Array", 
    "getLength", "myArray2" as "objID:java" ); 
  i = 0; 

  while ( i < length )
    element = javaLib.invoke( "java.lang.reflect.Array", 
      "getDouble", "myArray2" as "objID:java", i ); 

    // Hier erfolgt die entsprechende Verarbeitung eines Elements

    javaLib.invoke( "java.lang.reflect.Array", "setDouble",
      "myArray2" as "objID:java", i, element );
    i = i + 1; 
  end
Das vorstehende Beispiel ist äquivalent zum folgenden Java-Code:
  int length = myArray2.length;

  for ( int i = 0; i < length; i++ )
  { 
    double element = myArray2[i];

    // Hier erfolgt die entsprechende Verarbeitung eines Elements

    myArray2[i] = element;
  }  

Mit Objektgruppen (Sammlungen) arbeiten

Um eine Objektgruppe (Sammlung) zu iterieren, auf die von einer Variablen namens list verwiesen wird, führt ein Java-Programm den folgenden Code aus:
  Iterator contents = list.iterator(); 

  while( contents.hasNext() ) 
  { 
    Object myObject = contents.next();
    // Verarbeitung von 'myObject'
  }
Gehen Sie davon aus, dass es sich bei hasNext um eine boolesche Variable handelt und dass Ihr Programm eine Objektgruppe mit einer Kennung namens list in Beziehung gesetzt hat. Dann wäre der folgende EGL-Code äquivalent zum vorstehenden Java-Code:
  javaLib.store( "contents" as "objID:java", 
                 "list" as "objID:java", "iterator" );
  hasNext = javaLib.invoke( "contents"  as "objID:java", "hasNext" ); 

  while ( hasNext ) 
    javaLib.store( "myObject" as "objID:java", 
                   "contents" as "objID:java", "next");

    // Verarbeitung von 'myObject'
    hasNext = javaLib.invoke( "contents" as "objID:java", "hasNext" );
  end

Feldgruppe in Objektgruppe (Sammlung) konvertieren

Um eine Objektgruppe (Sammlung) aus einer Objektfeldgruppe zu erstellen, verwenden Sie die Methode asList() von java.util.Arrays, wie im folgenden Beispiel gezeigt:
  // Objektgruppe aus der Feldgruppe 'myArray' erstellen 
  // und diese Objektgruppe mit der Kennung "list" in Beziehung setzen 
  javaLib.store( "list" as "objID:java", "java.util.Arrays",
                 "asList", "myArray" as "objID:java" );

Iterieren Sie als Nächstes die Liste, wie in vorstehendem Abschnitt gezeigt.

Die Übertragung einer Feldgruppe in eine Objektgruppe (Sammlung) funktioniert nur für eine Feldgruppe mit Objekten, nicht aber für eine Feldgruppe mit Java-Basiselementen. Achten Sie darauf, java.util.Arrays nicht mit java.lang.reflect.Array zu verwechseln.

Fehlerbehandlung

Wenn Sie die Standardfehlerbehandlung verwenden (Einstellung NO für 'v60ExceptionCompatibility') und der aufgerufene Java-Code eine Ausnahmebedingung auslöst, reagiert EGL durch das Auslösen einer Ausnahmebedingung vom Typ 'JavaObjectException'. EGL-seitige Fehler verursachen eine Laufzeitausnahmebedingung (RuntimeException). Weitere Informationen finden Sie in den Fehlerhinweisen zu den den einzelnen Funktionen.

Wenn Sie die Funktion für V6-Ausnahmebedingungskompatibilität verwenden (siehe 'v60ExceptionCompatibility'), können Sie auf die Werte in 'sysVar.errorCode' zugreifen, die von Funktionen in 'javaLib' festgelegt werden. Eine entsprechende Beschreibung finden Sie in den zugehörigen Themen zu diesen Funktionen.

Von besonderer Bedeutung ist der Wert '00001000' für sysVar.errorCode. Er gibt an, dass eine Ausnahmebedingung durch eine aufgerufene Methode oder infolge einer Klasseninitialisierung ausgelöst wurde.

Wenn eine Ausnahmebedingung ausgelöst wird, speichert EGL diese im Objektbereich. Tritt eine weitere Ausnahmebedingung ein, nimmt diese die Stelle der ersten Ausnahmebedingung ein. Mithilfe der Kennung caughtException können Sie auf die Ausnahmebedingung zugreifen, die als Letztes aufgetreten ist.

Bei einer ungewöhnlichen Situation löst eine aufgerufene Methode statt einer Ausnahmebedingung einen Fehler aus, wie beispielsweise 'OutOfMemoryError' oder 'StackOverflowError'. In diesen Fällen wird das Programm unabhängig vom Wert der Systemvariablen 'vgVar.handlesysLibraryErrors' beendet.

Der folgende Java-Code zeigt, wie ein Java-Programm mehrere Catch-Blöcke für die Bearbeitung verschiedener Arten von Ausnahmebedingungen verwenden kann. Dieser Code versucht, ein Objekt vom Typ 'FileOutputStream' zu erstellen. Ein Fehler führt dazu, dass der Code eine Variable namens 'errorType' setzt und die ausgelöste Ausnahmebedingung speichert.
  int errorType = 0;
  Exception ex = null;
  
  try
  {
    java.io.FileOutputStream fOut = 
      new java.io.FileOutputStream( "out.txt" );
  }
  catch ( java.io.IOException iox )
  {
    errorType = 1;
    ex = iox;
  }
  catch ( java.lang.SecurityException sx )
  {
    errorType = 2;
    ex = sx;
  } 
Der folgende EGL-Code ist äquivalent zum vorstehenden Java-Code:
  vgVar.handlesysLibraryErrors = 1;
  errorType = 0;
  
  javaLib.storeNew( "fOut" as "objID:java",
                    "java.io.FileOutputStream", "out.txt" );

  if ( sysVar.errorCode == "00001000" )
    case ( javaLib.qualifiedTypeName( "caughtException" as "objID:java" ) )

      when ( "java.io.IOException" )
        errorType = 1;
        javaLib.storeCopy( "caughtException" as "objID:java", 
                           "ex" as "objID:java" );
      when ( "java.lang.SecurityException" )
        errorType = 2;
        javaLib.storeCopy( "caughtException" as "objID:java",
                           "ex" as "objID:java" );
    end
  end

Feedback