Domino 9 und frühere Versionen > ND9: Entwicklung

Lotus Script execute mit Java

<< < (2/2)

Sven Hasselbach:
Nur als Hinweis: Es gibt neben den Standard-Java Libraries auch Tools wie z.B. den Runtime Compiler von OpenHTF https://github.com/OpenHFT/Java-Runtime-Compiler.

In SSJS ist die Nutzung von Java-Code von Haus aus vorgesehen. SSJS sind Strings, die von der JVM zur Laufzeit interpretiert werden, dass muss man also nicht nochmal neu erfinden. Der Vorteil von SSJS ist, dass Du sämtliche Classloader-Problematiken umgehst, und sofort Zugriff auf die Domino-Umgebung/NSF-Klassen hast, da quietscht es sonst manchmal ganz gewaltig. Auch wenn es um "dynamische Parameter" geht, ist Javascript aufgrund seiner - nennen wir es in diesem Fall "Flexibilität" - von Vorteil.

So kannst Du Dir also eine SSJS - Funktion aufbauen, die direkt auf deinen Java-Code zugreift. Um Java-Klassen wie z.B. Apache-POI aufzurufen, kannst Du diese ja direkt einbinden.

Mit dieser anonymen SSJS-Funktion würde der Name und die aus Java stammende Nano-Time direkt zurück gegeben:

--- Code: ---function(name : string){ 
   return "Hello " + name + "! - " +java.lang.System.nanoTime() ;
}

--- Ende Code ---

Ich baue mir immer simple Java-Klassen als Wrapper, die letztlich nur die Parameter aufnehmen, und der "echte" Code wird dann in Java ausgeführt. Keine Lust, alles von Java nach SSJS zu portieren, ist aber natürlich machbar.

In Javascript kann ich eine Funktion zur Laufzeit in einer Variable "parken" (so funktionieren die ganzen Callbacks). Wie ich diese befülle (also auch zur Laufzeit geladener Code aus einem Notes-Dokument) ist meine Entscheidung (=> http://hasselba.ch/blog/?p=832).

Das vorige Beispiel des Evals kann man auch wie folgt abändern:

--- Code: ---var myCode = eval(code);
--- Ende Code ---

Wenn du dir den Datentyp von myCode anschaust, wirst du feststellen, dass es vom Typ JSFunction (oder so ähnlich) ist.

In Javascript ist es dann möglich, die Variable mit zwei Klammern auszuführen:

--- Code: ---varCode();
--- Ende Code ---

Und per Definition kann ich auch beliebig viele Parameter übergeben, da gibt es keine Begrenzungen. Wenn ich also sowas aufrufe, führt es nicht zu Problemen während der Laufzeit (keine Defintion der Parameter notwendig; man kann die weglassen oder einfach welche ergänzen):

--- Code: ---varCode(1,2,3,4,5,6);
--- Ende Code ---

Sven Hasselbach:
Um das noch ein wenig zu konkretisieren:

In deinem REST-Service hast du SSJS Code, der den eigentlichen auszuführenden Code aus einem Konfigurations-Dokument o.ä. lädt, mit eval() in eine Funktion umwandelt und diese dann mit den notwendigen Parametern ausführt. Also grob so etwas:


--- Code: ---<?xml version="1.0" encoding="UTF-8"?>
<xp:view
xmlns:xp="http://www.ibm.com/xsp/core"
xmlns:xe="http://www.ibm.com/xsp/coreex">

<xe:restService pathInfo="/foo">

<xe:this.service>
<xe:customRestService>
<xe:this.doGet><![CDATA[#{javascript:
function ladeCode(codeId:string) : string {

// hier wird der Code geladen
return geladenerCode;

}

var code = ladeCode( 'CodeID' );
var func = eval( '(' + code + ')' );


return func( 'bar' )
}]]></xe:this.doGet>
</xe:customRestService>
</xe:this.service>
</xe:restService>

</xp:view>


--- Ende Code ---

In dem Code-Dokument ist dann einfach eine anonyme(!) Funktion hinterlegt, z.B. so etwas:

--- Code: ---    function(foo:string){
        return foo;
    }

--- Ende Code ---

In dieser anonymen Funktion kannst Du dann deine Java-Klassen aufrufen:

--- Code: ---    function(excelSheetName: string, docId: string){
        return com.example.ExcelGenerator( excelSheetName, docId ) ;
    }

--- Ende Code ---

HH:
Hallo Sven,

danke für die ausführlichen Antworten! Werde mal versuchen, das in den nächsten Tagen umzusetzen.

Gruß
Hubert

Navigation

[0] Themen-Index

[*] Vorherige Sete

Zur normalen Ansicht wechseln