Getting Control of the Oracle Java Virtual Machine

Tuesday Apr 29th 2003 by Marin Komadina
Share:

Being the master of your database means gaining control of Oracle's Java Virtual Machine. Follow along with Marin Komadina as he explains installation tricks and offers some practical JVM tips.

From time to time, DBAs have to take over "alien" databases. These databases are usually living parts from some failed project, a badly documented job from a previous DBA or in a worst case scenario, a database with very important data without any support. The situation gets worse when the database has the Java Option installed. In this article, I'll explain about the Oracle database Java Option and offer some practical tips regarding Java Virtual Machine (JVM).

This article covers:

  • Java Components
  • Java Virtual Machine Parameters
  • Detecting Java Status
  • JVM Operational Test
  • Procedure for Cleaning Up JVM
  • Database JVM Upgrade Considerations
  • Java Backup
  • Conclusion

Java Components

The database Java Optionconsists ofaJava Virtual Machine (JVM) with a native compiler, a CORBA 2.0 ORB, an EJB server, an embedded server side JDBC driver, and a SQLJ translator.

The main Java module, JVM, is completely integrated with the SQL and PL/SQL database engines and 100% compliant with Sun's JVM specification. The JVM provides an enhanced support engine for Java programs and SQLJ written stored procedures, functions and triggers.

Because it runs under the database kernel, the JVM provides great stability for all running Java applications.

Java applications can be client or server side compiled. Client based code is Java code developed on the client, compiled, loaded and published in the database. Server based code is Java source loaded directly into the database and automatically compiled using SQLJ and the byte code compilers.

The Oracle database installation script, initjvm.sql, loads the initial set of necessary Java classes, initialises the Java and CORBA namespace supporting tables, publishes top-level entry points through call-specifications, modifies security settings for some loaded classes to run with definer's rights and installs new database start-up and shutdown triggers.

All Java classes are loaded in the SYS schema and all have public synonyms created for use by other database users.

Support Java classes for the following components will be loaded by the Java load procedure:

  • Aurora (Code name for initialised JavaVM)
  • The standard Java runtime
  • Bytecode verifier and optimiser
  • Java and SQLJ compilers
  • JDBC runtime
  • CORBA ORB and EJB runtime

All class files are stored in the location: $ORACLE_HOME/javavm/admin/classes.bin and source code for these classes are located in the directory $ORACLE_HOME/javavm/lib.

For example on version 8.1.7 initjvm.sql creates the following objects:

  • 3 functions
  • 4 indexes
  • 6438 java classes
  • 290 java data
  • 57 java resources
  • 6 packages
  • 1 sequence
  • 6443 synonyms
  • 8 tables
  • 2 triggers
  • 3 views

Java Virtual Machine Parameters

There are four parameters, which directly control the JVM:

Shared_pool_size is thememory used by the class loader during the loading and resolving Java classes (jars). Shared Pool memory requirements for class load are 8KB per class.

The Java load procedure (initjvm.sql) loads quite large number of the classes so recommended settings for shared_pool_size is around 50MB.

Java_pool_size parameter is theamount of memory allocated by the JVM memory manager for all session-specific Java code and data. Memory is not allocated at once, but in chunks during runtime. For dedicated database connections, Java pool is used for a shared part of each Java class. In addition, for MTS database connections, Java pool is used for some per session UGA memory (static session variables).

Java_soft_sessionspace_limitparameterdefines the Java memory soft limit for the session, allocated at session startup. The default value is 1MB. When the session exceeds this size, a trace file is generated.

Java_max_sessionspace_size parameter defines the Java memory hard limit for the session. When the session exceeds this value, the session will be closed with an error "ORA-29554 Unhanded Java out of memory condition".

Java_max_sessionspace_limit is a hidden parameter with a value ranging from 0 to 4Gb; the default value is 4GB. Version 8.X had a bug in which any attempt to start-up the database with more than 2GB for Java_max_session_space would fail.

When the Java option is not used, java_pool_size can be resized to the minimal value (1MB on version 8.1.5 and 32Kb on versions 8.1.6 and 8.1.7).

The Oracle database version 9.01 needs a larger java_pool_size because some database level triggers use the java pool for execution after every CREATE or ALTER database command.

Minimal and recommended JVM related database memory parameters:

  shared_pool_size >= 60Mb       ->   recommended 65 MB
  java_pool_size>= 30Mb             ->   recommended 50 MB 
  java_soft_sessionspace_limit=0  ->   meaning default 1 MB is used,  
  java_max_sessionspace_size=0  ->   meaning default of 4GB is used


Detecting Java Status



To determine Java status for the database we can query v$option dynamic view:

SQL > Select * from v$option; 
PARAMETER                                                       VALUE
-------------------------------------------------------------- ------
Partitioning					TRUE
Objects						TRUE
Parallel Server					FALSE
Advanced replication					TRUE
Bit-mapped indexes					TRUE
Connection multiplexing				TRUE
Connection pooling					TRUE
Database queuing					TRUE
Incremental backup and recovery				TRUE
Instead-of triggers					TRUE
Parallel backup and recovery				TRUE
Parallel execution					TRUE
Parallel load					TRUE
Point-in-time tablespace recovery			TRUE
Fine-grained access control				TRUE
N-Tier authentication/authorization			TRUE
Function-based indexes				TRUE
Plan Stability					TRUE
Online Index Build					TRUE
Coalesce Index					TRUE
Managed Standby					TRUE
Materialized view rewrite				TRUE
Materialized view warehouse refresh			TRUE
Database resource manager                          		TRUE
Spatial                                                         TRUE
Visual Information Retrieval                                	TRUE
Export transportable tablespaces                         	TRUE
Transparent Application Failover                          	TRUE
Fast-Start Fault Recovery                                   	TRUE
Sample Scan                                                     TRUE
Duplexed backups                                              	TRUE
Java						FALSE
OLAP Window Functions					TRUE 

Information from the view (Java=False) for the database version 8.1.5 - 8.1.7 inaccurately reports a situation with the JVM, that Java VM is not installed. This is not necessarily accurate.

To find out the real Java status we will make two select statements:

a.) count java objects

SQL> SELECT count(*) FROM dba_objects  WHERE object_type LIKE '%JAVA%';

  COUNT(*)
----------
     10401

We have 10401 Java objects, indicating that Java has been installed. If the JVM had not been installed the count for the Java objects would be 0:

SQL> SELECT count(*) FROM dba_objects  WHERE object_type LIKE '%JAVA%';

  COUNT(*)
----------
         0

The total number of Java objects is platform dependent.

An overview of the expected count for Java objects for different Oracle versions follows:

  • Version 8.1.5 - 4000 Java objects
  • Version 8.1.6 - 8000 Java objects
  • Version 8.1.7 - 10,300 Java objects
  • Version 9.2 - 10,452 Java objects

When the Java object count is less than given version/count, Java is only partially installed. For example, a full Java installation on 9.2 will give us following list, broken down by owner:

SQL> select count(*), owner from all_objects where object_type like '%JAVA%' group by owner; 
 
  COUNT(*) OWNER 
---------- ------------------------------ 
       247 ODM             -> Data Mining 
         1 ORDPLUGINS  -> Intermedia  
       903 ORDSYS        -> Intermedia 
      9261 SYS              -> Java Basic 
        40 WKSYS           -> Ultrasearch 

b.) Check for description of all database DBMS_JAVA PL/SQL procedures and functions

SQL>  Describe DBMS_JAVA
PROCEDURE AURORA_SHUTDOWN
PROCEDURE DELETE_EP
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 HOST                           VARCHAR2                IN
 PORT                           NUMBER                  IN
 PRESENTATION                   VARCHAR2                IN
PROCEDURE DELETE_PERMISSION
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 KEY                            NUMBER                  IN
PROCEDURE DEPLOY_CLOSE
. . . 

If the Java option is not installed, an attempt to describe DBMS_JAVA PL/SQL procedures and functions will return the following error:

SQL> Describe DBMS_JAVA
ERROR:
ORA-04043: object DBMS_JAVA does not exist

JVM Operational Test

The DBA should check the JVM core functionality before developers and end users begin work. For a test we are going to create a Java class, compile it, load it in the database and execute it as a part of PL/SQL block.

Creating Java class:

# vi dbatest.java
public class EchoInput { 
public static void main (String[] args){ 
 for (int i=0; i<args.length;i++) 
 System.out.println(args[i]);}}    

Compile Java class file:

# javac dbatest.java
# ls 
-rw-r--r--   1 oracle   tivdba       132 Apr  2 15:54 dbatest.java
-rw-r--r--   1 oracle   tivdba       429 Apr  2 15:54 dbatest.class

Load Java class dbatest.class in the database:

#  loadjava -u artist/artist -v -r dbatest.class
initialization complete
loading  : dbatest
creating : dbatest
resolver :  
resolving: dbatest

The class is saved in user schema "Artist" and will be wrapped in the PL/SQL. In that way, we are providing a call for the Java stored procedure from the PL/SQL package:



SQL> create or replace procedure dba_test ( s1 varchar2, s2 varchar2 ) as language java name 
'dbatest.main(java.lang.String[])'; 
Procedure created.

As a final step, call to procedure:

SQL> set serveroutput on
SQL> call dbms_java.set_output(5000);
Call completed.
SQL> call dba_test('DBA', 'Test');
DBA
Test
Call completed.

The basic JVM functionality is successfully checked and database is ready to use.

Procedure for Cleaning Up JVM

The JVM installation and un-installation scripts are copied automatically by Oracle during the installation procedure. To remove JVM from database versions 8.1.5 and 8.1.6 we need simply to run the rmjvm.sql deinstallation script.

For database version 8.1.7 this is not enough; we need to execute several steps before removing the JVM:

/$ORACLE_HOME/rdbms/admin/rmrepapi.sql 
/$ORACLE_HOME/oracore/admin/rmxml.sql 
drop trigger JIS$ROLE_TRIGGER$; 
delete from duc$ where owner='SYS' and pack='JIS$INTERCEPTOR$' 
and proc='USER_DROPPED'; 
delete from aurora$startup$classes$ 
where classname='oracle.aurora.mts.http.admin.RegisterService'; 
delete from aurora$dyn$reg; 
/$ORACLE_HOME/javavm/install/rmjvm.sql 

The procedure provided by Oracle, for removing JVM and other Java components has many errors and omissions.

In some versions, the removal scripts are buggy, and in others, the Oracle upgrade and removal documentation does not clarify all of the steps for all possible situations.

Subsequent attempts to re-install will not finish cleanly but rather have multiple failures. If the JVM becomes corrupt, half installed or inconsistent, it should be corrected with the "create or replace java system" command.

create or replace java system; 
* 
ERROR at line 1: 
ORA-03113: end-of-file on communication channel 

If the Java reload process (create or replace java system) doesn`t finish regularly, Oracle recommends several steps for manual Java removal:

  1. restart the database
  2. start a different session that the one the started the database
  3. run initjvmaux.sql
  4. run rmjvm.sql
  5. drop trigger JIS$ROLE_TRIGGER$;
  6. delete from ducs$ where owner='SYS' and pack='JIS$INTERCEPTOR$' and proc='USER_DROPPED';
  7. delete from aurora$startup$classes$ where classname='oracle.aurora.mts.http.admin.RegisterService';
  8. delete from aurora$dyn$reg;
  9. restart the database

To show once more how "buggy" Oracle JVM scripts are, here is a log from the regular JVM upgrade:

ORA-29515: exit called from Java code with status 0

Oracle says: "You need not worry about this message as actually it is not an error.

ORA-29515 is the way in which the javavm reports that the java exit method has been called. In this case, exit is being called intentionally to clear java session state.

You can ignore these harmless errors in 817/8171. This misleading message code is removed in 9i. "

Some more limitations regarding the Java option:

  • initjvm.sql should not be run from the same sqlplus session that started the instance (related to Bug:1335603).
  • for reinstall of all java-related components after executing initjvm.sql script and prior other scripts we should ( drop table JAVA$CLASS$MD5$TABLE; )
  • you can expect to find a few classes that will not compile or classes that are not found (missing); the jar file that the class belongs to needs to be reloaded in the following way (call dbms_java.loadjava ('-force -synonym -grant PUBLIC jis/lib/full_orb.jar jis/lib/servlet.jar)

Some of symptoms you can expect if the Java option is not complete:

a.      ) Shutdown immediate hanging hours

b.      ) Create or replace java system, never finished

c.      ) Java object count get total 6124 java objects

d.      ) Export could not export synonyms

. about to export DBSNMP's tables via Conventional Path ...

. exporting referential integrity constraints

. exporting synonyms

EXP-00008: ORACLE error 904 encountered

ORA-00904: invalid column name

EXP-00000: Export terminated unsuccessfully



An overview of published Oracle patches for Java/VM:




Patch Description Release
1761024 UTL_SMTP PACKAGE GIVES ORA-20001: 421 SERVICE NOT AVAILABLE 8.1.7.1
1753705 ORA-600 [7005] [0] EXECUTING PROCEDURE AGAINST CLOB TABLES 8.1.7.1
1395883 LRGJ1 TKJVSJ51 (THREADS) IS HANGING ON HPUX 8.1.7.1
2066561 ORA-00600 [17099] EXECUTING FND_AOLJ_UTIL.SET_NLS_CONTEXT() 8.1.7.1
2023634 NCOMP DOES NOT WORK WITH 8.1.7.2 JTC.H HEADER FILE 8.1.7.2
1761024UTL_SMTP PACKAGE GIVES ORA-20001: 421 SERVICE NOT AVAILABLE 8.1.7.2
1616035 EXPORT FAILED WITH ORA-01031 WHEN LOGIN AS SYSDBA 8.1.7.2
2176686 PLEASE PROVIDE A BASE LABEL FOR BUG 2066561 ON 8.1.7.2 8.1.7.2
2199855 PATCH SET EXCEPTION OF BUG 2064575 TO 8.1.7.2 SUN SOLARIS (453) 8.1.7.2
2066561 ORA-00600 [17099] EXECUTING FND_AOLJ_UTIL.SET_NLS_CONTEXT() 8.1.7.2
1994933 8.1.7.2 64 BIT RDBMS ON HPUX 11.0 FAILS TO START 8.1.7.2
1395883 LRGJ1 TKJVSJ51 (THREADS) IS HANGING ON HPUX 8.1.7.2
2176599 RFI BACKPORT OF BUG 2066561 ON TOP OF VERSION 8.1.7.3 (RFI#8749) 8.1.7.3
2275601 A PSE FOR BUG 1395883 ON 8.1.7.3 - AIX/32 ( 319 ) 8.1.7.3
2066561 ORA-00600 [17099] EXECUTING FND_AOLJ_UTIL.SET_NLS_CONTEXT() 8.1.7.3
1395883 LRGJ1 TKJVSJ51 (THREADS) IS HANGING ON HPUX 8.1.7.3
1715013 ORA-7445[JTCFV_JAVA_LANG_STR] FROM JAVA PROGRAM ON SESS_SH 8.1.7.3
2016464 ALTER SESSION SET CURRENT_SCHEMA HAS NO EFFECT ON KPRB DRIVER 8.1.7.3
2286448 ORA-29532 JAVA EXCEPTION USING XSLPROCESSOR WITHIN STYLESHEET 8.1.7.4
2239733 UNABLE TO READ FROM A SOCKET DESPITE GRANTING SOCKET PERMISSIONS8.1.7.4
2607850 MERGE OF BACKPORTS FOR 2286448,2311562 TO 8.1.7.4 ON SOLARIS(453) 8.1.7.4
1715013 ORA-7445[JTCFV_JAVA_LANG_STR] FROM JAVA PROGRAM ON SESS_SH 8.1.7.4
1395883 LRGJ1 TKJVSJ51 (THREADS) IS HANGING ON HPUX 8.1.7.4
2820879 MERGE OF 1395883 AND 1715013 ON 8.1.7.4 PORT 23 (SOLARIS 64-BIT) 8.1.7.4
2206874 OS COMM. FROM JAVA SP GIVES INCORRECT RESULTS IN 9.0.1.2 9.0.1.3
2627474 JDBC: ORACLERESULTSET.NEXT() RETURNS WRONG ANSWER 9.0.1.3
2747536 INCORRECT XMLPARSERV2.JAR FILE SHIPPED IN 9.0.1.3 PATCHSET 9.0.1.3
2598380 UNSATISFIEDLINKERROR WITH JAVA STORED PROCEDURE AFTER 9.0.1.4 9.0.1.4
2403347 MARCONI: MEMORY LEAK IN CTX_DDL.SYNC_INDEX 9.2.0.1
2460091 TRIGGER CALLING A JSP UPDATING A TIMESTAMP COLUMN RAISE ORA-3113 9.2.0.1

Java Backup

A good backup is always a DBA's best friend, especially when the database has a large number of Java Classes, Java Resources, Java Grants and Policies. No special tool is provided by Oracle to handle the Java objects backup, you'll need to use standard utilities.

A Java Classes Backup is made by a full database export without rows.

Example of a full database export:

% exp userid=system full=y ROWS=N file=full_export_norows.dmp 

To restore Java Classes from previously taken backup:

 
% imp userid=system INGORE=Y full=y

Java Privileges Backup is simply a Java grants and policies extraction from the database. Here is the script to extract the Java information (Oracle Metalink, DocID: 183825):

spool setjvmprivs.sql 
set echo off 
set feedback off 
set heading off 
set linesize 80 
set pagesize 1000 
column stmt format a70 word_wrapped 
select 'exec '||stmt 
from (select seq, 'dbms_java.grant_permission('''||grantee||''','''|| 
             type_schema||':'||type_name||''','''||name||''','''||action|| 
             ''');' stmt 
      from dba_java_policy 
      where grantee not in ('JAVADEBUGPRIV', 'JAVASYSPRIV', 'JAVAUSERPRIV', 
                         'JAVA_ADMIN', 'JAVA_DEPLOY', 'SYS', 'PUBLIC') and 
            type_name!='oracle.aurora.rdbms.security.PolicyTablePermission' 
      union all 
      select seq,'dbms_java.grant_policy_permission('''||a.grantee||''','''|| 
             u.name||''','''||permition||''','''||action||''');' stmt 
      from sys.user$ u, 
           (select seq, grantee, 
                   to_number(substr(name,1,instr(name,':')-1)) userid, 
                   substr(name,instr(name,':')+1,instr(name,'#') - 
                          instr(name,':')-1) permition, 
                   substr(name,instr(name,'#')+1 ) action 
            from dba_java_policy 
            where grantee not in ('JAVADEBUGPRIV', 'JAVASYSPRIV', 
                                  'JAVAUSERPRIV', 'JAVA_ADMIN', 'JAVA_DEPLOY', 
                                  'SYS', 'PUBLIC') and 
                  type_name = 
                      'oracle.aurora.rdbms.security.PolicyTablePermission') a 
      where u.user#=userid) order by seq; 
column stmt clear 
set pagesize 24 
set heading on 
spool off 

Output from that script should produce Java recreation commands like:

exec dbms_java.grant_permission('SCOTT','SYS:java.io.FilePermission','temp\output.txt','read,write);

Conclusion

Recent surveys showed interesting answers to the question of 'why use Java'.

Some said because Java developers are easier to find than other developers, others are of the opinion that the development time is reduced due to Java code's simplicity and accessibility. Most of them believe that Java's performance will be comparable to other natively compiled languages in the future.

Once loaded, the Java option will need attention from a DBA.

When it is no longer needed, it should be removed, rather than just sizing down the Java pool.

» See All Articles by Columnist Marin Komadina

Share:
Home
Mobile Site | Full Site
Copyright 2017 © QuinStreet Inc. All Rights Reserved