« Stored Procedure で host command | トップページ | Stored Procedure で host command #3 »

2007年7月 4日 (水)

Stored Procedure で host command #2

さて、前回のつづきです。
javaストアドプロシージャのソースは以下の通り。

OSコマンドを実行するjavaの例は、ググればやまほどヒットするので特に解説はなし。
Oracleでjavaストアドプロシージャを作成する方法は、マニュアル「Oracle Database Java開発者ガイド - 3 Oracle DatabaseでのJavaメソッドのコール」を参照のこと。
基本は前述のマニュアルで足りると思います。(今回は、JDBCも利用していませんし。)
それに加えて、OTN-JのOracleJVM and Java Stored Procedures なども参考になるでしょうね。

以下、Oracle JDeveloper 10.1.3.1 for MacOSXを利用。

Jdev10gmacosx_hostcommand

package jp.macdeoracle;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;


public class CommandOutputReader extends Thread {
private InputStream is;
private String lines = "";

public CommandOutputReader(InputStream is) {
this.is = is;
}

public void run()
{
String outputLine;
try {
BufferedReader br = new BufferedReader(new InputStreamReader(this.is));
while ((outputLine = br.readLine()) != null) {
System.out.println(outputLine);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package jp.macdeoracle;

import java.lang.Runtime;
import java.lang.SecurityException;
import java.io.IOException;

public class HostCommandExecuter
{
public static final String OS_WINDOWS_ = "Windows";
public static final String OS_MACOSX_ = "Mac OS X";
public static final String OS_LINUX_ = "Linux";

private static void exec(String[] command)
throws IOException,
SecurityException,
InterruptedException
{
Process myproc = Runtime.getRuntime().exec(command);
new CommandOutputReader(myproc.getInputStream()).start();
new CommandOutputReader(myproc.getErrorStream()).start();
myproc.waitFor();
}

public static void ls(String directory)
throws IOException,
SecurityException,
InterruptedException
{
String osname = System.getProperty("os.name");
if (osname.indexOf(OS_WINDOWS_) >= 0) {
String[] cmd = {"CMD.EXE", "/C", "DIR", "/B", directory};
exec(cmd);
} else if (
osname.indexOf(OS_MACOSX_) >= 0
|| osname.indexOf(OS_LINUX_) >= 0
) {
String[] cmd = {"/bin/ls", directory};
exec(cmd);
} else {
throw new IOException(osname + ":このOSには対応していません。");
}
}

public static void main(String[] args)
throws IOException,
InterruptedException,
SecurityException
{
ls(".");
}
}

上記ソースをコンパイルしてOracle Databaseへデプロイ! (以下、Oracle10g R2の例)
うまくいけば以下のようなログが表示される。

loadjavaを接続'Oracle10gR2_Scott'で呼出し中。引数:
-order -resolve -definer -force -thin -schema scott -verbose
creating : class SCOTT.jp/macdeoracle/CommandOutputReader
loading : class SCOTT.jp/macdeoracle/CommandOutputReader
creating : class SCOTT.jp/macdeoracle/HostCommandExecuter
loading : class SCOTT.jp/macdeoracle/HostCommandExecuter
resolving: class SCOTT.jp/macdeoracle/CommandOutputReader
resolving: class SCOTT.jp/macdeoracle/HostCommandExecuter
Loadjavaが終了しました。
公開が終了しました。
---- ストアド・プロシージャのデプロイが終了しました ----


次のようなエラーがでたら、J2SE 1.4.xでコンパイルし直してデプロイすべし! 
オラクルにしては、わかり易いメッセージじゃ。 (^^) 

loadjavaを接続'Oracle9iR2_Scott'で呼出し中。引数:
-order -resolve -definer -force -thin -schema scott -verbose
creating : class SCOTT.jp/macdeoracle/CommandOutputReader
loading : class SCOTT.jp/macdeoracle/CommandOutputReader
created : "SCOTT".CREATE$JAVA$LOB$TABLE
Error while creating class jp/macdeoracle/CommandOutputReader
ソケットから読み込むデータはこれ以上ありません。
Error while testing for existence of dbms_java.handleMd5
Exception java.sql.SQLException: OALL8 is in an inconsistent state.
created : "SCOTT".JAVA$CLASS$MD5$TABLE
creating : class SCOTT.jp/macdeoracle/HostCommandExecuter
loading : class SCOTT.jp/macdeoracle/HostCommandExecuter
Error while creating class jp/macdeoracle/HostCommandExecuter
ソケットから読み込むデータはこれ以上ありません。
The following operations failed
class SCOTT.jp/macdeoracle/CommandOutputReader: creation (createFailed)
class SCOTT.jp/macdeoracle/HostCommandExecuter: creation (createFailed)
oracle.aurora.server.tools.loadjava.ToolsException: Failures occurred during processing
at oracle.aurora.server.tools.loadjava.LoadJava.process(LoadJava.java:863)
at oracle.jdeveloper.deploy.tools.OracleLoadjava.deploy(OracleLoadjava.java:116)
at oracle.jdeveloper.deploy.tools.OracleLoadjava.deploy(OracleLoadjava.java:46)
at oracle.jdevimpl.deploy.OracleDeployer.deploy(OracleDeployer.java:97)
at oracle.jdevimpl.deploy.StoredProcHandler.doDeploy(StoredProcHandler.java:473)
at oracle.jdevimpl.deploy.StoredProcHandler.doDeploy(StoredProcHandler.java:360)
at oracle.jdevimpl.deploy.StoredProcHandler.doDeploy(StoredProcHandler.java:284)
at oracle.jdevimpl.deploy.StoredProcProfileDt$Action$1.run(StoredProcProfileDt.java:383)
#### デプロイが不完全です ####
*** Note ***
デプロイ・エラーの可能性の1つとして、ターゲット・データベースがJDKバージョン1.5をサポートしていないことが考えられます。
お使いのプロジェクト・プロパティ・コンパイラのソースとターゲットを古いバージョンに変更することで、この問題を修復できます。
************


プロジェクトプロパティを開いて、j2se 1.4.2を設定している様子。
Change_jdk1 Change_jdk2Change_jdk3Change_jdk4

今日はここまで。次回へつづく。

|

トラックバック


この記事へのトラックバック一覧です: Stored Procedure で host command #2:

コメント

コメントを書く