Inhaltsverzeichnis
Java in der Oracle Datenbank intern einsetzen
ab 8i - getestet mit 12c / 19c
Artikel begonnen am 2016/03/10
Auch in der Oracle Datenbank lässt sich Java als Programmiersprache einsetzen.
Architektur
In der Oracle Datenbank kann ab Oracle 8i (also seit wenigstens 1999) eine eigenen VM zum ausführen von Java Programmen gestartet werden.
Warum solle Java überhaupt in der DB eingesetzt werden?
- Verwaltung von Daten und Programmcode in einer Einheit
- Performance beim Zugriff auf die Daten
- Ersatz von PL/SQL
- Erweiterung der Datenbank mit neuen Funktionalitäten
- Plattformunabhängigkeit
Java versus PL/SQL
- PL/SQL nicht 100% Objektorientiert
- PL/SQL ist aber deutlich schneller
- PL/SQL erlaubt nur bedingte Interaktion mit der Umwelt
- PL/SQL ist nicht erweiterbar
- Java ist offen
- Java ist sehr populär
Der Oracle JServer (Aurora)- die Oracle Virtuelle Maschine in der Datenbank
- Multithreading durch Sessions
- Automatische Speicherverwaltung
- Session Footprint
- Performancesteigerung mit Native Compiler
- Dynamisches Laden von Klassen
- Embedded JDBC Driver
- Embedded SQLJ Translator
- Java ORB und IIOP connectivity
- Import und export Utilities zum Laden von Java
Multithreading
- Das Threading übernimmt die Datenbank
- Verwendung von Threads im Programm möglich aber nicht empfohlen
- Dead Locks werden von der VM automatisch erkannt
- Threads werden sequentiell abgearbeitet
- Alle Thread innerhalb eines Calls werden beendet, wenn der aufrufende Thread terminiert
- Threads werden cooperative abgearbeitet!(Hängt ein Thread, kein anderer Thread wird abgearbeitet!)
Welches JDK ist installiert
Überprüfen ob überhaupt Java zur Verfügung steht:
SELECT comp_id, comp_name, version,schema FROM dba_registry WHERE UPPER(COMP_NAME) LIKE '%JAVA%'; COMP_NAME STATUS VERSION SCHEMA ---------------------------------------- -------- ------------ ------------ JServer JAVA Virtual Machine VALID 12.1.0.2.0 SYS Oracle DATABASE Java Packages VALID 12.1.0.2.0 SYS
Welche Version von Java ist installiert:
-- create a wrapper function to call the java properties CREATE OR REPLACE FUNCTION getJavaProperty(myprop IN VARCHAR2) RETURN VARCHAR2 IS LANGUAGE JAVA name 'java.lang.System.getProperty(java.lang.String) return java.lang.String'; / -- read the propertie java.version SELECT getJavaProperty('java.version') as version from dual; Version --------- 1.6.0_81
Das sieht nicht sehr aktuell für eine Oracle 12c 12.1.0.2.0 aus ….
Und tatsächlich: „Oracle Database 12c Release 1 (12.1) supports JDK 6 and JDK 7, where JDK 6 is the default JDK version. So, if you do not set the JDK version explicitly, the JDK version in effect is JDK 6.“ siehe https://docs.oracle.com/database/121/JJDEV/chone.htm#JJDEV13628 Abschnitt über „Multiple JDK Support“
Auf Java 1.7 upgraden
siehe https://docs.oracle.com/database/121/JJDEV/chone.htm#CACDGBBI um die DB auf eine höhere Version zu heben.
Zuvor in das Oracle Home aber auch den aktuellsten CPU mit Java Update patchen!
Das erste Hello World Programm
Java in der Datenbank wird immer über einen PL/SQL Wrapper aufgerufen und ausgeführt.
Bei einfachen Java Programmen können diese direkt in der Datenbank erzeugt werden.
Über SQL*Plus lässt sich Java auch direkt in der Datenbank anlegen:
sqlplus gpi/gpi --create Java Class create or replace java source named "Hello" as public class Hello { public static String world() { return "Hallo, ich bin Java aus der DB"; } } / Java created. -- Create Wrapper create or replace function helloWorld return varchar2 as language java name 'Hello.world() return java.lang.String'; / -- Call select HELLOWORLD from dual; HELLOWORLD ----- Hallo, ich bin Java aus der DB
Beispiel DNS Auflösung aus der DB mit einer Java Klasse
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "DNSName" AS import java.net.*; public class DNSName extends Object { public static String getName(String ip) { try { InetAddress addr = InetAddress.getByName(ip); System.out.println(addr.getHostName()); System.out.println(addr.getHostAddress()); return addr.getHostName(); } catch (UnknownHostException e) { System.err.println(e.toString()); return "no"; } } public static void test(){ System.out.println("Test"); } } /
Wrapper:
CREATE OR REPLACE FUNCTION getIPName(p_ip varchar2) RETURN varchar2 AS LANGUAGE java name 'DNSName.getName(java.lang.String) return java.lang.String'; /
Auf einer 12c Datenbank kann das aber nicht sofort aufgerufen werden, es müssen die entsprechenden Rechte vergeben werden.
sqlplus / AS sysdba EXEC dbms_java.grant_permission( 'GPI', 'SYS:java.net.SocketPermission', '*', 'resolve' )
Hier muss in produktiven Umgebung mit etwas mehr Mühe gearbeitet werden um nicht hier gefährliche Toren zur DB zu öffnen!
Aufruf auf einer
SELECT getIPName('193.99.144.85') AS servername FROM dual; SERVERNAME ------------ www.heise.de
Komplexere Java Klassen in die DB Laden
Über das Programm „loadjava“ können Java Klassen auch direkt in die Datenbank geladen werden.
Siehe ⇒ https://docs.oracle.com/database/121/JJDEV/chtwo.htm#JJDEV02043