Not only developing

Linux,Oracle,Java and much more…..

Lanciare un processo sincrono da Oracle tramite Java

Pubblicato da teox78 su Gennaio 23, 2008

Ecco una breve classe java che permette di lanciare un qualsiasi processo del sistema operativo da Oracle.

CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED “FileHandler” AS
import java.io.*;
import java.sql.*;
import oracle.sql.*;
import oracle.jdbc.driver.*;


class StreamReader extends Thread {
InputStream inputStream;
String prefix;

StreamReader(InputStream inputStream, String prefix) {
this.inputStream = inputStream;
this.prefix = prefix;
}

public void run() {
try {
InputStreamReader inputStreamReader = new InputStreamReader(
inputStream);
BufferedReader bufferedReader = new BufferedReader(
inputStreamReader);
String line = null;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(prefix + ” ” + line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

class StreamWriter extends Thread {
OutputStream outputStream;
String prefix;

StreamWriter(OutputStream outputStream) {
this.outputStream = outputStream;
}

public void run() {
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
while (true) {
bufferedWriter.newLine();
}
} catch (IOException e) {

}
}
}

public class FileHandler {

public static int run (String command) {
Runtime runtime = Runtime.getRuntime();
Process process;
int exitValue = -1;
try {
process = runtime.exec(command);

StreamReader errorReader = new StreamReader(process.getErrorStream(), “<<ERROR>>”);
StreamReader outputReader = new StreamReader(process.getInputStream(), “<<OUTPUT>>”);
StreamWriter inputWriter = new StreamWriter(process.getOutputStream());
errorReader.start();
outputReader.start();
inputWriter.start();
exitValue = process.waitFor();

} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return exitValue;
}

};

La classe StreamReader serve per poter catturare lo standard output e lo standard error del processo lanciato e loggarli : in questo caso verranno scitti all’interno di trace file nella directory user dump di Oracle ma nulla ci vieta di inserire il tutto in una tabella per una consultazione più rapida. La classe StreamWriter invece impedisce che il processo si blocchi nel caso quest’ultimo sia in attesa sullo standard input. Nel mio caso ero solo interessato al fatto che il processo non si bloccasse quindi non faccio altro che simulare un invio da tastiera, però si potrebbero inviare delle informazioni tramite lo standard input se il processo lo richiedesse.

Il metodo run all’interno della classe FileHandler non fa altro che lanciare il processo e restituire il valore ritornato dal processo, solitamente 0 significa ‘terminato con successo’ e tutto il resto significa che si sono verificati degli errori.

Adesso creiamo una stored procedure che punti a questo metodo :

create or replace FUNCTION OSCommand_Run(Command IN STRING) RETURN NUMBER IS LANGUAGE JAVA NAME 'FileHandler.run(java.lang.String) return int';

Diamo i permessi necessari

EXEC DBMS_JAVA.grant_permission('SCHEMA-NAME', 'java.io.FilePermission', '<<ALL FILES>>', 'read ,write, execute, delete');
EXEC DBMS_JAVA.grant_permission(’SCHEMA-NAME’, ‘SYS:java.lang.RuntimePermission’, ‘writeFileDescriptor’, ”);
EXEC DBMS_JAVA.grant_permission(’SCHEMA-NAME’, ‘SYS:java.lang.RuntimePermission’, ‘readFileDescriptor’, ”);

A questo punto possiamo lanciare e monitorare un qualsiasi processo del sistema operativo da una stored procedure o package.

Lascia una Risposta

XHTML: Puoi usare questi tag: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>