ヘッダーをスキップ

Oracle Databaseプラットフォーム共通日本語README
10g リリース2(10.2)
B19227-09
  目次
目次
 

戻る
戻る
次へ
次へ
 

Oracle JVM README

原典情報: $ORACLE_HOME/relnotes/readmes/README_javavm.txt



目次

OracleのEnterprise Java Serverプラットフォーム: Oracle JVM

既知の問題

システム固有のコンパイル済Javaコード


OracleのEnterprise Java Serverプラットフォーム: Oracle JVM

Oracle Database 10g リリース2(10.2)には、すべての機能を持つJava仮想マシン(VM)とSun社のJava Development Kit(JDK)1.4.2用Javaクラス・ライブラリが組み込まれています。
このリリースには、OracleのJDBCおよびSQLJとともに、サーバーベースJavaアプリケーションの開発と配置のためのエンタープライズ・クラス・プラットフォームであるOracle JVMが用意されています。

ドキュメント

このリリースの主要なJava関連コンポーネントについては、次のマニュアルが用意されています。

  • 『Oracle Database Java開発者ガイド』
  • 『Oracle Database JDBC開発者ガイドおよびリファレンス』
  • 『Oracle Database SQLJ開発者ガイドおよびリファレンス』
  • 『Oracle Database JPublisherユーザーズ・ガイド』

『Oracle Database Java開発者ガイド』には、すべてのJava製品の概要が記載されており、Oracle10gのJava機能を活用する起点として最適です。

各分野の詳細は、前述の各ドキュメントとそれぞれのREADMEファイルを参照してください。Oracle JVMおよびNCompについては後述します。

スタート・ガイド

まず『Oracle Database Java開発者ガイド』に記載されている例に従って作業を開始することをお薦めします。$ORACLE_HOME/javavm/demoにあるデモと例には、Javaストアド・プロシージャに関するHelloWorldの例が含まれています。この例と他の例を実行すると、インストールが正常に完了していること、およびOracle JVMがデータベースで正常に有効化されていることを確認できます。

構成

『Oracle Database Java開発者ガイド』には、Java対応データベースのインストールと構成の詳細が記載されています。 Javaの使用とパフォーマンスに影響する主要なinit.oraパラメータは、shared_pool_sizeおよびjava_pool_sizeです。

shared_pool_sizeで指定したメモリーは、loadjavaの使用中に一時的に使用されます。データベース初期化プロセス(つまり、インストール済シード・データベースではなくクリーン・データベースに対するinitjvm.sqlの実行)では、shared_pool_sizeを50MBに設定する必要があります。これにより、約8000のクラスについてJavaバイナリがロードされ、解決されます。また、shared_poolで指定したリソースは、コール仕様部の定義時と、動的にロードされるJavaクラスが実行時に追跡されるときにも使用されます。

Java実行時の他のすべてのJavaの状態は、java_pool_sizeを使用して割り当てた量から取得されます。このメモリーには、Javaのメソッドとクラスの定義に関する共有メモリー内表現と、コール終了時にセッション領域に移行されるJavaオブジェクトが含まれます。前者の場合、メモリー・コストはすべてのユーザー間で共有されます。後者の場合は、各セッションの静的変数に保持されている実際の状態の量に基づいて、MTSモードでjava_pool_sizeの割当てを調整する必要があります。

Sun社のJDKと同様に、Javaコンパイラ(Javaソース・コードをJavaバイナリにコンパイルするようにJavaで記述されたコンパイラ)は、メモリーを大量に使用することが判明しています。Oracle JVMで大量のJavaソースをコンパイルする場合、または複雑なEJB(サーバー上のコンパイラを使用)を配置する場合は、java_pool_sizeの値を大きくすることを考慮する必要があります。java_pool_sizeのデフォルト値は20MBです。

Java互換性

このリリースは、Sun社のJava Compatibility Kit for the JDK 1.4.2を使用して詳細なテストが完了しています。オラクル社は、Oracle JVMが常にJavaおよびその他のインターネット標準と互換となるように努めています。

互換性モード

Oracle JVMサーバーでJavaを使用するには、次のように設定する必要があります。

    compatibility = 8.1.0以上

既知の問題

VM自体、Javaストアド・プロシージャ、ほとんどのJava開発者が使用するユーティリティloadjavaおよびdropjavaに関して、次の問題が判明しています。JavaとSQLの相互作用、特に、SQL-Java型変換のサポートに関連する既知の問題については、JDBCのREADMEを参照してください。

メモリー使用量

Javaを使用すると、開発時と実行時のメモリー使用量に大きな差が生じますが、これは提供されるインストール時の構成支援には反映されません。特に、インストール済の構成は最小、標準およびカスタム・インストールに限定されていますが、このリリースではインストール時に問い合せてJavaの使用方法を判断する手段は用意されていません。

Oracle JVMアプリケーションの開発時には、loadjavaなど、ランタイムJavaアプリケーションとはメモリーの使用方法が異なるツールを使用することになります。これらは開発時専用ツールであり、ランタイム・アプリケーションには関係しません。クライアント側IDEを使用する開発スタイルを選択するか、Oracle JVMでJavaコンパイラを使用するように選択できます。詳細は、『Oracle Database Java開発者ガイド』を参照してください。Sun社のJDKコンパイラをベースとするコンパイラはきわめてメモリー集中度が高く、java_pool_sizeの値をインストール済構成の値から大きくすることが必要になる場合があります。

次の経験則が適用されます。

  • サーバー上でコードをコンパイルする場合は、クライアント上でコンパイルしてサーバーにロードする場合に比べて、java_pool_sizeの設定値を大きくする必要があります。EJB配置では、サーバー上のJavaコンパイラを使用するため、java_pool_sizeの設定値を大きくする必要があります。

  • 多数のクラスをサーバーにロードして解決するには、shared_pool_sizeの設定値を大きくする必要があります。

  • MTSでは、セッション数とコール終了時にJava静的変数に保持されているメモリー量の両方に基づいて、java_pool_sizeの設定値を大きくする必要があります。

  • ほとんどの場合、実行時のランタイム・メモリー所要量は、Java開発時の所要量とは異なります。Java開発時には、次の値に設定することをお薦めします。

        shared_pool_size = 50000000
        java_pool_size = 20000000

    この2つは、Oracle JVMカスタム・インストール時のデフォルトのインストール値です。

Javaアプリケーションを配置する場合、メモリー所要量はアプリケーション自体と同時実行ユーザー数に依存します。

initjvm.sql実行中のメモリーまたはリソース不足

initjvm.sqlが正常に実行されると、Javaスキーマ・オブジェクトの総数は8,000を超えます。これを確認するには次のように入力します。

    connect internal
    select count (*) from user_objects where object_type='JAVA CLASS';

すべてのクラスにVALIDマークが付いているため、無効なクラスの数は0(ゼロ)となります。これを確認するには次のように入力します。

    select count(*) from user_objects 
       where object_type='JAVA CLASS' and status != 'VALID';

initjvmが失敗した場合は、init.oraファイルをチェックして、shared_pool_sizejava_pool_sizeがそれぞれ少なくとも50MBと20MBに設定されていることを確認する必要があります。最小インストールまたは標準インストールを選択した場合は、Java対応データベースを起動すると想定されるため、この2つの値が正しく設定されていない可能性があります。

Javaクラスのロード中のメモリー不足

shared_pool_sizeの設定値が小さすぎてクラスのスキーマ・オブジェクト作成を処理できない場合は、メッセージが表示されないまま操作が失敗し、データベースに無効なクラスが残ることがあります。以降のランタイム実行時に、システムはVALIDでないクラスを解決しようとします。この操作に失敗すると、実行時にClassNotFoundExceptionまたはNoClassDefFoundExceptionが表示されることがあります。これらは有効な実行時例外であり、サーバーへのクラスのインストール失敗が原因で発生する可能性があることに注意してください。ロード時にshared_pool_sizeの設定に問題があったことを示しているとはかぎりません。必ず、サーバーにロードするセットにクラスが含まれていたことを確認し、loadjavaの-forceオプションを使用してロード対象のクラスでサーバー常駐クラスを強制的に置き換えることを考慮する必要があります。

loadjavaに対してロード時にクラスの解決を試みるように要求するには、loadjavaの-resolveオプションを使用します。 通常、loadjavaでは解決に失敗するとエラー・メッセージが出力されます。これらのメッセージがメモリーの問題または「接続が失われました」などのエラーを示している場合は、shared_pool_sizejava_pool_sizeのサイズを増やして再試行できます。

loadjavaで作成したクラスのステータスをさらにチェックするには、クラスを含むスキーマでデータベースに接続し、次のように入力できます。

    select * from user_objects where object_name = 
        dbms_java.shortname('<classname>') ;

user_objectsの列にステータスが示されます。

JavaでのDESCRIBEの問題

package.procedureDESCRIBEは、メソッドがPL/SQL実装ではなくJavaを含む場合に、「オブジェクトが存在しない」ことを示します。パッケージのDESCRIBEでは、PL/SQLプロシージャのみがリストされ、Javaストアド・プロシージャは除外されます。

LoadjavaとDropjava

LoadjavaとDropjavaは、クライアント側で実行するJavaベース・ユーティリティであり、Javaバイナリ、ソースまたはjarファイルをサーバーにロードし、対応するlibunitを削除します。詳細は、印刷マニュアルとオンライン・マニュアル(『Oracle Database Java開発者ガイド』)を参照してください。

  1. ソースとバイナリを1つのjarファイルで一緒にロードしないことをお薦めします。
    同じクラスのソース(.java)ファイルとバイナリ(.class)ファイルを同じjarファイルでロードすることはできません。

  2. Javaの重要な側面は、バイナリ標準のサポートです。
    Javaバイナリ標準では、クライアント側で開発し、Javaバイナリのみをサーバーにロードできます。クライアント側コンパイラとloadjavaを使用してコンパイル済バイナリをロードする方が、ソースに対してloadjavaを使用するよりも効率がよい場合があります。

  3. dropjavaでパッケージを削除するのが望ましいですが、その機能は存在しません。

  4. 大きいjarファイルをロードするには、shared_poolの設定変更が必要になる場合があります。
    Javaスキーマ・オブジェクトの作成には、shared_pool_sizeに指定したメモリーが使用されます。大きいjarファイルをロードできない場合は、対策としてshared_pool_sizeの値を大きくすることを考慮してください。

    loadjavaに問題があるためにクラスを正常にロードして解決できないと思われる場合は、クラスをロードしたユーザー(scott/tigerなど)で接続して次の文を実行し、ロード済クラスの状態を検査できます。

        select * from user_objects;

    正常にロードされて解決されたクラスの場合は、ステータスがVALIDと表示されます。かわりに次のように入力し、VALIDでないクラスの有無を判断する方法もあります。

        select dbms_java.longname(object_name) from user_objects 
           where object_type = 'JAVA CLASS' and status != 'VALID';

エラー・レポート

通常、エラーはトレース・ファイルでレポートされます。問題を明確にする第1歩として、トレース・ファイルを調べてください。

java.versionoracle.jserver.versionおよびoracle.server.version

リリース2(10.2)では、java.versionプロパティがJDKのデフォルトに対応する1.4.2に戻っています。コードがクライアントではなくOracle JVMで実行中かどうかを判断するために、java.versionでOracle指定を使用していた場合は、oracle.jserver.versionプロパティがNULLでないかどうかをテストするように切り替える必要があります。(リリース8.1.5では、java.versionの値はOracle Server 1.1.6でした。リリース8.1.6、8.1.7および9.0.1では、java.versionの値は1.2.1でした。リリース9.2.0では、java.versionの値は1.3.1でした。リリース10.1.0では、java.versionの値は1.4.1でした。)oracle.server.versionプロパティは廃止になっています。このプロパティは、リリース8.1.5、8.1.6および8.1.7では下位互換性を保つためにのみ設定されていました。

Javaストアド・プロシージャの使用方法を示す多数の例が用意されています。これらの例は、ORACLE_HOME/javavm/demoにあります。

各例を実行する前に、Java用のJDKコマンドであるjavacをPATHに含める必要があります。詳細は、第3.13項を参照してください。 また、ORACLE_HOMECLASSPATHJAVA_HOMELD_LIBRARY_PATHを正しく設定する必要があります。最後に、init.oraファイル内でjava_pool_sizeshared_pool_sizeの値を確認してください。それぞれ少なくとも50MBに設定されている必要があります。

また、各Makeファイル内では、2つの異なるCLASSPATHが定義されていることに注意してください。一方はJDK 1.1.x用で他方はJDK 1.2用です。例を実行する前に、Makeファイル(Windows NTの場合はバッチファイル)を編集し、JDKインストールに関連するMAKE_CLASSPATHがコメント解除されていることを確認する必要があります。

すべてのサンプルは、そのままで動作します。詳細は、個々のREADMEを参照してください。例を実行する前にデモ・ユーザーCLERKの作成など、多少の準備が必要となるため、READMEを参照してください。

JAccelerator(NComp): システム固有のコンパイル済Javaコード

このリリースには、すべてのコアJavaクラスとJDBCおよびSQLJ Javaクラスがシステム固有のコンパイル済形式で組み込まれています(注意: swingクラスとawtクラスはサーバー上での互換性のためにのみ組み込まれており、システム固有の方法でコンパイルされていません)。システム固有のコンパイル済コードは、$ORACLE_HOME/javavm/adminディレクトリにある共有オブジェクト・ライブラリを使用して実行時に動的にオープンされます。詳細は、『Oracle Database Java開発者ガイド』を参照してください。

アップグレード、ダウングレード、インポート、エクスポート

このリリースでシステム固有の方法でコンパイルするJavaコードは、将来のリリースで自動的にアップグレードされることはありません。新規のOracleリリースに移行するには、アップグレードしてから、アップグレード後のサーバーでコードをシステム固有の方法で再コンパイルする必要があります。同様に、システム固有のコンパイル済形式によるJavaコードは、Oracleデータベース間でのJavaコードのインポートとエクスポートには含まれません。このような場合に、オペレーティング・システムとプラットフォームが同じであれば、最初に作成した配置用jarファイルを再配置し、システム固有のコンパイル済Javaコードを別の位置にインストールする必要があります。

セキュリティ

システム固有のコンパイル済コードをサーバーに配置すると、Java権限により保護されます。詳細は、ドキュメントを参照してください。この権限が付与されるのは、システム固有のコンパイル済コードをインストールまたは提供するユーザーが、十分に認識され信頼されている場合のみ可能であることを理解する必要があります。オラクル社は共有ライブラリの生成に使用されるコード生成プロセスを提供し、詳細にテストしていますが、解析済のJavaコードおよびPL/SQLプログラムとは異なり、システム固有のコードは実行時に動的にオープンされる共有ライブラリから実行されます。この種の共有ライブラリをインストールする権利は、厳密に制御する必要があります。

許容されるCコンパイラ・バージョン

プラットフォーム上のSettings_os.propertiesファイルを調べて、このリリースでOracle JVMアクセラレータとの使用がサポート対象として認定されているCコンパイラを判断してください。オラクル社はこのリリースと将来のリリースに対して、より多くのCコンパイラを認定するために継続的に作業しており、この種の情報はOracle Technology Networkで随時提供されます。

既知の問題

Cコンパイル中のCコンパイラのメモリー不足

きわめて大型のパッケージのコンパイル中に、Cコンパイラがメモリー不足になることがあります。次の指定を省略すると、非バンドル・モードに切り替えて各クラスを個別にコンパイルできます。

makefile.maker = $(one.c.unit.per.dll.makefile.maker)

この指定は次の2つのファイルにあります。

  javavm/jahome/Settings_solaris.properties

および

   javavm/jahome/Settings_sunos.properties

既知の不具合: 配置用Jarのディレクトリ名にピリオドを含めると配置が異常終了する

deployncに配置用jarのフルパス名を指定する場合に、次のようにパスのディレクトリ名または配置用jar名に.(ピリオド)が含まれていると、不正な結果となります。

 deploync ... /foo.bar/mydepl.jar
 deploync ... /foo_bar/my.depl.jar

回避策(1) ディレクトリ名とjar名には.(ピリオド)を使用しません。
回避策(2) 次のように-dオプションを使用します。

 deploync ... -d /foo.bar mydepl.jar

前にNcomp化したパッケージの半分が存在しなくなる

アプリケーションが2つのjarファイルにわかれていて、パッケージPのクラスの半分が最初のjarファイルに、残りの半分が第2のjarファイルに含まれている場合、第2のjarファイルをNcomp化すると、最初のjarに含まれていたクラスが非Ncomp化されることがわかります。これは、Ncompではパッケージごとにdllが配置されるためです。

このような状況を回避するには、所定のパッケージPのクラスがすべて1つのjarファイルに収まるようにソースjarを構成します。これにより、パフォーマンスも最大になります。

すべてのトップレベルが同じUnnamedPackageパッケージにある

トップレベルのクラスに注意してください。トップレベルのクラスXを前にNcomp化しており、その後にトップレベルのクラスYを別個にNcomp化すると、Xは非Ncomp化されます。これは、トップレベルのクラスはすべて特殊なパッケージであるUnnamedPackageにあるとみなされるためです。

パッケージPになにもないため、Ncomp化する対象がない

サーバー上に存在するクラスのないパッケージがソースjarに含まれていると、Ncompでは次のように個々の各クラスがNOT_FOUND_IN_SCHEMAであるが、各パッケージはALREADY_NCOMPEDとレポートされます。

NOT_FOUND_IN_SCHEMA oracle/aurora/mts/iiop/ORB
NOT_FOUND_IN_SCHEMA oracle/aurora/mts/iiop/SessIiopService
..
ALREADY_NCOMPED oracle/aurora/mts/iiop/

この場合、このALREADY_NCOMPEDは、「なにも存在しないためNcomp化する対象がない」ことを意味します。

NcompでNEED_NCOMPINGと表示された後に凍結する

Ncompでは、一連のNEED_NCOMPINGがレポートされた後、配置用jarが作成されて配置準備が完了するまでは何も表示されません。マシンによっては、この遅延が凍結状態のようにみえることがあります。進行状況を確認するには、ncomp.logファイルを調べます。もう1つの解決策は、-verboseオプションを指定して出力を画面にリダイレクトすることです。

javavm/adminのファイル領域の管理

Ncompのリリース10.2.0のユーザー・インタフェースは、javavm/adminディレクトリにあるdllの管理は試行されません。dllには一意の名前が付いているため、javavm/adminには時間経過とともに廃止になった多数のdllが累積していく場合があります。

特定のスキーマの特定のパッケージごとに、最新の配布dllのみが使用されます。jaccelerator$dlls表を分析するか、次のスクリプトを実行すると、どのdllが使用中であるかを検出できます。

#!/bin/sh
# list of ncomp dlls in use

usage () {
  echo "libs used by ncomped classes foo/bar*"
  echo "usage: $0 foo/bar"
  exit 1
}

if [ $# -lt 1 ]; then  usage; fi

DIR=`dirname $0`

cat >$DIR/DLLsReport.java <<EOJAVA

package oracle.jaccelerator.utl;
import oracle.aurora.rdbms.Schema;
import oracle.aurora.rdbms.ClassHandle;
import oracle.aurora.rdbms.Handle;
import oracle.aurora.rdbms.ObjectTypeChangedException;
import oracle.sql.CHAR;

import java.io.*;
import java.util.Date;

import java.sql.*;
import oracle.jdbc.driver.*;

public class DLLsReport {
  public static String dll (String schemaAndName) 
    throws SQLException
  {
    int colonIdx = schemaAndName.indexOf(':');
    String name = schemaAndName.substring(colonIdx + 1);
    String schema = schemaAndName.substring(0, colonIdx);
    String  result = "bad handle";

    ClassHandle h = Handle.lookupClass(name, Schema.lookup(schema));
    if (h == null) {
      result = "null handle" + h;
    }
    else {
      result = h.getNcompDllNameAsCHAR().toString();
    }
    return result;
  }
}
EOJAVA

set -x

loadjava -oci8 -resolve -user internal/change_on_install  $DIR/DLLsReport.java

svrmgrl  <<EOI

connect internal/change_on_install

create or replace function isvnc_get_class_dll (pkg varchar2) return VARCHAR2 as
  language java name 'oracle.jaccelerator.utl.DLLsReport.dll(java.lang.String) return java.lang.String';
/
show errors;
select distinct isvnc_get_class_dll(OWNER || ':'  || dbms_java.longname(OBJECT_NAME)) from
  all_objects where OBJECT_TYPE = 'JAVA CLASS' and dbms_java.longname(OBJECT_NAME) like '$1%' ;

EOI