28. Januar 2008

Java in der Datenbank

English title: Java in the database ...

In der Vergangenheit habe ich ja bereits einige Posts dem Thema Java in der Datenbank gewidmet. Nun, es ist weigehend bekannt, dass die Oracle-Datenbank seit Oracle8i ("i" für "Internet") mit einer Java-Engine ausgestattet ist ... Diese Java-Engine ...
  • ... ist wie PL/SQL Bestandteil der Datenbank und wird nicht als separater Betriebssystem-Prozeß gestartet
  • ... kann nicht durch den Nutzer ausgetauscht werden
  • ... führt bis Oracle10g den Java-Code grundsätzlich interpretiert aus.
    • Man kann den Code mit dem ncomp-Werkzeug native kompilieren - dazu ist ein separater C-Compiler nötig und die so erstellten shared objects bzw. DLL's liegen dann im Dateisystem
    • Auch die Java-Systemklassen werden interpretiert ausgeführt, es sei denn, man spielt die nativ vorkompilierte Variante ein (in Oracle10g auf der Companion CD). Für Java in Oracle10g ist es daher ein MUSS, die Companion CD einzuspielen.
  • ... ab Oracle11g ist ein Just-In-Time-Compiler (JIT) dabei. Java-Klassen werden also von der Datenbank automatisch nativ kompiliert - mit dem Paket DBMS_JAVA kann man das allerdings auch manuell initiieren. Das gilt auch für die Systemklassen.
Manchmal fragt man sich allerdings, welche Java-Version eigentlich in der Datenbank vorhanden ist. Nun, da die Java-Engine ja nicht ausgetauscht werden kann, lässt sich diese Frage leicht beantworten:
  • Oracle 8.1.5: Java 1.1
  • Oracle 8.1.7: Java 1.2
  • Oracle 9.2: Java 1.3
  • Oracle 10.1: Java 1.4.1
  • Oracle 10.2: Java 1.4.2
  • Oracle 11.1: Java 1.5
Es ist auch recht einfach, es selbst herauszufinden (dieses Beispiel lief in einer Oracle Datenbank 11.1.0.6):
create or replace function get_java_version(p_name in varchar2) return varchar2
is language java name 'java.lang.System.getProperty(java.lang.String) return java.lang.String';
/
sho err

select get_java_version('java.version') from dual
/

GET_JAVA_VERSION('JAVA.VERSION')
--------------------------------------------------------------------------------
1.5.0_10
In the past I published some more posts about using the JVM inside the oracle database. Most people know that Oracle contains this JVM since Oracle8i ("i" for "internet") ... This server-side JVM ...
  • ... is part of the database (like PL/SQL) and does not run as a separate operating system process
  • ... cannot be exchanged or solely upgraded by the user
  • ... executes java code until Oracle10g (inclusive) basically in interpreted mode
    • Using the ncomp-Utility one can compile the code natively - a C compiler is required for that and the resulting shared objects / DLL's then reside in the file system dann
    • This is also true for the provided Java system classes. But these are provided in native compiled form by Oracle. In Oracle10g these native classes are contained in the Companion CD, so if you are going to execute Java in an Oracle10g database ... installing the Companion CD is a MUST.
  • ... beginning with Oracle11g the JVM has a Just-In-Time-Compiler (JIT). So the java classes are native-compiled automatically by the database (using the DBMS_JAVA package) one can also compile them manually. A separate C compiler is no longer required. This applies also to the system classes
Some times I get questions which java version runs in a particalar database. Since the JVM cannot be changed or upgraded solely this question is easy to answer:
  • Oracle 8.1.5: Java 1.1
  • Oracle 8.1.7: Java 1.2
  • Oracle 9.2: Java 1.3
  • Oracle 10.1: Java 1.4.1
  • Oracle 10.2: Java 1.4.2
  • Oracle 11.1: Java 1.5
It's also very easy to determine (this example ran in an Oracle database 11.1.0.6) ...
create or replace function get_java_version(p_name in varchar2) return varchar2
is language java name 'java.lang.System.getProperty(java.lang.String) return java.lang.String';
/
sho err

select get_java_version('java.version') from dual
/

GET_JAVA_VERSION('JAVA.VERSION')
--------------------------------------------------------------------------------
1.5.0_10
Es gibt noch ein paar Besonderheiten ...
  • Threading ist ausgeschaltet: Java-Programme, die Threading verwenden, laufen zwar, allerdings serialisiert die Datenbank alle Threads. Möchte man Java-Code in der Datenbank parallelisierem, muss man wie mit PL/SQL mit dem Paket DBMS_JOB bzw. DBMS_SCHEDULER arbeiten.
  • Die Klassen des AWT für grafische Features können ab Oracle10g ("headless" AWT) genutzt werden; natürlich kann die Datenbank keine Fenster öffnen.
  • Datenbankaktionen (SQL, DML, DDL) erfolgen wie in allen Java-Programmen per JDBC. Es gibt einen speziellen Connection-String für den server-side internal driver ("jdbc:default:connection:"), mit dem die Java-Klasse in "ihre eigene" Session verbunden wird. Username und Passwort werden nicht benötigt. Alle JDBC-Operationen sind Teil des Transaktions-Kontext dieser Session.
There some special characteristics ...
  • Threading is deactivated: Java classes using threading will run, but the database will serialize the execution of threads so that there is no parallelism. To really parallelize the execution of java code in the database you have to use DBMS_JOB or DBMS_SCHEDULER (like PL/SQL).
  • The GUI classes (AWT) are usable within Oracle10g and higher ("headless" AWT), but the database cannot open windows (of course).
  • Database actions (SQL, DML, DDL) are done via JDBC calls as in every java program. There is a special connection string for the server-side internal driver ("jdbc:default:connection:"), which connects the java class to the database session it is running in. Username and password are not required. All JDBC calls are executed in this session's transaction context.
Und das wichtigste zum Schluß: Mit den Call Specifications können PL/SQL-Wrapper für Methoden in Java-Klassen geschrieben werden. Damit sieht Java-Funktionalität nach außen hin aus wie eine PL/SQL-Prozedur, eine -Funktion oder ein Package ... und kann entsprechend von SQL oder PL/SQL aus genutzt werden. Damit kann (und die vergangenen Posts beschäftigen sich genau damit) Java sehr gut für Dinge verwendet werden, die PL/SQL nicht kann (bspw. bessere Interaktion mit dem Dateisystem). Übrigens: Obiger Code zum Feststellen der Java-Version ist eine eben solche "Call Specification".
And finally the the best thing: Using the Call Specifications one can create "PL/SQL-Wrappers" for java methods in the database. The java functionality then looks like a PL/SQL procedure, a function or a package. And it can be used like that within other PL/SQL code or within SQL queries or DML commands. So java in the database can complement PL/SQL very nicely when using it for requiremts PL/SQL cannot suffice (e.g. better filesystem interaction). BTW: The above code to determine the java version is such a "call specification".

Keine Kommentare:

Beliebte Postings