=====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