=====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 {{:dba:oracle_java_vm_in_the_database_v01.png?direct|Oracle Java in der Datenbank}} 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 ---- ==== Quellen ===== Oracle: * https://docs.oracle.com/database/121/JJDEV/chone.htm#JJDEV01000 Web: * http://blogs.artinsoft.net/Mrojas/archive/2010/02/01/Get-Java-Version-for-Oracle-Stored-Procedures.aspx