Oracle Databaseプラットフォーム共通日本語README 10g リリース2(10.2) B19227-09 |
|
戻る |
次へ |
原典情報: $ORACLE_HOME/relnotes/readmes/README_javavm.txt
目次
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開発者ガイド』には、すべての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です。
このリリースは、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_size
とjava_pool_size
がそれぞれ少なくとも50MBと20MBに設定されていることを確認する必要があります。最小インストールまたは標準インストールを選択した場合は、Java対応データベースを起動すると想定されるため、この2つの値が正しく設定されていない可能性があります。
Javaクラスのロード中のメモリー不足
shared_pool_size
の設定値が小さすぎてクラスのスキーマ・オブジェクト作成を処理できない場合は、メッセージが表示されないまま操作が失敗し、データベースに無効なクラスが残ることがあります。以降のランタイム実行時に、システムはVALIDでないクラスを解決しようとします。この操作に失敗すると、実行時にClassNotFoundException
またはNoClassDefFoundException
が表示されることがあります。これらは有効な実行時例外であり、サーバーへのクラスのインストール失敗が原因で発生する可能性があることに注意してください。ロード時にshared_pool_size
の設定に問題があったことを示しているとはかぎりません。必ず、サーバーにロードするセットにクラスが含まれていたことを確認し、loadjavaの-force
オプションを使用してロード対象のクラスでサーバー常駐クラスを強制的に置き換えることを考慮する必要があります。
loadjavaに対してロード時にクラスの解決を試みるように要求するには、loadjavaの-resolve
オプションを使用します。 通常、loadjavaでは解決に失敗するとエラー・メッセージが出力されます。これらのメッセージがメモリーの問題または「接続が失われました」などのエラーを示している場合は、shared_pool_size
とjava_pool_size
のサイズを増やして再試行できます。
loadjavaで作成したクラスのステータスをさらにチェックするには、クラスを含むスキーマでデータベースに接続し、次のように入力できます。
select * from user_objects where object_name = dbms_java.shortname('<classname>') ;
user_objectsの列にステータスが示されます。
package.procedure
のDESCRIBE
は、メソッドがPL/SQL実装ではなくJavaを含む場合に、「オブジェクトが存在しない」ことを示します。パッケージのDESCRIBE
では、PL/SQLプロシージャのみがリストされ、Javaストアド・プロシージャは除外されます。
LoadjavaとDropjavaは、クライアント側で実行するJavaベース・ユーティリティであり、Javaバイナリ、ソースまたはjarファイルをサーバーにロードし、対応するlibunit
を削除します。詳細は、印刷マニュアルとオンライン・マニュアル(『Oracle Database Java開発者ガイド』)を参照してください。
ソースとバイナリを1つのjarファイルで一緒にロードしないことをお薦めします。
同じクラスのソース(.java)ファイルとバイナリ(.class)ファイルを同じjarファイルでロードすることはできません。
Javaの重要な側面は、バイナリ標準のサポートです。
Javaバイナリ標準では、クライアント側で開発し、Javaバイナリのみをサーバーにロードできます。クライアント側コンパイラとloadjavaを使用してコンパイル済バイナリをロードする方が、ソースに対してloadjavaを使用するよりも効率がよい場合があります。
dropjava
でパッケージを削除するのが望ましいですが、その機能は存在しません。
大きい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.version
、oracle.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_HOME
、CLASSPATH
、JAVA_HOME
、LD_LIBRARY_PATH
を正しく設定する必要があります。最後に、init.ora
ファイル内でjava_pool_size
とshared_pool_size
の値を確認してください。それぞれ少なくとも50MBに設定されている必要があります。
また、各Makeファイル内では、2つの異なるCLASSPATHが定義されていることに注意してください。一方はJDK 1.1.x用で他方はJDK 1.2用です。例を実行する前に、Makeファイル(Windows NTの場合はバッチファイル)を編集し、JDKインストールに関連するMAKE_CLASSPATHがコメント解除されていることを確認する必要があります。
すべてのサンプルは、そのままで動作します。詳細は、個々のREADMEを参照してください。例を実行する前にデモ・ユーザーCLERKの作成など、多少の準備が必要となるため、READMEを参照してください。
このリリースには、すべてのコアJavaクラスとJDBCおよびSQLJ Javaクラスがシステム固有のコンパイル済形式で組み込まれています(注意: swingクラスとawtクラスはサーバー上での互換性のためにのみ組み込まれており、システム固有の方法でコンパイルされていません)。システム固有のコンパイル済コードは、$ORACLE_HOME/javavm/admin
ディレクトリにある共有オブジェクト・ライブラリを使用して実行時に動的にオープンされます。詳細は、『Oracle Database Java開発者ガイド』を参照してください。
このリリースでシステム固有の方法でコンパイルするJavaコードは、将来のリリースで自動的にアップグレードされることはありません。新規のOracleリリースに移行するには、アップグレードしてから、アップグレード後のサーバーでコードをシステム固有の方法で再コンパイルする必要があります。同様に、システム固有のコンパイル済形式によるJavaコードは、Oracleデータベース間でのJavaコードのインポートとエクスポートには含まれません。このような場合に、オペレーティング・システムとプラットフォームが同じであれば、最初に作成した配置用jarファイルを再配置し、システム固有のコンパイル済Javaコードを別の位置にインストールする必要があります。
システム固有のコンパイル済コードをサーバーに配置すると、Java権限により保護されます。詳細は、ドキュメントを参照してください。この権限が付与されるのは、システム固有のコンパイル済コードをインストールまたは提供するユーザーが、十分に認識され信頼されている場合のみ可能であることを理解する必要があります。オラクル社は共有ライブラリの生成に使用されるコード生成プロセスを提供し、詳細にテストしていますが、解析済のJavaコードおよびPL/SQLプログラムとは異なり、システム固有のコードは実行時に動的にオープンされる共有ライブラリから実行されます。この種の共有ライブラリをインストールする権利は、厳密に制御する必要があります。
プラットフォーム上の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