11 August 2006

RMI Call via PL/SQL

Oracle has a JVM which called OracleJVM. You can load java classes or java source directly on Oracle. I need an RMI call within Oracle. So I implement it. I describe how to call RMI within PL/SQL below




The interface that will be used from RmiServer and RmiClient is written. The function which will be invoked must be declared in the intreface.
(Server ve client in ortak kullnacağı interface yazılır. Bu intreface içinde RMI ile invoke edilecek fonksiyon belirtilir)

package rmi;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface IServer extends Remote {

    public String getTipOfTheDay() throws RemoteException;
}


A class is writen for parameters.
(Parametreler için de bir class yazılır)

package rmi;

public class Parameter {

    public static int portNumber       = 2005;
    public static String objectName    = "//127.0.0.1:2005/RmiServer”;
    public static String host      = "//127.0.0.1:2005/RmiServer";
   
    public Parameter() {
    }
   
}


Java files for RmiServer is writen:
(Server için java dosyaları yazılır)

package rmi;

import java.rmi.Naming;
import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;


public class RmiServer extends UnicastRemoteObject implements IServer {

    private Parameter configurationParameters;
   
    public RmiServer() throws RemoteException {
        alert("Server Created...");
        configurationParameters  = new Parameter();
    }

    public static void main(String[] args) {       
        try {       
            RmiServer rmiServer = new RmiServer();
            rmiServer.changeState("start");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void changeState( String state ) {
        if( state == "start" ){
            start();
        }else if( state == "stop" ){
            stop();
        }
    }
   
    private static void alert( String message ){
        System.out.println( message );
    }
   
    private void start( ) {
        System.setSecurityManager(new RMISecurityManager());
        try {
            LocateRegistry.createRegistry(Parameter.portNumber);
           
            Naming.rebind(Parameter.objectName, this );
            alert( "Server is ready to handle request.......");
        } catch (Exception ex) {
            alert( "Error occured...........");
            ex.printStackTrace();
        }
    }

    private void stop() {
        try {
            Naming.unbind(Parameter.objectName);
            alert( "Server CANNOT handle requests anymore.......");
        } catch (Exception e) {
            alert( "Error occured...........");
            e.printStackTrace();
        }
    }

    public String getTipOfTheDay() throws RemoteException {
        alert("getTipOfTheDay Method Invoked....");
        String tip = "Imagination is more important than knowledge. Knowledge is limited; imagination encircles the world.";
       
        return tip;
    }
}

Also for RmiClient java source files are created within Oracle.
(Client için java kaynak dosyaları Oracle içine yazılır)


create or replace and compile java source named rmi as

package rmi;

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.Naming;

public class Parameter {

    public static int portNumber       = 2005;
    public static String objectName    = "//127.0.0.1:2005/RmiServer”;
    public static String host      = "//127.0.0.1:2005/RmiServer";
   
    public Parameter() {
    }
   
}


    private static IServer getServer() throws Exception {
        Parameter configurationParameters = new Parameter();
        IServer server = (IServer) Naming.lookup( configurationParameters.objectName);

        return server;
    }

}

public class RmiClient {
   
    public RmiClient(){
    }
   
    public static String getTipOfTheDay(){
        String result = "";
        try {
            IServer server = getServer();
            result = server.getTipOfTheDay();   
        } catch (Exception ex) {
            result = ex.getStackTrace().toString();
        }
        return result;
       
    }

/

Compilation is done
(Compile işlemi yapılır)


C:\projects\RmiSample\classes\rmi>del *.*

C:\projects\RmiSample\src\rmi>javac -classpath classes *
C:\projects\RmiSample\src\rmi>move *.class ../../classes/rmi


rmic compilation is done. Stub file(RmiServer_Stub.class) is created( With JDK 1.5 Skel file is nor created with rmic)
(rmic ile derleme işlemi yapılır. Stub dosyası oluşturulur( JDK 1.5 ile Skel oluşmamaktadır))

C:\projects\RmiSample\classes>rmic -classpath . rmi.RmiServer

Policy.file is created:
(Policy.file oluşturulur)

grant {
    //All Permissions Given!
    permission java.security.AllPermission;
  };


For RmiServer, runRmiServer.bat file is cretaed
(Server’in çalıştıracak runRmiServer.bat dosyası oluşturulur)

set CLASSPATH=.;classes
java -Djava.security.manager -Djava.security.policy=policy.file  rmi.RmiServer

If you want to start RmiServer on unix environment, runRmiServer.sh  is created.
(RmiServer unix ortamında çalıştırılacak ise runRmiServer.sh oluşturulur)

#!/bin/ksh

CLASSPATH=classes
export CLASSPATH
java -classpath $CLASSPATH -Djava.security.manager -Djava.security.policy=policy.file  rmi.RmiServer

policy.file and runRmiServer.(bat/sh) files are put the same directory.
(policy.file ve runRmiServer.bat dosyası aynı yere konur)

C:\projects\RmiSample>dir
 Volume in drive C is Cronus
 Volume Serial Number is 8CC9-D0FD

 Directory of C:\projects\RmiSample

08.08.2006  15:28   
          .
08.08.2006  15:28   
          ..
04.08.2006  16:05             3.913 build.xml
08.08.2006  15:34   
          classes
08.08.2006  13:52                15 params.txt
03.08.2006  15:08                92 policy.file
03.08.2006  12:01               549 RmiSample.iml
03.08.2006  12:08            10.540 RmiSample.ipr
03.08.2006  12:38            28.139 RmiSample.iws
03.08.2006  16:30             4.611 RmiSample.jpr
03.08.2006  13:54               105 runRmiServer.bat
04.08.2006  16:05               151 runRmiServer.sh
08.08.2006  14:11   
          src
               9 File(s)         48.115 bytes
               4 Dir(s)   2.516.996.096 bytes free


runRmiServer.(bat/sh) is executed.
(Bir command penceresinden runRmiServer.bat çalıştırılır)

C:\projects\RmiSample>runRmiServer.bat

C:\projects\RmiSample>set CLASSPATH=.;classes

C:\projects\RmiSample>java -Djava.security.manager -Djava.security.policy=policy.file  rmi.RmiServer
Server Created...
Server is ready to handle request.......

RmiServer_Stub.class is loaded OracleJVM via loadjava utility.
(RmiServer_Stub.class, loadjava ile OracleJVM içine yüklenir)

E:\oracle\product\10.2.0\db_2\BIN>loadjava -resolve C:\projects\RmiSample\classes\rmi\RmiServer_Stub.class

PL/SQL wrapper function is created
(PL/SQL çağırıcı fonksiyon yazılır)

CREATE OR REPLACE FUNCTION rmi_call_plsql
   RETURN VARCHAR2 IS
   LANGUAGE JAVA
   NAME 'rmi.RmiClient.getTipOfTheDay() return java.lang.String';
/

rmi_call_plsql function is called via PL/SQL
(rmi_call_plsql fonksiyonu PL/SQL içinden çağırılır)

DECLARE
  res VARCHAR2(1000);
BEGIN
  dbms_output.put_line('Result is ' || rmi_call_plsql);
END;

Output checked
(Çıktı kontrol edilir)

Result is Imagination is more important than knowledge. Knowledge is limited; imagination encircles the world.


Be sure RmiServer invoked
(Server açık olduğu command penceresine bakılır)

C:\projects\RmiSample>java -Djava.security.manager -Djava.security.policy=policy
.file  rmi.RmiServer
Server Created...
Server is ready to handle request.......
getTipOfTheDay Method Invoked....


No comments: