Home>Question Details



Henk-Jan -- Thanks for the question regarding "Java procedure for host calls on Unix environment", version 8.1.6

Submitted on 24-Oct-2000 11:10 Central time zone
Last updated 2-Sep-2009 10:15

You Asked

Steve,

I'm looking for a Java-procedure executing host calls on a Unix environment from the 
Oracle-server. I know the standard way of doing it by means of ProC (for Oracle versions 
before 8.1) but I do not have the ProC compiler available.

I do not know Java or ProC (nor do I currently have the time to learn them). I've found 
several examples of these scripts but the "Runtime Power" script on this site does not 
seem to do anything at all and the other script I've found in an Oracle newsgroup seems 
to miss some "#import" statements in order to compile correctly.

I would greatly appreciate your help on this one.
Henk-Jan 

and we said...


Here is how to do this in java in 8.1.6.  8.1.6 added lots of new security features so 
this would be a little different in 8.1.5 but mostly the same.  

We need to start by granting some privs.  I'm going to grant as little as I have to get 
allow us to execute the program /usr/bin/ps.  As SYS or some appropriately priveleged 
user, we will execute:

sys@DEV816> begin
  2      dbms_java.grant_permission
  3      ('RT_TEST',
  4       'java.io.FilePermission',
  5       '/usr/bin/ps',
  6       'execute');
  7  
  8      dbms_java.grant_permission
  9      ('RT_TEST',
 10       'java.lang.RuntimePermission',
 11       '*',
 12       'writeFileDescriptor' );
 13  end;
 14  /

PL/SQL procedure successfully completed.


That allows our user RT_TEST to successfully execute that program.  We could have allowed 
it to execute /usr/bin/* or * or whatever -- I'm just letting it execute that one 
program.

Now, RT_TEST would create in its schema:


rt_test@DEV816> create or replace and compile
  2  java source named "Util"
  3  as
  4  import java.io.*;
  5  import java.lang.*;
  6  
  7  public class Util extends Object
  8  {
  9  
 10    public static int RunThis(String[] args)
 11    {
 12    Runtime rt = Runtime.getRuntime();
 13    int        rc = -1;
 14  
 15    try
 16    {
 17       Process p = rt.exec(args[0]);
 18  
 19       int bufSize = 4096;
 20       BufferedInputStream bis =
 21        new BufferedInputStream(p.getInputStream(), bufSize);
 22       int len;
 23       byte buffer[] = new byte[bufSize];
 24  
 25       // Echo back what the program spit out
 26       while ((len = bis.read(buffer, 0, bufSize)) != -1)
 27          System.out.write(buffer, 0, len);
 28  
 29       rc = p.waitFor();
 30    }
 31    catch (Exception e)
 32    {
 33       e.printStackTrace();
 34       rc = -1;
 35    }
 36    finally
 37    {
 38       return rc;
 39    }
 40    }
 41  }
 42  /

Java created.

rt_test@DEV816> create or replace
  2  function RUN_CMD( p_cmd  in varchar2) return number
  3  as
  4  language java
  5  name 'Util.RunThis(java.lang.String[]) return integer';
  6  /

Function created.


To make this callable as a procedure (ignoring the return code), we'll create a 
procedure:

rt_test@DEV816> 
rt_test@DEV816> create or replace procedure RC(p_cmd in varchar2)
  2  as
  3    x number;
  4  begin
  5    x := run_cmd(p_cmd);
  6  end;
  7  /

Procedure created.

And now to run it:

rt_test@DEV816> set serveroutput on size 1000000
rt_test@DEV816> exec dbms_java.set_output(1000000)
PL/SQL procedure successfully completed.
rt_test@DEV816> exec rc('/usr/bin/ps -ef');
UID   PID  PPID  C    STIME TTY      TIME CMD
root     0     0  0   Aug 17 ?        0:06 sched
root     1     0  0   Aug 17 ?        1:19 /etc/init -
root     2     0  0   Aug 17 ?        0:23 pageout
.....

PL/SQL procedure successfully completed.

rt_test@DEV816>


See

http://java.sun.com/j2se/1.3/docs/api/java/lang/RuntimePermission.html
http://java.sun.com/j2se/1.3/docs/api/java/security/SecurityPermission.html
http://java.sun.com/j2se/1.3/docs/api/java/io/FilePermission.html
and 


http://download-east.oracle.com/docs/cd/A81042_01/DOC/java.816/a81353/perf.htm#1001971
From the “Java Developer’s Guide”, Part No. A81353-01, Chapter 5:

Table 5–1 Permission Types
n java.util.PropertyPermission
n java.io.SerializablePermission
n java.io.FilePermission
n java.net.NetPermission
n java.net.SocketPermission
n java.lang.RuntimePermission
n java.lang.reflect.ReflectPermission
n java.security.SecurityPermission
n oracle.aurora.rdbms.security.PolicyTablePermission
n oracle.aurora.security.JServerPermission

 

Reviews    
5 stars   May 30, 2001 - 3pm Central time zone
Reviewer: Nagarajan from USA
very useful material. Thanks for the same 


5 stars Exactly what I needed to see   June 4, 2001 - 8am Central time zone
Reviewer: B.Wisniewski from Columbus, OH USA
This is exactly what I needed to see in an example of interacting with the operating system.  
Trying to persuade the developers to use Java vs Perl and this is what I needed.

Thanks again. 


5 stars   July 27, 2001 - 5am Central time zone
Reviewer: Mark Penny from Thetford, Norfolk UK.
I had never imagined that this could be done so easily. Thank you. 


5 stars great answer   October 3, 2001 - 10am Central time zone
Reviewer: Sharon from Israel
Great material , it's exactlly what I was looking for
10x you a lot 


5 stars   November 21, 2001 - 8pm Central time zone
Reviewer: A reader 
hi tom
your reply on extrnal procedure works
Thanks

I am also trying to run executable from java
i am getting this error

I am running Pesonal Oracle 8.1.7 on windows 98

SQL>  exec rc('c:\windows\command /c dir');
java.io.IOException
at oracle.aurora.java.lang.OracleProcess.create(OracleProcess.java)
at oracle.aurora.java.lang.OracleProcess.construct(OracleProcess.java)
at java.lang.Runtime.execInternal(Runtime.java)
at java.lang.Runtime.exec(Runtime.java)
at java.lang.Runtime.exec(Runtime.java)
at java.lang.Runtime.exec(Runtime.java)
at Util.RunThis(Util:11)

PL/SQL procedure successfully completed. 


Followup   November 22, 2001 - 8am Central time zone:

Ok, is there a c:\windows\command.exe ?

do a dir c:\windows\command.*

show us the entire example from the dbms_java calls to the create or replace and compile java 
source to the call you are doing itself. 

5 stars   November 22, 2001 - 10am Central time zone
Reviewer: A reader 
hi tom

it was dir c:\windows\command.com

when i run 
exec rc('c:\windows\command.com /c dir');

it never come back

i examined udump file it looks like

Dump file d:\oracle\admin\swami\udump\ORA10653.TRC
Thu Nov 22 09:34:37 2001
ORACLE V8.1.7.0.0 - Production vsnsta=0
vsnsql=e vsnxtr=3
Windows 95 V4.10, OS V192.0, CPU type 586
Oracle8i Personal Edition Release 8.1.7.0.0 - Production
JServer Release 8.1.7.0.0 - Production
Windows 95 V4.10, OS V192.0, CPU type 586
Instance name: swami

Redo thread mounted by this instance: 1

Oracle process number: 13

Windows thread id: -710243, image: ORACLE.EXE


*** 2001-11-22 09:34:37.720
*** SESSION ID:(17.10) 2001-11-22 09:34:37.610
Specified COMMAND search directory bad   Microsoft(R) Windows 98    
(C)Copyright Microsoft Corp 1981-1998.  D:\Oracle\Ora81\DATABASE>

any idea.

Thanks


 


Followup   November 22, 2001 - 10am Central time zone:

Well, it looks like it just started up a command shell -- did not process the "/c dir" part of it 
(hence the apparent HANG -- it was waiting for someone to type "exit".


what happens if you just enter:

c:\windows\command.com /c dir


on the dos prompt itself.  does that work?

what if you create a script:

do_dir.bat:

@echo off
dir


and run that instead? 

5 stars but....   November 22, 2001 - 10am Central time zone
Reviewer: Connor from Cold cold Scotland
who is Steve ?

:-) 


Followup   November 22, 2001 - 10am Central time zone:

Thats a darn good question -- never noticed that Henk-Jan called me "steve" :) 

5 stars   November 22, 2001 - 10am Central time zone
Reviewer: A reader 
hi tom,

i ran

c:\windows\command.com /c dir

on dos prompt it works fine
and i also created do_dit.bat and it also works fine

thanks
 


Followup   November 22, 2001 - 11am Central time zone:

did you call the do_dir.bat from the java stored procedure -- if so, thats your solution.  You see 
-- this is purely a "command.com" issue here -- we are getting a command.com error "search path 
invalid (sounds like a bad COMSPEC or something, been a really long time since I worked with dos 
stuff like that). 

5 stars re: steve   November 22, 2001 - 11am Central time zone
Reviewer: Mark A. Williams from Indianapolis, IN USA
I think 'Steve' is Tom's alter ego -- you know, the one who is answering questions and such on 
Thanksgiving!  Thought you (Tom) were taking a break?  OK, so I'm *reading* AskTom on 
Thanksgiving...  but that's just because I haven't had the turkey yet. 


5 stars   November 22, 2001 - 11am Central time zone
Reviewer: A reader 
<code>hi tom
Sorry for disturbance on thanks giving but my problem is critical i have to implement this on coming MONDAY

when i run
exec rc('c:\windows\command.com /c dir');

it never come back

THIS TIME I SET SQL_TRACE = TRUE

AND LOG FILE IS AS FOLLOWS

I KILLED SESSION FOR THREE TIMES AND CHECK LOG FILE EACH TIME. IT IS SIMILER EVERY TIME

Dump file d:\oracle\admin\swami\udump\ORA51445.TRC
Thu Nov 22 11:16:57 2001
ORACLE V8.1.7.0.0 - Production vsnsta=0
vsnsql=e vsnxtr=3
Windows 95 V4.10, OS V192.0, CPU type 586
Oracle8i Personal Edition Release 8.1.7.0.0 - Production
JServer Release 8.1.7.0.0 - Production
Windows 95 V4.10, OS V192.0, CPU type 586
Instance name: swami

Redo thread mounted by this instance: 1

Oracle process number: 10

Windows thread id: -341771, image: ORACLE.EXE


*** 2001-11-22 11:16:57.070
*** SESSION ID:(11.3) 2001-11-22 11:16:57.010
APPNAME mod='SQL*Plus' mh=3669949024 act='' ah=4029777240
=====================
PARSING IN CURSOR #1 len=35 dep=0 uid=18 oct=42 lid=18 tim=0 hv=2767092717 ad='4332a9c'
alter session set sql_trace = true
END OF STMT
EXEC #1:c=0,e=0,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=4,tim=0
=====================
PARSING IN CURSOR #1 len=87 dep=0 uid=18 oct=47 lid=18 tim=0 hv=3739629728 ad='433c588'
BEGIN RC('c:\windows\command.COM /c exp scott/tiger file=c:\xx.dmp tables=emp'); END;
END OF STMT
PARSE #1:c=0,e=0,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=4,tim=0
=====================
PARSING IN CURSOR #2 len=64 dep=1 uid=0 oct=2 lid=0 tim=0 hv=3686129482 ad='477a920'
insert into javasnm$(short, longname, longdbcs) values(:1,:2,:3)
END OF STMT
PARSE #2:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=0,tim=0
=====================
PARSING IN CURSOR #3 len=46 dep=1 uid=0 oct=3 lid=0 tim=0 hv=2044415509 ad='475d6b4'
select longname from javasnm$ where short = :1
END OF STMT
PARSE #3:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=0
EXEC #3:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=0
FETCH #3:c=0,e=0,p=0,cr=5,cu=0,mis=0,r=1,dep=1,og=4,tim=0
EXEC #3:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=0
FETCH #3:c=0,e=0,p=0,cr=5,cu=0,mis=0,r=1,dep=1,og=4,tim=0
EXEC #3:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=0
FETCH #3:c=0,e=0,p=0,cr=5,cu=0,mis=0,r=1,dep=1,og=4,tim=0
EXEC #3:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=0
FETCH #3:c=0,e=0,p=0,cr=5,cu=0,mis=0,r=1,dep=1,og=4,tim=0
EXEC #3:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=0
FETCH #3:c=0,e=0,p=0,cr=5,cu=0,mis=0,r=1,dep=1,og=4,tim=0
EXEC #3:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=0
FETCH #3:c=0,e=0,p=0,cr=5,cu=0,mis=0,r=1,dep=1,og=4,tim=0
EXEC #3:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=0
FETCH #3:c=0,e=0,p=0,cr=5,cu=0,mis=0,r=1,dep=1,og=4,tim=0
EXEC #3:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=0
FETCH #3:c=0,e=0,p=0,cr=5,cu=0,mis=0,r=1,dep=1,og=4,tim=0
EXEC #3:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=0
FETCH #3:c=0,e=0,p=0,cr=5,cu=0,mis=0,r=1,dep=1,og=4,tim=0
=====================
PARSING IN CURSOR #4 len=57 dep=1 uid=0 oct=3 lid=0 tim=0 hv=467722929 ad='46be564'
SELECT max(version) FROM "SYS"."JAVA$POLICY$SHARED$TABLE"
END OF STMT
PARSE #4:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=0
EXEC #4:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=1,cu=4,mis=0,r=1,dep=1,og=4,tim=0
STAT #4 id=1 cnt=1 pid=0 pos=0 obj=0 op='SORT AGGREGATE '
STAT #4 id=2 cnt=2 pid=1 pos=1 obj=16803 op='TABLE ACCESS FULL JAVA$POLICY$SHARED$TABLE '
=====================
PARSING IN CURSOR #4 len=57 dep=1 uid=0 oct=3 lid=0 tim=0 hv=467722929 ad='46be564'
SELECT max(version) FROM "SYS"."JAVA$POLICY$SHARED$TABLE"
END OF STMT
PARSE #4:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=0
EXEC #4:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=1,cu=4,mis=0,r=1,dep=1,og=4,tim=0
STAT #4 id=1 cnt=1 pid=0 pos=0 obj=0 op='SORT AGGREGATE '
STAT #4 id=2 cnt=2 pid=1 pos=1 obj=16803 op='TABLE ACCESS FULL JAVA$POLICY$SHARED$TABLE '
EXEC #3:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=0
FETCH #3:c=0,e=0,p=0,cr=5,cu=0,mis=0,r=1,dep=1,og=4,tim=0
EXEC #3:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=0
FETCH #3:c=0,e=0,p=0,cr=5,cu=0,mis=0,r=1,dep=1,og=4,tim=0
EXEC #3:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=0
FETCH #3:c=0,e=0,p=0,cr=5,cu=0,mis=0,r=1,dep=1,og=4,tim=0
=====================
PARSING IN CURSOR #4 len=147 dep=1 uid=0 oct=3 lid=0 tim=0 hv=3013728279 ad='468ad64'
select privilege#,level from sysauth$ connect by grantee#=prior privilege# and privilege#>0 start with (grantee#=:1 or grantee#=1) and privilege#>0
END OF STMT
PARSE #4:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=0
EXEC #4:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=5,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=4,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=4,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=2,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=4,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=4,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=4,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=2,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=4,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=5,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=2,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=4,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=5,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=3,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=5,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=5,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=5,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=5,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=2,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=4,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=6,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=2,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=4,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=6,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=4,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=4,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=4,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=4,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=2,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=3,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=6,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=4,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=4,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=2,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=5,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=4,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=4,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=3,cu=0,mis=0,r=0,dep=1,og=4,tim=0
STAT #4 id=1 cnt=37 pid=0 pos=0 obj=0 op='CONNECT BY '
STAT #4 id=2 cnt=20 pid=1 pos=1 obj=0 op='CONCATENATION '
STAT #4 id=3 cnt=1 pid=2 pos=1 obj=102 op='INDEX RANGE SCAN '
STAT #4 id=4 cnt=20 pid=2 pos=2 obj=102 op='INDEX RANGE SCAN '
STAT #4 id=5 cnt=19 pid=1 pos=2 obj=83 op='TABLE ACCESS BY USER ROWID SYSAUTH$ '
STAT #4 id=6 cnt=55 pid=1 pos=3 obj=102 op='INDEX RANGE SCAN '
=====================
PARSING IN CURSOR #4 len=147 dep=1 uid=0 oct=3 lid=0 tim=0 hv=3013728279 ad='468ad64'
select privilege#,level from sysauth$ connect by grantee#=prior privilege# and privilege#>0 start with (grantee#=:1 or grantee#=1) and privilege#>0
END OF STMT
PARSE #4:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=0
EXEC #4:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=5,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=4,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=4,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=2,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=4,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=4,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,cr=4,cu=0,mis=0,r=1,dep=1,og=4,tim=0
FETCH #4:c=0,e=0,p=0,c

Followup   November 23, 2001 - 9am Central time zone:

I already diagnosed this!  It is NOT HANGNING IN ORACLE.  You put up this dump file before:

i examined udump file it looks like


.....
Dump file d:\oracle\admin\swami\udump\ORA10653.TRC
Thu Nov 22 09:34:37 2001
ORACLE V8.1.7.0.0 - Production vsnsta=0
vsnsql=e vsnxtr=3
Windows 95 V4.10, OS V192.0, CPU type 586
Oracle8i Personal Edition Release 8.1.7.0.0 - Production
JServer Release 8.1.7.0.0 - Production
Windows 95 V4.10, OS V192.0, CPU type 586
Instance name: swami

Redo thread mounted by this instance: 1

Oracle process number: 13

Windows thread id: -710243, image: ORACLE.EXE


*** 2001-11-22 09:34:37.720
*** SESSION ID:(17.10) 2001-11-22 09:34:37.610
Specified COMMAND search directory bad   Microsoft(R) Windows 98    
(C)Copyright Microsoft Corp 1981-1998.  D:\Oracle\Ora81\DATABASE>

any idea.

.......

When you are running "command /c dir"  -- dos is messing up.  You see the error message there 
"Specified COMMAND search directory bad" and a command prompt.  That is your HANG.

command.com is running,
It is messing up.
It is dumping you at the command prompt -- waiting for you to type something in.

Unfortunately for you - this command prompt is in the background, you cannot see it, you cannot 
type into it.  It will sit there forever.  

This is NOT hanging in the database. This is hanging in DOS.  


Did you try the .bat file as I suggested.  If that works -- that is in fact your solution.  If it 
doesn't, you'll have to find out what that error message is and how to fix it.  I don't have 
windows98 to test with. 

5 stars   November 24, 2001 - 5pm Central time zone
Reviewer: A reader 
hi tom

finally i am able to run OS command from pl/sql.but from
Windws NT not Windows 98.

Now I can  run os command using extrnal procedure
and Java stored procedure.

Thank you very much for your co-opration 


3 stars Encountering some limitations   November 29, 2001 - 3pm Central time zone
Reviewer: Andrew from ca, usa
Tom
Thanks for the great code, but I'm hitting limitations using '>', '|' and other metacharacters. 
Please could you explain why my attempts fail. I can only overcome the problem by writing the 
string I want to execute to a script (using utl_file, doing a chmod +x on that and then executing 
it). As you can see the use of '|' returns and error, the use of '>' is ignored.

1.) Granted the following privs from sys:
begin                                       
    dbms_java.grant_permission     
    ('SCOTT',                    
     'java.io.FilePermission',     
     '/tmp/*',                
     'execute');         
    dbms_java.grant_permission     
    ('SCOTT',                    
     'java.io.FilePermission',     
     '/usr/bin/*',                
     'execute');         
    dbms_java.grant_permission     
    ('SCOTT',                    
     'java.lang.RuntimePermission',
     '*',                          
     'writeFileDescriptor' );  
-- try to accomodate input redirection    
    dbms_java.grant_permission     
    ('SCOTT',                    
     'java.lang.RuntimePermission',
     '*',                          
     'readFileDescriptor' );      
-- try to accomodate input/output redirection    
    ('SCOTT',                    
     'java.io.FilePermission',     
     '/tmp/*',                
     'read,write'); 
-- commit;        
end;
/


2.) changed RC to output the return code:
CREATE OR REPLACE procedure RC(p_cmd in varchar2)
as
  x number;
begin
  x := run_cmd(p_cmd);
  DBMS_OUTPUT.PUT_LINE ( 'run_cmd returned : '||rpad(x, 3, ' ')||' for '|| p_cmd); 
end;
/


3.) the results
SQL> set serveroutput on
SQL> 
SQL> set serveroutput on
SQL> 
SQL> declare
  2    dummy varchar2(50);
  3  begin
  4    dbms_output.enable(1000000);
  5    dbms_java.set_output(1000000);
  6    
  7    -- the following work fine
  8    -- rc('/usr/bin/ps -ef');
  9    -- rc('/usr/bin/pwd');
 10    -- rc('/usr/bin/touch /tmp/t.txt');
 11    
 12    -- the following don't work 
 13    rc('/usr/bin/ps -ef | /usr/bin/grep oracle');
 14    rc('/usr/bin/pwd > /tmp/pwd.log');
 15    -- rc('/usr/bin/ksh -c "/usr/bin/pwd > /tmp/pwd.log"');
 16  end;
 17  /
run_cmd returned : 1   for /usr/bin/ps -ef | /usr/bin/grep oracle
/apps/oracle/product/8.1.7/dbs
run_cmd returned : 0   for /usr/bin/pwd > /tmp/pwd.log

PL/SQL procedure successfully completed.

4.) From Unix:
ls -ltr /tmp/pwd.log
/tmp/pwd.log: No such file or directory
 


Followup   November 30, 2001 - 8am Central time zone:

What I believe your issue is is that we wrote this tiny routine to run "A" program.  You are not 
running "A" program -- you are running a shell specific command.  This is like someone on windows 
trying to run "dir", "dir" is not a program -- its an internal command.  similarly, ps -ef | grep 
oracle is not a command -- its an internal command to your shell that says "start ps, redirect its 
stdout, start grep, redirect its stdin".

you would need to run a SHELL that understands "|" and ">", something like:

sh -c 'ps -ef | grep oracle'

BUT -- then you would need execute on /bin/sh, with that you can run ANY command as the user 
"oracle" (or who ever starts the database).  That would let you for example "sh -c rm -rf /*" and 
erase everything oracle is allowed to erase.  So, my real suggestion would be to create a script 
that has the commands you want to execute and you run THAT script from the database.  Give your 
self the permission to run that one command -- not /bin/sh

 

5 stars Tom, sorry for the mixup.   December 17, 2001 - 5am Central time zone
Reviewer: Henk-Jan Korpel from Veenendaal, the Netherlands
He Tom,

Sorry, for the mixup with Steve (Feuerstein, that is) whose stuff I was studying at that time. I 
just saw it today, hope this clears it. 

Regards
Henk-Jan 


4 stars "Java procedure for host calls on Unix environment", version 8.1.6   January 16, 2002 - 6pm Central time zone
Reviewer: Randy Bradley from Montgomery, AL USA
Tom,
I found this information to be very helpful. The step-by-step instructions were easy to follow. I 
have a question about using the ftp command instead of the ps command. When I run the ps command 
everything work fine, but when I run the ftp command ("/usr/bin/ftp -vin < /public/parfile.txt"), 
the procedure just hangs.

What's seems to be causing this problem. I did assign execute permissions via the dbms_java 
package.

One more thing... I'm running 8.1.7 (64-bit) on HP-UX 11.00 (64-bit). 


Followup   January 17, 2002 - 7am Central time zone:

ftp is waiting for the username and password to be entered and ftp refuses to read this from stdin 
as you are trying (i assume you have the username/password in the parfile.txt)

Do a man on netrc to see how to setup a .netrc (in the ORACLE account -- could be somewhat 
"dangerous").

A better approach might be to use some java classes that let you PROCEDURALLY do an ftp from java 
-- in that fashion, you can alleviate the inherit security issues with the .netrc file solution. 

3 stars special characters >, >>, |, < etc.   January 17, 2002 - 12pm Central time zone
Reviewer: A reader from ca, usa
I bet the above reader will need to do the FTP from a shell script if he wants to use '<'. I had a 
similar problem higher up in this thread.
 


Followup   January 17, 2002 - 1pm Central time zone:

Absolutely correct -- I didn't even read that far into the command -- that will be the next problem 
they hit. 

4 stars Java procedure for host calls on Unix environment", version 8.1.6   January 17, 2002 - 12pm Central time zone
Reviewer: Randy Bradley from Montgomery, AL USA
Your information about using .netrc worked to some degree. I woks when I run the ftp command from 
the unix prompt, but it still hangs when I attempt to execute from SQL*PLUS. I hope you can help me 
resolve yet another issue.

Thanks! 


Followup   January 17, 2002 - 2pm Central time zone:

See above... 

5 stars Java procedure for host calls on Unix environment", version 8.1.6   January 17, 2002 - 4pm Central time zone
Reviewer: Randy Bradley from Montgomery, AL USA
I created shell script and I execute the shell script from with the procedure. Thanks for all the 
help.

Randy 


3 stars Standard shell script...   January 17, 2002 - 6pm Central time zone
Reviewer: A reader from ca, usa
In my comments higher up I referred to writing the command to a file, doing a chmod +x etc. 
Obviously that's only if you don't know the command you want to run. Creating a standard ftp shell 
script with predefined input parms is better. Maybe the way you implemented it?? From what I can 
remember the DBMS_PIPE solution (see this site) doesn't have the special character limitation. Java 
solution just seems neater. 


5 stars 9i ?   February 7, 2002 - 7am Central time zone
Reviewer: Connor from UK
Apologies for my total lack of java knowledge (I'm getting there...), but your example (which 
worked fine in 8i) appears to bomb out under my 9i version.  Could you post if the same code works 
under one of your 9i versions?

SQL> variable x number;
SQL> set serveroutput on
SQL> exec dbms_java.set_output(100000);
SQL> exec :x := RUN_CMD('/usr/bin/ls');
java.lang.ArrayIndexOutOfBoundsException
at Util.RunThis(Util:14)

Cheers
Connor 


Followup   February 11, 2002 - 7am Central time zone:

I just removed the String array definition on the PL/SQL wrapper
function and the Java method. I've included all the code again (and an
example) below. I do not fully know why it worked in 8i.
My assumption is that the JVM-PL/SQL data type pickler may have
automatically promoted non-array types to arrays when required. Or 8i
was less exacting that in 9i.


ops$tkyte@ORA9I.WORLD> begin
  2    dbms_java.grant_permission
  3    ('RT_TEST',
  4     'java.io.FilePermission',
  5     '/usr/bin/ls',
  6     'execute');
  7  
  8    dbms_java.grant_permission
  9    ('RT_TEST',
 10     'java.lang.RuntimePermission',
 11     '*',
 12     'writeFileDescriptor' );
 13  end;
 14  /

PL/SQL procedure successfully completed.

ops$tkyte@ORA9I.WORLD> connect rt_test/rt_test
Connected.
ops$tkyte@ORA9I.WORLD> @login

rt_test@ORA9I.WORLD> create or replace and compile
  2  java source named "Util"
  3  as
  4  import java.io.*;
  5  import java.lang.*;
  6  
  7  public class Util extends Object
  8  {
  9    public static int RunThis(String args)
 10    {
 11    Runtime rt = Runtime.getRuntime();
 12    int        rc = -1;
 13  
 14    try
 15    {
 16       Process p = rt.exec(args);
 17  
 18       int bufSize = 4096;
 19       BufferedInputStream bis =
 20        new BufferedInputStream(p.getInputStream(), bufSize);
 21       int len;
 22       byte buffer[] = new byte[bufSize];
 23  
 24       // Echo back what the program spit out
 25       while ((len = bis.read(buffer, 0, bufSize)) != -1)
 26          System.out.write(buffer, 0, len);
 27  
 28       rc = p.waitFor();
 29    }
 30    catch (Exception e)
 31    {
 32       e.printStackTrace();
 33       rc = -1;
 34    }
 35    finally
 36    {
 37       return rc;
 38    }
 39    }
 40  }
 41  /

Java created.

rt_test@ORA9I.WORLD> create or replace
  2  function RUN_CMD(p_cmd in varchar2) return number
  3  as
  4  language java
  5  name 'Util.RunThis(java.lang.String) return integer';
  6  /

Function created.

rt_test@ORA9I.WORLD> create or replace procedure RC(p_cmd in varchar2)
  2  as
  3    x number;
  4  begin
  5    x := run_cmd(p_cmd);
  6  end;
  7  /

Procedure created.

rt_test@ORA9I.WORLD> variable x number;
rt_test@ORA9I.WORLD> set serveroutput on
rt_test@ORA9I.WORLD> exec dbms_java.set_output(100000);

PL/SQL procedure successfully completed.

rt_test@ORA9I.WORLD> exec :x := RUN_CMD('/usr/bin/ls /tmp');
10514.ksh
10565.sql
...
xxx.dat
xxx.dbf
zz

PL/SQL procedure successfully completed.

rt_test@ORA9I.WORLD> 

 

5 stars   March 4, 2002 - 6am Central time zone
Reviewer: A reader from italy


5 stars Any workaround on 8.1.5   April 29, 2002 - 4pm Central time zone
Reviewer: Senthil from Massachusetts, USA
Tom-

procedure dbms_java.grant_permission is available from 8.1.6. Is there any workaround available in 
8.1.5 to achieve the same functionality. I am using 8.1.5 on windows NT. It throws the following 
error if i try to assign permission to any user...

PLS-00302: component 'GRANT_PERMISSION' must be declared

thanks,
senthil 


Followup   April 29, 2002 - 9pm Central time zone:

There is JAVASYSPRIV (a role) you can grant but beware -- it is "all powerful".  The granular 
privilege model added in 816 and up is far superior.  Make sure to lock down this account so this 
role cannot be abused. 

5 stars I think this what I need   May 8, 2002 - 10am Central time zone
Reviewer: Adam Hapworth from ME USA
I am looking at making a Java-procedure like the ones you have shown to run a program on our Unix 
server.  The question I have is will I be able to have a user on a client machine run this 
java-procedure from a Form(4.5 now 6 coming) and get results back from the program on the server.  
I have seen a number of other news group posts regarding this with no answer and thought I would 
ask here where the experts are. 


Followup   May 8, 2002 - 12pm Central time zone:

The answer is simply "YES".  

The reason, all Java stored procedures are called through a wrapper, like this:

rt_test@DEV816> create or replace
  2  function RUN_CMD( p_cmd  in varchar2) return number
  3  as
  4  language java
  5  name 'Util.RunThis(java.lang.String[]) return integer';
  6  /

Function created.



that maps the java types to SQL types.  So, externally, it looks like PLSQL to the caller, but 
underneath, it is java. 

4 stars Java procedure for host calls on Unix environment   June 6, 2002 - 2pm Central time zone
Reviewer: Sandeep Lekhwani from CA, USA
Hi Tom,
Content proved to be very useful.
But, I am facing a problem.
The ksh I am calling from oracle using this utility, has some parameters. Now, some of the 
parameters contain the spaces. While running the ksh from unix we just put these parameters in 
double quotes. But, when calling from oracle, it identifies them as delimiters and hence treat as 
separate parameters. Is there a way that I can make it avoid the spaces which are inside double 
quotes. Or can I specify some other delim? Pls let me know. It's really urgent. 


Followup   June 6, 2002 - 5pm Central time zone:

We are not parsing anything -- I don't understand what you mean? We are just executing a string -- 
passing it to the command interpreter.

There undoubtably exists a more sophisticated java api as well that lets you set an array of 
parameters instead of just string -- you could look that up as well. 

3 stars help debugging, PLEASE :-)   June 19, 2002 - 2pm Central time zone
Reviewer: George Liblick from Chester Springs, PA USA
Tom,

I cut and past your solution, then modified the procedure
names and changed the grant_permission to /usr/ucb/ps because that is what I found through the 
which command
on my box (/usr/bin/ps appears to be identical anyway.)
But when I execute the command, I am getting an error that
I don't know where to begin debugging... 

SQL> exec cmd( 'ps -f' );
java.lang.ArrayIndexOutOfBoundsException
at MyCommand.RunThis(MYCOMMAND:14)

PL/SQL procedure successfully completed.

.. it works the same for /usr/ucb/ps ..

You have been a great help in the past - thanks - and I
hope you will help one more time. 


Followup   June 19, 2002 - 9pm Central time zone:

search this question from the top for ArrayIndexOutOfBoundsException and you'll see the fix for 9i. 

5 stars Thanks   June 20, 2002 - 12pm Central time zone
Reviewer: George from Chester Springs, PA USA
I hate when the answer implies I didn't do my home work :-(
Both yesterday and today I searched for ArrayIndexOutOfBoundsException throughout the archives, but 
the search failed to return anything... I never thought the
answer would be right under my nose :-(  I wonder why your site search failed to find this?

Anyway, it is working now and you have been most gracious - thanks. 


Followup   June 20, 2002 - 12pm Central time zone:

partly my fault.

My index is on the q&a.  Not the comments. 

I have to code a function in this style:

http://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:440419921146
in order to assemble the question, answer and all comments and responses into a clob and let 
intermedia index that!  Just haven't done it yet, will do it soon (bothers me too)



 

5 stars that why i like oracle .. u can do almost anything   August 21, 2002 - 9pm Central time zone
Reviewer: Nitin Gulati from Singapore
Hi tom,
I am facing a problem of similar type.
I need to change permission in few files which are made from utl_file though oracle onli. I think 
this solution will help me. But when i scearch dbms_java in all objects i cannot find there. Is 
there anything wrong in my oracle installation. When i scearh for dbms_java in 
/$oracle_HOME/rdbms/admin i cant find there also so how to load this ?
But no doubt the explanation is really good
cheers,
nitin
 


Followup   August 22, 2002 - 8am Central time zone:

If you do not have java installed, your DBA can install it via initjvm.sql found in 
$ORACLE_HOME/javavm/install 

4 stars great response, but...   October 10, 2002 - 6pm Central time zone
Reviewer: craig from Lowell, AR USA
Tom - 

Your examples work great, but I'm having some trouble running my particular command using your 
script.

I'm trying to use scp to move files from the database to another box.  I can run this from the 
shell a-ok, but when run via your class, it returns a 1 (failure) every time. Indeed, the file does 
not exist in the new location when it is all said and done.  Can you help me out?

Again, the following works from the shell on the db box:
/usr/bin/scp /u01/home/cnelson/flat_files/CSV2.txt cnelson@pspdwhp1:/u01/home/cnelson/CSV2.txt

Thanks again for your sage advice. 


Followup   October 11, 2002 - 8pm Central time zone:

Well, you ran that script as YOU (cnelson) where as the java ran as ORACLE

different user
different environment
different everything


suggestion:

a) log in as Oracle and test this scp, make sure Oracle can run it (permissions)

b) start out with a script /tmp called "test.sh"

In there put in a call to 

/usr/bin/env


and make sure the environment is OK (paths and everything else are totally differnet)

Then add the call to /usr/bin/scp in there (eg: incrementally add in things -- try to figure out 
where it is going awry) 

4 stars Very Useful - How about returning output greater than 32K?   November 8, 2002 - 6pm Central time zone
Reviewer: Greg DelVecchio from So. California
I managed to alter your example so that it returns the command line output as a varchar2.  However, 
some of my commands output more than 32K of data.  Is there a way to pass more than 32K of data 
from Java to PL/SQL?  Could you pass the command line output as a CLOB or break it into a varray?  
Thanks for any suggestions you might have.

(NOTE: For others that may try this in 8.1.7.  There is a bug (#1322857) that limits the string 
length that may be returned by a java stored function to 4K.  If you write it as a java stored 
procedure you may pass a string up to 32K in length) 


Followup   November 8, 2002 - 9pm Central time zone:

You'll have to use a CLOB  - the caller could allocate a temporary clob and the java could write to 
it. 

5 stars Problem when passing string parameters with lots of white spaces   November 20, 2002 - 5am Central time zone
Reviewer: Mahomed Suria from U.K
I am running a unix script exec_cmd.sh using rc.exec as per your example. The script is simply
#!/bin/sh
$@
#finish

When a send several parameters including one that is a string with lots of white spaces , the 
string is being treated as several parameters rather than just one, even when I hav enclosed the 
string in double qoutes.

 rc ('/usr/users/cdb_env/exe/exec_cmd.sh /usr/users/cdb_env/exe/
qsnd 1 triggr yrdman 1 "+000000001+000000001+000000001DC1  DL1  steve          PC" ' )

When I list the parameters that exec_cmd.sh is receiving  I get the following :
/usr/users/cdb_env/exe/qsnd
1
triggr
yrdman
1
"+000000001+000000001+000000001DC1
DL1
steve
PC"

It seems like the quoted string is being split into several parameters. I want the string to be a 
single parameter.

Can you help? I do not know what the problem is?


 


Followup   November 21, 2002 - 12pm Central time zone:

You'll have to read up on java -- the answer would lie there.  You could use a lower level java api 
then the rather simple one i have here (no, I don't know the name or even if it exists)

As a workable workaround -- suggest you pass a single string for that parameter using an _ where 
you have whitespace and then using sed to remove it.  EG:

$ cat /tmp/test.sh

#!/bin/sh

/usr/bin/echo '$1 = ' $1
X="`echo $1 | sed 's/_/ /g'`"
echo '$X = ' $X
/usr/bin/echo ---------------



and then:

rt_test@ORA817DEV.US.ORACLE.COM> exec rc('/tmp/test.sh a_b ' )
$1 =  a_b
$X =  a b
---------------
return code = 0 from /tmp/test.sh a_b


so, your script would use $X instead of $1 or you could just use

  `echo $1 | sed s/_/ /g`

in your script where currently you just have $1
 

3 stars Calling OS command using Java procedure in PL/SQL generates NON-EXISTANT PROCESS on NT   December 19, 2002 - 11am Central time zone
Reviewer: Alain Labonte from Quebec - Canada
Hi, i use a java procedure mostly similar to this one, but when the command is terminated, a 
NON-EXISTANT PROCESS stays on the server (NT 4.0).  Those processes seem to take some memory.  So 
when i execute many jobs, they take a lot of memory and slow down my server.  When i stop my 
database, they disapear, but i can't stop my database at anytime.

Do you have any idea of what might causes that? 


Followup   December 19, 2002 - 12pm Central time zone:

I don't know what a "non existant process on nt" means.   

4 stars need to run a script   January 7, 2003 - 1am Central time zone
Reviewer: tong siew pui from singapore
The info is very useful. Many thanks.
I am able to follow the example and get the results as stated.

But what I needed is to run a unix script (with different unix commands), instead of a unix 
command.

I have a script 'tsp1.txt' in
    /u01/home/sinvb/tong

tsp1.txt
--------
ls -la


when I run
SQL> exec rc('/u01/home/sinvb/tong/tsp1.txt');
PL/SQL procedure successfully completed.

but the files are not listed.

when I run the command
'tsp1.txt' at '/u01/home/sinvb/tong'
the files get listed.

I tried different alternative
1) modified tsp1.txt to
    sh -c 'ls -la'
2) copy the file tsp1.txt to /usr/bin
   and 
    exec rc('/usr/bin/tsp1.txt');
both show the same result
PL/SQL procedure successfully completed.

pls adv what is the pbm and what must I do.
the ultimate aim is to prepare tsp1.txt as
a unix script which contains various unix command.

thanks for your help in advance.

i also noticed that if i run
exec rc('/usr/bin/ps')
nothing is displayed.

but i got results if i run
exec rc('/usr/bin/ps -ef');

but if i execute the command 'ps',
i get something displayed.
is there a reason why ???


 
 


Followup   January 7, 2003 - 6am Central time zone:

time for you to do a little debugging eh?

did you check the permissions?  can ORACLE run your script?  is the r-x flag on the entire path to 
this file? is ls in the rarified environment these scripts run in?  what is the path?  did you put 
some 

/usr/bin/echo $PATH > /tmp/$$.debug

type statements in there?
is the script getting run at all?

did you read the "great response, but... " comment above and do what I suggested there?

....... 

3 stars   January 9, 2003 - 5am Central time zone
Reviewer: Stephan from Netherlands
Try to execute the following:

exec rc('/usr/bin/sh /u01/home/sinvb/tong/tsp1.txt');

Note the sh command to open a shell and your script as 'parameter'. Be sure you have execute 
permissions for sh (with dbms_java.grant_permission).

This should output the desired result.
 


Followup   January 9, 2003 - 7am Central time zone:

as I said above however -- that would be a really bad idea.

you have to give privs on sh

exec rc( '/usr/bin/sh rm -rf /u01/apps/oracle/oradata/your_sid/*' )

is as easy to execute as tsp1.txt would be!  caveat emptor. 

1 stars Using Java   January 16, 2003 - 12am Central time zone
Reviewer: Abdal-Rahman Agha from Yemen
Hi Tom,
- Sorry, I am interesting to use Java in Oracle, can you advice on a book or any good place to 
learn about Oracle Java quickly?
- I have Win2k, Oracle9 R2: Please, explain this output:

SQL> exec rc('E:\WINNT\command.* /c dir');
java.lang.ArrayIndexOutOfBoundsException
at Util.RunThis(Util.java:14)

PL/SQL procedure successfully completed. 


Followup   January 16, 2003 - 8am Central time zone:

that error just means you got really excited -- stopped reading the article and went to play with 
it!  read on -- ctl-f for ArrayIndexOutOfBoundsException and you'll see the cause.

you might be interested in
http://www.amazon.com/exec/obidos/ASIN/1861006020/
 

5 stars Is it possible to call os comand of another server   January 18, 2003 - 2am Central time zone
Reviewer: Reader from UAE
Hi Tom

This is excellent piece of Code.

i have one clarification.  Is it possible to call a particular command in other unix server.

Ie My oracle DB is in Unix server A
My ETL tool is running in Unix server B
I want to call the ETL Process as Commandline from Java procedure.  Will it need to login into 
Server B. If so How to do it. 


Followup   January 18, 2003 - 9am Central time zone:

if you can do it from sever A on the command line (outside of oracle), we can do it inside the 
database.

Solve that problem and we'll go from there.  Oracle cannot bypass the OS and do magical things 
beyond what you've set up at the OS level.

We can use C based extprocs in 9i to do this as the extproc is allowed to run on another machine 
all together.  but basically, you would need an agent on server b one way or another. 

3 stars error on excuting java   February 3, 2003 - 12am Central time zone
Reviewer: Nikunj 
hi tom,

i have oracle ee 8.1.7 on windows nt 4.0 with service pack 6a. i want to execute host command from 
database.

so i follow ur steps as below.

SQL> CONNECT SYSTEM@BABUL
Enter password: *******
Connected.
SQL> begin
  2  dbms_java.grant_permission
  3  ('SCOTT',
  4  'java.io.FilePermission',
  5  'C:\WINNT',
  6  'execute');
  7  
  8  dbms_java.grant_permission
  9  ('SCOTT',
 10  'java.lang.RuntimePermission',
 11  '*',
 12  'writeFileDescriptor' );
 13  end;
 14  /

PL/SQL procedure successfully completed.

SQL> connect scott@babul
Enter password: *****
Connected.
SQL> 
SQL> create or replace and compile
  2  java source named "Util"
  3  as
  4  import java.io.*;
java source named "Util"
                  *
ERROR at line 2:
ORA-29536: badly formed source: Encountered "<EOF>" at line 1, column 17.

Was expecting:

";" ...

why i am geting this error.

thanks nikunj 


Followup   February 3, 2003 - 7am Central time zone:

what version of sqlplus do you have.

This:

ops$tkyte@ORA817DEV> create or replace and compile
  2  java source named "Util"
  3  as
  4  import java.io.*;
java source named "Util"
                  *
ERROR at line 2:
ORA-29536: badly formed source: Encountered "<EOF>" at line 1, column 17.
Was expecting:
";" ...



is what I get when I use 8.0 sqlplus which didn't understand "java source".  It just sucked the 
code upto the first ';' and submitted it (since sqlplus didn't know back then that java source 

a) existed
b) could contain ';' like plsql can


suggest you get your client software updated. 

5 stars Java Permisson   February 25, 2003 - 2pm Central time zone
Reviewer: Steve from NYC, USA
Hi Tom,

I just tried the answer here but I got the following messssage. What should I do? Thanks!  --steve

SQL> call testjava.run_cmd('ls') into :y;
java.security.AccessControlException: the Permission (java.io.FilePermission <<ALL FILES>> execute)
has not been granted by dbms_java.grant_permission to
SchemaProtectionDomain(SRS|PolicyTableProxy(SRS))
at java.security.AccessControlContext.checkPermission(AccessControlContext.java)
at java.security.AccessController.checkPermission(AccessController.java)
at java.lang.SecurityManager.checkPermission(SecurityManager.java)
at oracle.aurora.rdbms.SecurityManagerImpl.checkPermission(SecurityManagerImpl.java)
at java.lang.SecurityManager.checkExec(SecurityManager.java)
at java.lang.Runtime.exec(Runtime.java)
at java.lang.Runtime.exec(Runtime.java)
at java.lang.Runtime.exec(Runtime.java)
at Util.RunThis(Util:13)

Call completed.
 


Followup   February 25, 2003 - 8pm Central time zone:

did you use dbms_java grant permission to grant yourself the needed privs?  like my example does?

 

4 stars Why it is not able to run java class   March 13, 2003 - 7am Central time zone
Reviewer: Umesh Nimbalkar from Mumbai, India
Dear Tom, 
     I want to run class placed in one directory. For this i am giving permissions as follows

begin
        dbms_java.grant_permission
        ('SALES',
         'java.io.FilePermission',
         '/usr/java130/jre/bin/java',
         'execute');
    
        dbms_java.grant_permission
        ('SALES',
        'java.lang.RuntimePermission',
        '*',
        'writeFileDescriptor' );
   end;
/

now when i am trying to execute as below
exec rc('/usr/java130/jre/bin/java -version');

it is not giving any output. but if i run like
exec rc('/usr/java130/jre/bin/java'); 
it is iving output.
Pls let me know why it is not accepting parameters. 


Followup   March 14, 2003 - 5pm Central time zone:

maybe the -version is writing to stderr.  mine does:

$ java -version > xxx
java version "1.3.1_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_02-b02)
Java HotSpot(TM) Client VM (build 1.3.1_02-b02, mixed mode)


I only caught stdout.

 

4 stars Oracle Application Developer   March 19, 2003 - 2pm Central time zone
Reviewer: Dawar from CA USA
Is there a way to call unix command in oracle programs/ packages?


Dawar 


Followup   March 19, 2003 - 3pm Central time zone:

umm, you mean like this:

rt_test@DEV816> exec rc('/usr/bin/ps -ef');
UID   PID  PPID  C    STIME TTY      TIME CMD
root     0     0  0   Aug 17 ?        0:06 sched
root     1     0  0   Aug 17 ?        1:19 /etc/init -
root     2     0  0   Aug 17 ?        0:23 pageout
.....

PL/SQL procedure successfully completed.



which is the example from above??? 

4 stars Having small problem   April 24, 2003 - 12pm Central time zone
Reviewer: Rob from Chicago, USA
I was able to run your example ps -ef with no problem.

I create a simple shell script on UNIX to copy a file rfk.scr:
cp /apps/actappl/rfk.test /apps/actappl/rfk.test2

I can run this with no problem using the Oracle account on UNIX.

When I try to run it using the Java callout nothing happens, no errors no copy.

DECLARE
t NUMBER(9);
BEGIN

t := act_dw_sys_events.run_cmd('/apps/actappl/rfk.scr');
END;

Any suggestions?

Thanks Rob 


Followup   April 24, 2003 - 12pm Central time zone:

scripts can be tricky.

did you grant on it.
is is executable by the oracle software owner.
is the path to it traversable by the oracle software owner.
can the oracle software owner write to that directory.
can it read that file.
what was the return code.

look for (cnelson) on this page (had the same issue).  ideas are there as well. 

4 stars interesting response but do not answer to my problem   April 24, 2003 - 4pm Central time zone
Reviewer: Rene Paradis from Canada,Quebec
I want to execute a second perl script into the perl script called by the Java procedure like:
system("/path/perl_script.pl argv");
But 
But the java grant permissions seem to allow only the first perl script to be executed and this one 
ends when the system command is called.
here is the granted permissions
 begin
           dbms_java.grant_permission
           ('SUPER_MAN',
            'java.io.FilePermission',
            '/path/first_script.pl',
            'execute,read ,wrtie');
       
           dbms_java.grant_permission
           ('SUPER_MAN',
           'java.lang.RuntimePermission',
           '*',
           'writeFileDescriptor' );
      end;
      /
 begin
           dbms_java.grant_permission
           ('SUPER_MAN',
            'java.io.FilePermission',
            '/path/second_script.pl',
            'execute,read ,wrtie');
       
           dbms_java.grant_permission
           ('SUPER_MAN',
           'java.lang.RuntimePermission',
           '*',
           'writeFileDescriptor' );
      end;
      /
if it is not possible to call a second perl script inside the first one, I planned to call it 
separatly:
declare
      x number;
    begin
      x := run_cmd('/path/first_script.pl argv');
      x := run_cmd('/path/second_script.pl argv');
    end;
    / 


Followup   April 24, 2003 - 6pm Central time zone:

I missing your point?

if first_script.pl calls second_script.pl -- you need not grant on it (the Oracle JVM has *no clue* 
what first script might do, and it is allowed to do anything it wants really as far as running 
other commands go)


if first_script.pl doesn't call second_script.pl, but you want to -- you just need to grant on it.


So, I'm not understanding what you are saying here.   

5 stars excellent   April 25, 2003 - 10am Central time zone
Reviewer: A reader 


2 stars did not solve my problem (first and second perl script)   April 25, 2003 - 11am Central time zone
Reviewer: Rene Paradis from Canada, Quebec
Hi again Tom, 
here is my part of code inside the first perl script that calls the second perl script:
...
$fichier = shift @ARGV;
print("test1 tahaa/mascot/data/make_input_txt.pl $fichier\n");
#we build a txt file here
$x = system("/tahaa/mascot/data/make_input_txt.pl $fichier");
print("x value is $x\n");
...

the dbms.output would be:
test1 /seq/murin/proteo/make_input_txt.pl /tahaa/mascot/data/20030327/F006236.dat

PL/SQL procedure successfully completed.

The x value is not printed. but when I execute the command manually 
(/seq/murin/proteo/make_input_txt.pl /tahaa/mascot/data/20030327/F006236.dat), the script works. So 
it really seems that the first script cannot execute the system command, altough it does when it is 
executed manually. What should I do to make it work?
thank you very much for your help

 


Followup   April 25, 2003 - 3pm Central time zone:

this looks like a classic PERMISSION problem at the OS level.

put some debug in.  remember -- as coded, this catches ONLY stdout -- you might want yet another 
wrapper -- a script that runs perl1 (which runs perl2) but redirects stderr to stdout so you can 
see it.

UNDOUBTABLY perl is pumping out an error to stderr and you just haven't seen it yet.

 

4 stars   May 7, 2003 - 6pm Central time zone
Reviewer: dk 
Hi Tom,

I am a dveloper.
When I try to creat a java stored procedure in database, I met the following message, what happend 
? What requirement I need 
to ask DBA?

Thanks!

DLIV>create or replace and compile
  2  java source named "Util"
  3  as
  4     import java.io.*;
java source named "Util"
                  *
ERROR at line 2:
ORA-29547: Java system class not available: oracle/aurora/rdbms/Compiler
 


Followup   May 8, 2003 - 9am Central time zone:

search for

ORA-29547

on this site 

4 stars It almost works perfectly   May 15, 2003 - 10am Central time zone
Reviewer: Mark from USA
Tom,

I will appologize in advance because I think this might go a bit beyond the scope of the original 
question.

I modified your code to work on Windows and after some dumb mistakes on my part I can now execute 
commands at will from Oracle 9i stored procedures.

Thanks

There is one problem though that I have not been able to resolve yet.  When I execute a batch file 
and that batch file then executes another program (not internal command) I get no output.  It's 
like standard out has been redirected to the bit bucket.  If I execute an internal command like 
'dir' or 'set' I get the output in the stored procedure.  I can also redirect that output to a file 
from within the batch file called from the stored procedure.  But when I execute an external 
program, for example a "Hello World" java program or grep (windows version) to get some text, there 
is no output.  The ERRORLEVEL indicates the program ran.

Any ideas what could be going on here? 


Followup   May 15, 2003 - 5pm Central time zone:

windows isn't unix and concepts like stdin, stderr, stdout are so foriegn to it.

they do not all share the same "tty" if you will.  don't know what to tell you other then use 
redirection and then "type" the output. 

4 stars Can't get permissions to set up correctly..   May 16, 2003 - 1pm Central time zone
Reviewer: Mahomed from U.K
Oracle9i Release 9.2.0.1.0 - Production
JServer Release 9.2.0.1.0 - Production

SQL> connect / as sysdba

begin

   dbms_java.grant_permission
      ('CDB_TRAIN',
      'java.io.FilePermission',
      '/data4/cdb_train/exe/exec_cmd',
      'execute');

   dbms_java.grant_permission
      ('CDB_TRAIN',
       'java.lang.RuntimePermission',
       '*',
       'writeFileDescriptor');
 end;
/
PL/SQL procedure successfully completed.

exec dbms_java.grant_permission( 
'CDB_TRAIN','SYS:java.io.FilePermission','/usr/cdb_train/exe/exec_cmd', 'execute' );

PL/SQL procedure successfully completed.


exec :x := pkg_utils.sp_cmd('test',3,'/data4/cdb_train/exe/db_locks');
java.security.AccessControlException: the Permission (java.io.FilePermission
/usr/cdb_train/exe/exec_cmd execute) has not been granted to CDB_TRAIN. The
PL/SQL to grant this is dbms_java.grant_permission( 'CDB_TRAIN',
'SYS:java.io.FilePermission', '/usr/c
db_train/exe/exec_cmd', 'execute' )
at java.security.AccessControlContext.checkPermission(AccessControlContext.java)
at java.security.AccessController.checkPermission(AccessController.java)
at java.lang.SecurityManager.checkPermission(SecurityManager.java)
at
oracle.aurora.rdbms.SecurityManagerImpl.checkPermission(SecurityManagerImpl.java
)
at java.lang.SecurityManager.checkExec(SecurityManager.java)
at java.lang.Runtime.exec(Runtime.java)
at java.lang.Runtime.exec(Runtime.java)
at java.lang.Runtime.exec(Runtime.java)
at java.lang.Runtime.exec(Runtime.java)
at MyCommand.RunThis(MyCommand.java:14)

PL/SQL procedure successfully completed. 


Followup   May 16, 2003 - 5pm Central time zone:

so show us a TRUE cut and paste, nothing doctored as above. 

5 stars Another compile problem...   May 18, 2003 - 2pm Central time zone
Reviewer: Jack Wells from Fort Lauderdale, FL USA
Tom,
I'm getting the following error when I try to create the Util Java source:

SQL> sho err
Errors for JAVA SOURCE Util:

LINE/COL ERROR
-------- -----------------------------------------------------------------
0/0      Util:4: Superclass object of class Util not found.
0/0      Info: 1 errors
SQL> 

I get the same error on an 8.1.7.4 HP/UX instance, a Linux 9.2.0.3 instance and a 9.2.0.1 Windows 
instance.  Running the dbms_java.grant_permission, however, works fine on all three.  What is the 
"superclass object" of Util?  Is it one of the two imports just above the Util class declaration? 


Followup   May 18, 2003 - 2pm Central time zone:

hows about the entire example -- never saw that myself. 

5 stars Another compile problem (full example)...   May 18, 2003 - 4pm Central time zone
Reviewer: Jack Wells from Fort Lauderdale, FL USA
Tom,
Here is the whole example:

SQL> connect sys@ncgd
Enter password: *****
Connected.
SQL> select version from v_$instance;

VERSION
-----------------
8.1.7.4.0

1 row selected.

SQL> CREATE OR REPLACE AND COMPILE
  2      JAVA SOURCE NAMED "Util"
  3     AS
  4      import java.io.*;
  5      import java.lang.*;
  6      
  7      public class Util extends object
  8      {
  9        public static int runthis(string args)
 10       {
 11       runtime rt = runtime.getruntime();
 12       int        rc = -1;
 13     
 14       try
 15       {
 16          process p = rt.exec(args);
 17     
 18          int bufsize = 4096;
 19          bufferedinputstream bis =
 20           new bufferedinputstream(p.getinputstream(), bufsize);
 21          int len;
 22          byte buffer[] = new byte[bufsize];
 23     
 24          // echo back what the program spit out
 25          while ((len = bis.read(buffer, 0, bufsize)) != -1)
 26             system.out.write(buffer, 0, len);
 27     
 28          rc = p.waitfor();
 29       }
 30       catch (exception e)
 31       {
 32          e.printstacktrace();
 33          rc = -1;
 34       }
 35       finally
 36       {
 37          return rc;
 38       }
 39       }
 40     }
 41  /

Warning: Java created with compilation errors.

SQL> sho err
Errors for JAVA SOURCE Util:

LINE/COL ERROR
-------- -----------------------------------------------------------------
0/0      Util:4: Superclass object of class Util not found.
0/0      Info: 1 errors
SQL> 

 


Followup   May 18, 2003 - 6pm Central time zone:

object

should be

Object


initcap, java is case sensitive.


rt_test@DEV816> create or replace and compile
  2  java source named "Util"
  3  as
  4  import java.io.*;
  5  import java.lang.*;
  6  
  7  public class Util extends Object
  8  {
  9   

5 stars Duh...   May 19, 2003 - 1am Central time zone
Reviewer: Jack Wells from Fort Lauderdale, FL USA
Oh.

After correcting that faux pax, there were a few other "spelling" mistakes I needed to correct...  
works like a charm now!

p.s. Note to self: don't use PL/Formatter on Java code! 


5 stars Got an error   May 19, 2003 - 4pm Central time zone
Reviewer: A reader 
I copied the same code but got an error

SQL> exec rc('/usr/bin/ps -ef');
java.lang.ArrayIndexOutOfBoundsException
at Util.RunThis(UTIL.java:14)

What is problem? 


4 stars What are the pre-requisites to run this?   June 10, 2003 - 3pm Central time zone
Reviewer: Emelyn from Hayward, CA
In order to run your Java program, do I need to add entries to listener.ora and tnsnames.ora or any 
preparation or set-up to be done?
I'm running version 8.1.5.
Thanks in advance! 


Followup   June 10, 2003 - 3pm Central time zone:

just have java installed in the database. 

4 stars What are the pre-requisites to run this?   June 10, 2003 - 6pm Central time zone
Reviewer: Emelyn from Hayward, CA
Here's what I got when I ran sql*plus:

SQL*Plus: Release 8.0.5.0.0 - Production on Tue Jun 10 14:52:27 2003

(c) Copyright 1998 Oracle Corporation.  All rights reserved.


Connected to:
Oracle8i Enterprise Edition Release 8.1.5.0.0 - Production
With the Partitioning and Java options
PL/SQL Release 8.1.5.0.0 - Production

With the phrase: With the Partitioning and Java options
Does it mean, Java is installed?
 


Followup   June 10, 2003 - 8pm Central time zone:

yes.

you'll have problems creating java with the 805 sqlplus client however -- sqlplus "parses" 
statements before submitting them.  it won't recognize 'create or replace java ....' and will most 
likely "barf" 

3 stars Some points regarding to pass parameters to your shell   June 11, 2003 - 12pm Central time zone
Reviewer: Erdal from Seattle
I have been using the Java Stored Procedures a lot to replace the Pro*C Codes and all the other 
workarounds we did in the past to execute a command on the operating system (mostly UNIX).
There's a very good article here
http://www.mountainstorm.com/publications/javazine.html
It helped me a lot for passing parameters to UNIX Shell.
{"/bin/sh", "-c", "Your Command") format has no surprises when executing anything on UNIX.  


Followup   June 11, 2003 - 7pm Central time zone:

unless of course, someone gives you 

"rm -rf /usr/oracle/oradata"
  

to run.  /bin/sh would not be something I would want "open" to run.  

/bin/ps, sure
/bin/sh (run anything you like), not so sure I'd like that. 

4 stars about username for dbms_java.grant_permission   June 18, 2003 - 5pm Central time zone
Reviewer: Jianhui from DC
The username must be uppercase or it will report user or role doesnt exist error. This may need to 
be improved since pl/sql is not case sensitive traditionally. 


5 stars Issue with 9i   June 19, 2003 - 8am Central time zone
Reviewer: Steve from UK
Hi Tom

I've successfully run this in 8.1.7 and have put your amended code into 9.0.1.4 but get an error.  
Could you glance at it and tell me where I've gone wrong please?

ltop_owner@EU0084P> conn sys/eu0084psys@eu0084p as sysdba
Connected.
ltop_owner@EU0084P> ed
Wrote file afiedt.buf

  1  begin
  2        dbms_java.grant_permission
  3        ('LTOP_OWNER',
  4         'java.io.FilePermission',
  5         'e:\orant_eu0084p\scripts\bandvisit.bat',
  6         'execute');
  7        dbms_java.grant_permission
  8        ('LTOP_OWNER',
  9        'java.lang.RuntimePermission',
 10        '*',
 11        'writeFileDescriptor' );
 12*    end;
ltop_owner@EU0084P> /

PL/SQL procedure successfully completed.

ltop_owner@EU0084P> conn ltop_owner/prodltop@eu0084p
Connected.
ltop_owner@EU0084P> ed
Wrote file afiedt.buf

  1  create or replace and compile
  2     java source named "Util"
  3     as
  4     import java.io.*;
  5     import java.lang.*;
  6     public class Util extends Object
  7     {
  8       public static int RunThis(String args)
  9       {
 10       Runtime rt = Runtime.getRuntime();
 11       int        rc = -1;
 12       try
 13       {
 14          Process p = rt.exec(args);
 15          int bufSize = 4096;
 16          BufferedInputStream bis =
 17           new BufferedInputStream(p.getInputStream(), bufSize);
 18          int len;
 19          byte buffer[] = new byte[bufSize];
 20          // Echo back what the program spit out
 21          while ((len = bis.read(buffer, 0, bufSize)) != -1)
 22             System.out.write(buffer, 0, len);
 23          rc = p.waitFor();
 24       }
 25       catch (Exception e)
 26       {
 27          e.printStackTrace();
 28          rc = -1;
 29       }
 30       finally
 31       {
 32          return rc;
 33       }
 34       }
 35*    }
 36  /

Java created.

ltop_owner@EU0084P> ed
Wrote file afiedt.buf

  1  create or replace
  2      function RUN_CMD(p_cmd in varchar2) return number
  3      as
  4      language java
  5*     name 'Util.RunThis(java.lang.String) return integer';
ltop_owner@EU0084P> /

Function created.

ltop_owner@EU0084P> ed
Wrote file afiedt.buf

  1  create or replace procedure RC(p_cmd in varchar2)
  2      as
  3        x number;
  4      begin
  5        x := run_cmd(p_cmd);
  6*     end;
  7  /

Procedure created.

ltop_owner@EU0084P> conn ltop_owner/prodltop@eu0084p
Connected.
ltop_owner@EU0084P> variable x number
ltop_owner@EU0084P> set serveroutput on
ltop_owner@EU0084P> exec dbms_java.set_output(100000);

PL/SQL procedure successfully completed.

ltop_owner@EU0084P> exec :x := RUN_CMD('/usr/bin/ls /tmp');
java.io.IOException: The handle is invalid.
at oracle.aurora.java.lang.OracleProcess.create(OracleProcess.java)
at oracle.aurora.java.lang.OracleProcess.construct(OracleProcess.java)
at java.lang.Runtime.execInternal(Runtime.java)
at java.lang.Runtime.exec(Runtime.java)
at java.lang.Runtime.exec(Runtime.java)
at java.lang.Runtime.exec(Runtime.java)
at Util.RunThis(Util:11)

PL/SQL procedure successfully completed.

ltop_owner@EU0084P> 


Followup   June 19, 2003 - 8am Central time zone:

you seem to be on windows (e:\ ...)

but you seem to be trying to use the power of unix (/usr/bin/ls...) ???

 

5 stars Oops....just checking you were awake!!   June 19, 2003 - 8am Central time zone
Reviewer: steve from UK
Hide my shame!!!!  I'll just wait for the ground to open up and swallow me!

Yes the server is on Windoze and if I run the correct command it runs as it should.  The power of 
cut 'n paste!!!

"The DBA formerly known as Steve." 


5 stars OS Output   June 21, 2003 - 2am Central time zone
Reviewer: Jack Wells from Boca Raton, FL
Tom,

I'm having trouble passing the OS output back in a parameter to the calling PL/SQL binding 
function.  I'd like to do this rather than rely on the dbms_output approach.  I've added the 
following to the function call (per your instruction in your book):

      public static int RunOsCmd(java.lang.String OsCmdLine,
                                 java.lang.String[] CmdOutput)

Now I need to get the routine to stuff its output in the "CmdOutput" parameter.  How would I do 
this? 


Followup   June 21, 2003 - 10am Central time zone:

you'll have to write a little java to concatenate the output instead of using system.out to write 
it "on screen" and then assign that to CmdOutput[0] before you return. 

5 stars How to concatenate output   June 21, 2003 - 6pm Central time zone
Reviewer: Jack Wells from Boca Raton, FL
Tom,

Here is my PL/SQL binding code and Java code and output from running the program.  I can't seem to 
get the output in the return variable.  As I'm not a Java dude, I suspect I'm not concatenating 
correctly or not handling the "buffer" variable correctly.  What is the problem?

  FUNCTION run_command_java (
    fv_command   IN   VARCHAR2,
    fv_output    OUT  VARCHAR2
  )
    RETURN NUMBER
  AS
    LANGUAGE JAVA
    NAME 'NcgOSj.runOsCmd( java.lang.String,
                           java.lang.String[] ) return integer';

  PROCEDURE run_command_java (
    fv_command   IN       VARCHAR2,
    fv_output    OUT      VARCHAR2
  )
  IS
    ln_return_code   NUMBER;
  BEGIN
    ln_return_code    := run_command_java (fv_command, fv_output);
  END run_command_java;

CREATE OR REPLACE AND COMPILE
    JAVA SOURCE NAMED "NcgOSj"
   AS
    import java.io.*;
    import java.lang.*;
    
    public class NcgOSj extends Object
    {
      public static int runOsCmd(String OsCmdLine,
                                 String[] CmdOutput)
     {
     Runtime rt = Runtime.getRuntime();
     int     rc = -1;
     String  coutput = "";

     if (OsCmdLine.length() < 1) {
         System.out.println("USAGE: java NcgOSj.runOsCmd \'cmd\' OutputStringVariable");
         System.exit(1);
     } 
     try
     {
        // The exec() method in java.lang.Runtime is overloaded and
        // can be called in different forms.  The following use illustrates
        // the simplest form of exec() which takes a string as a parameter.
        //
        // Execute the command using the Runtime object variable 'rt' and
        // get the process 'p' which controls this command
        Process p = rt.exec(OsCmdLine);
   
        int bufSize = 4096;
        BufferedInputStream bis =
         new BufferedInputStream(p.getInputStream(), bufSize);
        int len;
        byte buffer[] = new byte[bufSize];
   
        // Echo back what the program spit out
        while ((len = bis.read(buffer, 0, bufSize)) != -1) {
           System.out.write(buffer, 0, len);
           coutput = coutput + buffer;
        }
        // Wait for the process 'p' to finish and get the return code
        // from the process 
        rc = p.waitFor();
     }
     catch (Exception e)
     {
        e.printStackTrace();
        rc = -1;
     }
     finally
     {
        CmdOutput[0] = coutput;
        return rc;
     }
     }
   }
/

VARIABLE outpt VARCHAR2(2000)
SET serveroutput on
EXEC dbms_java.set_output(100000);
EXEC run_command_java ('/bin/ls /', :outpt);
bin
boot
dev
etc
home
initrd
lib
lost+found
misc
mnt
ncg01
ncg02
ncg03
ncg04
ncglx01
ncglx01_cp.log
ncglx01_cp.sh
ncglx01_mount.sh
nohup.out
opt
proc
root
sbin
tmp
tmpdir
usr
var

PL/SQL procedure successfully completed.

PRINT outpt

OUTPT
-----------------------------------------------------------
[B@e8955a6a

 


Followup   June 21, 2003 - 6pm Central time zone:

we will have to hope a java dude comes along.   

5 stars Convert...   June 22, 2003 - 1pm Central time zone
Reviewer: Kamal Kishore from New Jersey, USA
The byte array needs to be converted to a String before assigning to the OUT variable.
The while (read...) loop needs to be changed to the following:

        // Echo back what the program spit out
        while ((len = bis.read(buffer, 0, bufSize)) != -1) {
           System.out.write(buffer, 0, len);
           ot = new String(buffer, 0, len) ;
           coutput = coutput + ot ;
        }

Where "ot" is a String variable declared in the program above like this:


     Runtime rt = Runtime.getRuntime();
     int     rc = -1;
     String  coutput = " ";
     String  ot = " " ;


This seems to work when run on my system.
 


Followup   June 22, 2003 - 4pm Central time zone:

Thanks, appreciate that... 

5 stars Works like a charm!   June 22, 2003 - 4pm Central time zone
Reviewer: Jack Wells from Boca Raton, FL
Thanks Kamal!  Made those changes and it works just as expected.

Tell me, do you know how I could just convert the byte array variable "buffer" to a string inline 
instead of declaring the new variable "ot"?  Something like:

   // capture the output in a string variable
   while ((len = bis.read(buffer, 0, bufSize)) != -1) {
      coutput = coutput + toString (buffer, 0, len);
   }

Wouldn't this use up less memory than allocating "new" memory for each iteration for the "ot" 
variable? 


5 stars Hangs on sendmail   June 23, 2003 - 8pm Central time zone
Reviewer: Jack Wells from Boca Raton, FL
Tom,

Do you have any idea why the program above would hang on a call to sendmail?  As long as I have 
done the dbms_java.grant_permission, the program works fine for /bin/ls, /bin/rm, etc., but when I 
issue the following command from SQL*Plus, it just hangs:

EXEC run_command_java (/usr/sbin/sendmail jwells@nichegroup.com < /home/oracle/smtest.txt', 
:outpt);

The server is on Red Hat Linux AS 2.1 and 9.2 of the database.  Issuing the command line as oracle 
at the Unix prompt works fine.  Does it work on your Linux box? 


Followup   June 24, 2003 - 7am Central time zone:

sendmail must be waiting for you to type something in.  If you goto the OS and kill it, and it 
returns, that is what is happening.

write a script, call the script perhaps.

(or heck, just use UTL_SMTP eh?)

------------------------------------------------

Oh I see it, search for

you would need to run a SHELL that understands...

on this page.  you sent a SHELL command (redirect).  you are thinking "oh, anything that runs in 
shell, runs here", but it doesn't.  redirection is a "shell thing"
 

4 stars   June 24, 2003 - 4pm Central time zone
Reviewer: Yong from CA, USA
Jack,

You cannot pass more than one parameters in this case. As tom suggested: write a script and run the 
script. You can use pl/sql to write a script and change run mode and call the script.

BTW, why not use pl/sql send mail with attachemet? 


5 stars You were right   July 7, 2003 - 12pm Central time zone
Reviewer: Jack Wells from Boca Raton, FL
Tom,
You were right, it was the "<" redirection... a shell thing.  In my zeal to ensure only granular 
permissions were issued, I had avoided giving execute permission on /usr/sh.  When I did, though, 
it worked fine.  Now, the only thing that bothers me is this execute priv on /usr/sh... 


Followup   July 7, 2003 - 1pm Central time zone:

so -- write a SCRIPT that you invoke that does the redirection.

 

4 stars "Java procedure for host calls on Unix environment"   August 11, 2003 - 12pm Central time zone
Reviewer: Raja 
Hi Tom,
We are looking to call a unix shell script from Oracle after an update/insert/delete happens on a 
table in the database.  The above solution looks kind of neat, however, just wondering whether the 
procedure RC above could be called from a database trigger and made to execute a shell script (lets 
say test.sh) OR do you have any other suggestions which might help? We are using Oracle version 
8.1.7

Thanks in advance!

Raja 


Followup   August 11, 2003 - 2pm Central time zone:

lets back up a second.

what exactly would this shell script do?  this sounds like a fairly "bad idea" for many reasons.  
Once I know what the script does, I'll give you a "for example" 

4 stars "Java procedure for host calls on Unix environment"   August 11, 2003 - 5pm Central time zone
Reviewer: Raja 
Hi Tom,
In simple words, what we are trying to do here is just notify the java webserver that for example 
an update has occured, based on which it will initiate other necessary actions on its side on the 
webserver.  

Actually, I do not code java. Our java developers just gave me an idea of what they want (for 
example to be able to execute host calls - shell scripts from Oracle which will notify the 
webserver for either executing something on the webserver with respect to the database update event 
on a table or maybe run shell script which could FTP some files or other information for each 
updated)

Let me know if this is enough or need more details.

Regards,
Raja 


Followup   August 11, 2003 - 6pm Central time zone:

well, the update hasn't really happened -- NOT until you commit anyhow.

what about this:


update t set x = 5;  -- update 1,000,000 records
ROLLBACK;


whoops -- so sorry, I just ran 1,000,000 sh scripts to notify someone about 

a) an even they cannot see (since I did not commit, they can never have seen the updated data)

b) that didn't really happen.


Another interesting on -- read this article:
http://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:11504247549852
to see an update that updates 4 rows BUT fires the row trigger 6 times!  what about that?



You want to read about AQ (advanced queues) I believe and they want to use JMS to be notified about 
events.

It is nice and transactional.  they'll only get notified of REAL ACTUAL committed events.

 

4 stars "Java procedure for host calls on Unix environment"   August 12, 2003 - 11am Central time zone
Reviewer: Raja 
Hi Tom,
Thanks a lot for a prompt reply.  This is certainly helping.  Actually, just wanted to know if JMS 
supported in Oralce 8.1.7 as, I just happened to go to metalink (let me know if I am looking at the 
right article).....

http://metalink.oracle.com/metalink/plsql/ml2_documents.showDocument?p_database_id=NOT&p_id=232301.1
and it mentions.....
The following requirements need to be satisfied when using JMS-AQ:

OC4J 9.0.3.0.0 
Supported RDBMS version 
Oracle9i Database 9.0.1.4 (Patch: 2517300) 
Oracle9i Database 9.2.0.2 (Patch: 2632931) 
For further information, see: 

Note:230372.1

Send JMS Messages to OJMS Queue Fails with PLS-00306 

You,ve been very helpful!
Regards,
Raja 


Followup   August 12, 2003 - 12pm Central time zone:

read
http://download-west.oracle.com/docs/cd/A87860_01/doc/appdev.817/a76938/adq03pr7.htm#62580

4 stars is there any security issue   August 26, 2003 - 1pm Central time zone
Reviewer: please help from New York, USA
Hi Tom,

Thanks for this nice solution, currently I am using it to call sqlldr to load a file into a table 
from plsql, since it will run sqlldr as user oracle, my boss worrys about any possible security 
hole here, please give me some your comments

Thanks
 


Followup   August 27, 2003 - 7am Central time zone:

what is your boss worried about exactly?

using java with very very specific grants like this (eg: this user is allowed to run 
/home/oracle/bin/sqlldr and nothing else) is much more secure then the other methods of:

o using an extproc.  that can run any code the user running the extproc listener can run

o using "java_sys_priv" or some other broad ranging privs.


if you have a specific concern, we can address that. 

5 stars Trigger again   September 16, 2003 - 2pm Central time zone
Reviewer: Warren from Canada
Tom,

I noticed that you had put the person off who asked about using triggers, but I have a similar 
question.  OK, I have a third party app that is inserting or updating into a table, tableA.  I 
would like to set up a trigger on these actions such that it will call a batch file (say 
devtest.bat, sorry I had to use Windows for these guys).  Can I use your method to pass a column 
name (call it Project_Name) from tableA to the devtest.bat file?

The insert/update is automatically committed by the application when the click on the OK button.  
No rollback opportunity, and no other ad-hoc application (i.e. sqlplus) access to the database.

I have your method working calling the devtest.bat file directly, but can't get a trigger working 
for this.

Thanks! 


Followup   September 16, 2003 - 6pm Central time zone:

tell you want -- read this:

http://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:11504247549852
and see if you REALLY want to call a bat file from a trigger. pretend where I use a sequence - you 
called your bat file.  think about the ramifications....


you want to use a stored procedure, invoked by dbms_job, AFTER the transaction commits.  It is the 
only transactional method that works.

yes, you can pass a parameter to a script.
but I don't have a windows machine anywhere to play with to test for you.
you might have to invoke "cmd /c ....." in order to get it to go.
but that means you need to be able to run "cmd.exe" which means you can run ANYTHING.  (not good) 

4 stars Works nicely   December 2, 2003 - 12pm Central time zone
Reviewer: Mike from St. Louis
Tom's code works well.  Question: is it possible to expand the solution to also populate the 
DIR_LIST table with file attributes such as size and last-mod date?  If so, any code snippets to 
share? 


5 stars Return value into a variable   January 7, 2004 - 1pm Central time zone
Reviewer: Highlander from NY
Tom,
Can you post an axample of the "Util" java that will return the output to a variable or lob instead 
of dbms_output.

Thank you. 


Followup   January 7, 2004 - 6pm Central time zone:

on the road, in a car right now (not conducive to massive coding :)

ask some other time when I'm taking questions (or search the site for java examples that show how 
to return strings and other such things -- they are out there, I had them all in my book "Expert 
one on one Oracle" as well) 

4 stars AUTHID CURRENT_USER - privileges problem   January 8, 2004 - 10am Central time zone
Reviewer: Andriy Terletskyy from Germany
Hi Tom,

I have two Questions:

1. I defined the java source and wrapper function RUN_CMD with invoker-rights  AUTHID CURRENT_USER 
in SCHEMA1 (GLOBAL) and granted the execute right on RUN_CMD to SCHEMA2 (WP).

After that I granted the execute and writeFileDescriptor permission with DBMS_JAVA.GRANT_PERMISSION 
to user WP (SCHEMA2).

If I trying to execute this functiom with user WP (SCHEMA2) :

...
 GLOBAL.run_cmd('/oracle/u01/app/oracle/admin/BBSE/appscripts/ls.sh')
...


FEHLER in Zeile 1:
ORA-29532: Java call terminated by uncaught Java exception:
java.security.AccessControlException: the Permission (java.io.FilePermission
/oracle/u01/app/oracle/admin/BBSE/appscripts/ls.sh execute) has not been
granted to GLOBAL. The PL/SQL to grant this is dbms_java.grant_permission(
'GLOBAL', 'SYS:java.io.FilePermission',
'/oracle/u01/app/oracle/admin/BBSE/appscripts/ls.sh', 'execute' )
ORA-06512: at "GLOBAL.RUN_CMD", line 0
ORA-06512: at line 5

What's wrong?

2. How I can write the wrapper function based on Java-class another user?

WP@BBSE> create or replace
  2    function RUN_CMD( p_cmd  in varchar2) return number
  3    as
  4    language java
  5    name 'GLOBAL:Util.RunThis(java.lang.String[]) return integer';
  6  /

Warnung: Funktion wurde mit Kompilierungsfehlern erstellt.

WP@BBSE> show error
Fehler bei FUNCTION RUN_CMD:

LINE/COL ERROR
-------- -----------------------------------------------------------------
0/0      PL/SQL: Compilation unit analysis terminated
4/3      PLS-00311: the declaration of
         "GLOBAL:Util.RunThis(java.lang.String[]) return integer" is
         incomplete or malformed


Thanks 


Followup   January 8, 2004 - 3pm Central time zone:

1) worked for me.  See full example below (shows that the invoker OPS$TKYTE needs the priv, not the 
owner RT_TEST)



2) this works:

ops$tkyte@ORA920PC> create synonym "Util" for rt_test."Util"
  2  /
 
Synonym created.
 
ops$tkyte@ORA920PC>
ops$tkyte@ORA920PC> create or replace
  2  function RUN_CMD(p_cmd in varchar2) return number
  3  as
  4  language java
  5  name 'Util.RunThis(java.lang.String) return integer';
  6  /
 
Function created.


And in this case -- OPS$TKYTE is the true invoker and OPS$TKYTE would need execute on ls (not 
RT_TEST)

ops$tkyte@ORA920PC> begin
  2    dbms_java.grant_permission
  3    ('RT_TEST',
  4     'java.io.FilePermission',
  5     '/bin/ls',
  6     'execute');
  7
  8    dbms_java.grant_permission
  9    ('RT_TEST',
 10     'java.lang.RuntimePermission',
 11     '*',
 12     'writeFileDescriptor' );
 13  end;
 14  /
 
PL/SQL procedure successfully completed.
 
ops$tkyte@ORA920PC>
ops$tkyte@ORA920PC> @connect rt_test/rt_test
ops$tkyte@ORA920PC> set termout off
rt_test@ORA920PC> REM GET afiedt.buf NOLIST
rt_test@ORA920PC> set termout on
rt_test@ORA920PC>
rt_test@ORA920PC> create or replace and compile
  2  java source named "Util"
  3  as
  4  import java.io.*;
  5  import java.lang.*;
  6
  7  public class Util extends Object
  8  {
  9    public static int RunThis(String args)
 10    {
 11    Runtime rt = Runtime.getRuntime();
 12    int        rc = -1;
 13
 14    try
 15    {
 16       Process p = rt.exec(args);
 17
 18       int bufSize = 4096;
 19       BufferedInputStream bis =
 20        new BufferedInputStream(p.getInputStream(), bufSize);
 21       int len;
 22       byte buffer[] = new byte[bufSize];
 23
 24       // Echo back what the program spit out
 25       while ((len = bis.read(buffer, 0, bufSize)) != -1)
 26          System.out.write(buffer, 0, len);
 27
 28       rc = p.waitFor();
 29    }
 30    catch (Exception e)
 31    {
 32       e.printStackTrace();
 33       rc = -1;
 34    }
 35    finally
 36    {
 37       return rc;
 38    }
 39    }
 40  }
 41  /
 
Java created.
 
rt_test@ORA920PC> grant execute on "Util" to public
  2  /
 
Grant succeeded.
 
rt_test@ORA920PC>
rt_test@ORA920PC> create or replace
  2  function RUN_CMD(p_cmd in varchar2) return number
  3  authid current_user
  4  as
  5  language java
  6  name 'Util.RunThis(java.lang.String) return integer';
  7  /
 
Function created.

rt_test@ORA920PC> show errors
No errors.
rt_test@ORA920PC>
rt_test@ORA920PC> create or replace procedure RC(p_cmd in varchar2)
  2  authid current_user
  3  as
  4    x number;
  5  begin
  6    x := run_cmd(p_cmd);
  7  end;
  8  /
 
Procedure created.
 
rt_test@ORA920PC> grant execute on rc to public
  2  /
 
Grant succeeded.
 
rt_test@ORA920PC>
rt_test@ORA920PC> variable x number;
rt_test@ORA920PC> set serveroutput on
rt_test@ORA920PC> exec dbms_java.set_output(100000);
 
PL/SQL procedure successfully completed.
 
rt_test@ORA920PC>
rt_test@ORA920PC>
rt_test@ORA920PC> exec :x := RUN_CMD('/bin/ls /tmp');
afiedt.buf
BEQ2113
DCE2113
DEC2113
foo.dat
hostname.txt
ISPX2113
ITCP2113
kde-tkyte
ksocket-tkyte
log
LU622113
net2113
NMP2113
nscopy.tmp
nsmail-1.tmp
nsmail-2.tmp
nsmail-3.tmp
nsmail-4.tmp
nsmail-5.tmp
nsmail.eml
nsmail.html
nsmail.tmp
orbit-tkyte
RAW2113
SPX2113
ssh-XXDMz0hl
TCP2113
TCPS2113
US2113
VI2113
 
PL/SQL procedure successfully completed.
 
rt_test@ORA920PC>
rt_test@ORA920PC> @connect /
rt_test@ORA920PC> set termout off
ops$tkyte@ORA920PC> REM GET afiedt.buf NOLIST
ops$tkyte@ORA920PC> set termout on
ops$tkyte@ORA920PC>
ops$tkyte@ORA920PC>
ops$tkyte@ORA920PC> create synonym "Util" for rt_test."Util"
  2  /
 
Synonym created.
 
ops$tkyte@ORA920PC>
ops$tkyte@ORA920PC> create or replace
  2  function RUN_CMD(p_cmd in varchar2) return number
  3  as
  4  language java
  5  name 'Util.RunThis(java.lang.String) return integer';
  6  /
 
Function created.
 
ops$tkyte@ORA920PC> show errors
No errors.
ops$tkyte@ORA920PC>
ops$tkyte@ORA920PC> create or replace procedure RC(p_cmd in varchar2)
  2  as
  3    x number;
  4  begin
  5    x := run_cmd(p_cmd);
  6  end;
  7  /
 
Procedure created.
 
ops$tkyte@ORA920PC>
ops$tkyte@ORA920PC>
ops$tkyte@ORA920PC> variable x number;
ops$tkyte@ORA920PC> set serveroutput on
ops$tkyte@ORA920PC> exec dbms_java.set_output(100000);
 
PL/SQL procedure successfully completed.
 
ops$tkyte@ORA920PC>
ops$tkyte@ORA920PC>
ops$tkyte@ORA920PC> exec :x := RUN_CMD('/bin/ls /tmp');
java.security.AccessControlException: the Permission (java.io.FilePermission /bin/ls execute) has 
not been granted to OPS$TKYTE.
The PL/SQL to grant this is dbms_java.grant_permission( 'OPS$TKYTE', 'SYS:java.io.FilePermission', 
'/bin/ls', 'execute' )
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:283)
at java.security.AccessController.checkPermission(AccessController.java:399)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:545)
at oracle.aurora.rdbms.SecurityManagerImpl.checkPermission(SecurityManagerImpl.java:267)
at java.lang.SecurityManager.checkExec(SecurityManager.java:800)
at java.lang.Runtime.exec(Runtime.java:548)
at java.lang.Runtime.exec(Runtime.java:418)
at java.lang.Runtime.exec(Runtime.java:361)
at java.lang.Runtime.exec(Runtime.java:325)
at Util.RunThis(Util.java:13)
 
PL/SQL procedure successfully completed.
 
ops$tkyte@ORA920PC> exec :x := rt_test.RUN_CMD('/bin/ls /tmp');
java.security.AccessControlException: the Permission (java.io.FilePermission /bin/ls execute) has 
not been granted to OPS$TKYTE.
The PL/SQL to grant this is dbms_java.grant_permission( 'OPS$TKYTE', 'SYS:java.io.FilePermission', 
'/bin/ls', 'execute' )
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:283)
at java.security.AccessController.checkPermission(AccessController.java:399)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:545)
at oracle.aurora.rdbms.SecurityManagerImpl.checkPermission(SecurityManagerImpl.java:267)
at java.lang.SecurityManager.checkExec(SecurityManager.java:800)
at java.lang.Runtime.exec(Runtime.java:548)
at java.lang.Runtime.exec(Runtime.java:418)
at java.lang.Runtime.exec(Runtime.java:361)
at java.lang.Runtime.exec(Runtime.java:325)
at Util.RunThis(Util.java:13)
 
PL/SQL procedure successfully completed.
 
ops$tkyte@ORA920PC>
ops$tkyte@ORA920PC>




 

4 stars Thanks for the question regarding "Java procedure for host calls on Unix environment", version 8.1.6   January 8, 2004 - 11am Central time zone
Reviewer: fakhri from Tunisia
hi tom,

i applied this script and i have error message :

SQL> ed
Wrote file afiedt.buf

  1  begin
  2        dbms_java.grant_permission
  3        ('scott',
  4         'java.io.FilePermission',
  5         '/usr/bin/ps',
  6         'execute');
  7       dbms_java.grant_permission
  8        ('scott',
  9         'java.lang.RuntimePermission',
 10         '*',
 11         'writeFileDescriptor' );
 12*   end;
SQL> /
begin
*
ERROR at line 1:
ORA-29532: appel Java arrêté par une exception Java non interceptée :
oracle.aurora.vm.IdNotFoundException: scott is not a user or role
ORA-06512: à "SYS.DBMS_JAVA", ligne 0
ORA-06512: à ligne 2


can you help me 

thanks
 


Followup   January 8, 2004 - 3pm Central time zone:

'scott' isn't a user

'SCOTT' probably is. 

4 stars AUTHID CURRENT_USER - privileges problem   January 9, 2004 - 7am Central time zone
Reviewer: Andriy Terletskyy from Germany
Hi Tom,

my two Guestions in not answered:

1. It is well that I can see the invoker need the priv. But if I give the priv to invoker and 
revoke that from owner - i see that: 
ORA-29532: Java call terminated by uncaught Java exception:
java.security.AccessControlException: the Permission (java.io.FilePermission
/oracle/u01/app/oracle/admin/BBSE/appscripts/ls.sh execute) has not been
granted to GLOBAL. 
  

The Permission of this script must be granted to the OWNER too? That is wrong.

2. Wrapper function based on Java-class another user.
That work, if java class is not in package, but need also owner execute privs(see 1.)

But, if I put the class in package, that dosn't work:

WP@BBSE> @conn global@bbse
Kennwort eingeben: *****
GLOBAL@BBSE> create or replace and compile java source named util as
  2  package de.berenbergbank.global.tools;
  3  
  4  import java.io.BufferedReader;
  5  import java.io.BufferedInputStream;
  6  import java.io.InputStream;
  7  import java.io.InputStreamReader;
  8  import java.io.IOException;
  9  
 10  import java.util.Collections;
 11  import java.util.LinkedList;
 12  import java.util.List;
 13  
 14  
 15  /**
 16   * Created by IntelliJ IDEA.
 17   * User: Terletskyy
 18   * Date: 06.01.2004
 19   * Time: 13:26:35
 20   * To change this template use Options | File Templates.
 21   */
 22  public class Util {
 23  
 24    public static String run_cmd(String command) throws Exception
 25    {
 26      StringBuffer myBuffer = new StringBuffer();
 27      Process p = Runtime.getRuntime().exec(command);
 28      int out;
 29  
 30      int bufSize = 4096;
 31      BufferedInputStream bis = new BufferedInputStream(p.getInputStream(), bufSize);
 32      byte buffer[] = new byte[bufSize];
 33      int len;
 34  
 35      // Echo back what the program spit out
 36      while ( (len = bis.read(buffer, 0, bufSize)) != -1) {
 37        myBuffer.append(new String(buffer, 0, len));
 38      }
 39  
 40      if ((out=p.waitFor()) != 0 ){
 41        throw new Exception("Error: "+out);
 42      }
 43  
 44      return myBuffer.toString();
 45    }
 46  
 47  }
 48  /

Java wurde erstellt.

GLOBAL@BBSE> GRANT EXECUTE ON GLOBAL."de/berenbergbank/global/tools/Util" TO PUBLIC;

Benutzerzugriff (Grant) wurde erteilt.


WP@BBSE> create synonym "de/berenbergbank/global/tools/Util" for 
GLOBAL."de/berenbergbank/global/tools/Util"
  2  /

Synonym wurde angelegt.

WP@BBSE> CREATE OR REPLACE FUNCTION RUN_CMD (in_command IN VARCHAR2) RETURN VARCHAR2
  2   AS LANGUAGE JAVA NAME 'de.berenbergbank.global.tools.Util.run(java.lang.String) return 
java.lang.String';
  3  /

Funktion wurde erstellt.

WP@BBSE> variable x Varchar2(4000);
WP@BBSE> set serveroutput on
WP@BBSE> exec dbms_java.set_output(100000);

PL/SQL-Prozedur wurde erfolgreich abgeschlossen.

WP@BBSE> exec :x :=  RUN_CMD ('/oracle/u01/app/oracle/admin/BBSE/appscripts/ls.sh');
java.lang.NoSuchMethodException: No applicable method found
at
oracle.aurora.util.JRIExtensions.getMaximallySpecificMethod(JRIExtensions.java)
at
oracle.aurora.util.JRIExtensions.getMaximallySpecificMethod(JRIExtensions.java)
BEGIN :x :=  RUN_CMD ('/oracle/u01/app/oracle/admin/BBSE/appscripts/ls.sh'); END;

*
FEHLER in Zeile 1:
ORA-29531: no method run in class de/berenbergbank/global/tools/Util
ORA-06512: at "WP.RUN_CMD", line 0
ORA-06512: at line 1


Thanks,
Andriy 


4 stars AUTHID CURRENT_USER - privileges problem   January 9, 2004 - 7am Central time zone
Reviewer: Andriy Terlerskyy from Gernamy
Sorry it must be

WP@BBSE> CREATE OR REPLACE FUNCTION RUN_CMD (in_command IN VARCHAR2) RETURN  VARCHAR2
  2  AS LANGUAGE JAVA NAME 'de.berenbergbank.global.tools.Util.run_cmd(java.lang.String) return 
java.lang.String';
  3  /

Funktion wurde erstellt.

WP@BBSE> show error
Keine Fehler.
WP@BBSE> variable x Varchar2(4000);
WP@BBSE> set serveroutput on
WP@BBSE> exec dbms_java.set_output(100000);

PL/SQL-Prozedur wurde erfolgreich abgeschlossen.

WP@BBSE> exec :x :=  RUN_CMD('/oracle/u01/app/oracle/admin/BBSE/appscripts/ls.sh');
java.security.AccessControlException: the Permission (java.io.FilePermission
/oracle/u01/app/oracle/admin/BBSE/appscripts/ls.sh execute) has not been granted
to GLOBAL. The PL/SQL to grant this is dbms_java.grant_permission( 'GLOBAL',
'SYS:java.io.FilePer
mission', '/oracle/u01/app/oracle/admin/BBSE/appscripts/ls.sh', 'execute' )
at java.security.AccessControlContext.checkPermission(AccessControlContext.java)
at java.security.AccessController.checkPermission(AccessController.java)
at java.lang.SecurityManager.checkPermission(SecurityManager.java)
at
oracle.aurora.rdbms.SecurityManagerImpl.checkPermission(SecurityManagerImpl.java
:267)
at java.lang.SecurityManager.checkExec(SecurityManager.java)
at java.lang.Runtime.exec(Runtime.java)
at java.lang.Runtime.exec(Runtime.java)
at java.lang.Runtime.exec(Runtime.java)
at java.lang.Runtime.exec(Runtime.java)
at de.berenbergbank.global.tools.Util.run_cmd(UTIL.java:26)
BEGIN :x :=  RUN_CMD('/oracle/u01/app/oracle/admin/BBSE/appscripts/ls.sh'); END;

*
FEHLER in Zeile 1:
ORA-29532: Java call terminated by uncaught Java exception:
java.security.AccessControlException: the Permission (java.io.FilePermission
/oracle/u01/app/oracle/admin/BBSE/appscripts/ls.sh execute) has not been
granted to GLOBAL. The PL/SQL to grant this is dbms_java.grant_permission(
'GLOBAL', 'SYS:java.io.FilePermission',
'/oracle/u01/app/oracle/admin/BBSE/appscripts/ls.sh', 'execute' )
ORA-06512: at "WP.RUN_CMD", line 0
ORA-06512: at line 1
 


Followup   January 9, 2004 - 8am Central time zone:

yes, it appears that both need the grant -- if you feel this is "a bug", please open a tar with 
support -- I cannot change the code. 

3 stars Java procedure for host calls on Unix environment   January 9, 2004 - 9am Central time zone
Reviewer: fakhri from tunisia
hi tom,

thanks for your help, all the procedures are succefull, but when I execute :

SQL>  exec rc('/usr/bin/ps -ef');
java.lang.ArrayIndexOutOfBoundsException
at Util.RunThis(Util.java:11)

PL/SQL procedure successfully completed.

I have Oracle 9i database.

thx for you help.
fakhri 


Followup   January 9, 2004 - 9am Central time zone:

and read the entire page........  ctl-f for arrayindexoutofbounds 

5 stars win-2003   January 9, 2004 - 10am Central time zone
Reviewer: RR from Richmond
In redhat linux AS 2.1  with oracle 9i-2 your code worked fine.But while I am trying the following 
in win-2003 with oracle 9i-2 its giving the following error. Please help.
SQL> begin
  2   dbms_java.grant_permission
  3       ('DEVEL',
  4        'java.io.FilePermission',
  5        'c:\oracle\backup\abc.bat,
  6        'execute');
  7  end;
  8  /
begin
*
ERROR at line 1:
ORA-04021: timeout occurred while waiting to lock object
SYS.JAVA$POLICY$SHARED$0000001d
ORA-06512: at "SYS.DBMS_JAVA", line 0
ORA-06512: at line 2


 


Followup   January 9, 2004 - 1pm Central time zone:

well, it is not "my code", it is just a standard API call.

read through:

http://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:292016138754#14645479504811
where we just worked through how to find out who is blocking you when you get that 4021. 

5 stars RE: Win 2003   January 9, 2004 - 10am Central time zone
Reviewer: Mark A. Williams from Indianapolis, IN USA
'c:\oracle\backup\abc.bat

Is missing the closing tick - is that correct?  Just an observation...

- Mark 


5 stars   January 9, 2004 - 11am Central time zone
Reviewer: rr from richmond
file is present.It just hangs & giving the following error.
Same thing is happening with '*' too.

SQL> begin
  2   dbms_java.grant_permission
  3       ('DEVEL',
  4        'java.io.FilePermission',
  5        'c:\oracle\backup\*,
  6        'execute');
  7  end;
  8  /
begin
*
ERROR at line 1:
ORA-04021: timeout occurred while waiting to lock object
SYS.JAVA$POLICY$SHARED$0000001d
ORA-06512: at "SYS.DBMS_JAVA", line 0
ORA-06512: at line 2
 


5 stars   January 9, 2004 - 11am Central time zone
Reviewer: rr from richmond
closing tick ' is present in the actual code. I just made a typo after pasting it here.thanks! 


5 stars Line 5   January 9, 2004 - 11am Central time zone
Reviewer: Mark A. Williams from Indianapolis, IN USA
Is line 5 correct?

'c:\oracle\backup\abc.bat,

It looks like it is missing the closing tick:
i.e., 'c:\oracle\backup\abc.bat',

Or is it just getting dropped in the copy and paste?

- Mark 


5 stars   January 9, 2004 - 11am Central time zone
Reviewer: A reader 
AS its my test database , I just shutdown & restarted the database & everything seems to be normal 
now. Thanks! 


5 stars   January 9, 2004 - 12pm Central time zone
Reviewer: A reader 
The Beauty of Windows shutdown and restart, everything works fine. 

:-))))))


 


5 stars Only as 'oracle' o/s user?   January 21, 2004 - 3pm Central time zone
Reviewer: Robert from Memphis, USA.
Tom,

Is there any way to run this so that the o/s command is run as another user besides the 'oracle' 
user?

We want to implement this to run users' application scripts, but would like to limit potential 
security risks of users' scripts running as 'oracle'.

Thanks,

Robert. 


Followup   January 21, 2004 - 3pm Central time zone:

using a C based external procedure and a listener running "as that other user", yes.

Using Java -- no. 

4 stars UnsatisfiedLinkError   January 27, 2004 - 10am Central time zone
Reviewer: Janick Reynders from Belgium
Hi Tom,

A few months ago I tried to run a program from within Oracle using the procedure you described 
here,
(Actually it was a shell script) and it worked great! But just recently I tried to do the same 
thing on another machine, and now I get an exception:

java.lang.UnsatisfiedLinkError
at oracle.aurora.java.lang.OracleProcess.create(OracleProcess.java)
at oracle.aurora.java.lang.OracleProcess.construct(OracleProcess.java)
at java.lang.Runtime.execInternal(Runtime.java)
at java.lang.Runtime.exec(Runtime.java)
at java.lang.Runtime.exec(Runtime.java)
at java.lang.Runtime.exec(Runtime.java)
at UsBblLoadingWrapper.load(UsBblLoadingWrapper:13)

Until now I have not been able to find the problem. Any ideas what could be going wrong?

Thanks,
Janick


this is the setup:
------------------
 Oracle9i

- The permissions:
    dbms_java.grant_permission('AMICUS', 'java.io.FilePermission', 
'/home/ami35/bin/loading_script.sh', 'execute');
    dbms_java.grant_permission('AMICUS', 'java.lang.RuntimePermission', '*', 
'writeFileDescriptor');

- The class:

create or replace and compile
java source named "UsBblLoadingWrapper"
as
import java.io.*;
import java.lang.*;


public class UsBblLoadingWrapper extends Object {

    public static int load() {
        Runtime rt = Runtime.getRuntime();
        int rc = -1;
        System.out.println("\n\n ---START--- \n\n");
    
        try {
            Process p = rt.exec("/home/ami35/bin/loading_script.sh");
            
            int bufSize = 4096;
            BufferedInputStream bis = new BufferedInputStream(p.getInputStream(), bufSize);
            
            
            int len;
            byte buffer[] = new byte[bufSize];
            System.out.println("\n\n--stdout--\n");
            
            // Echo back what the program spit out
            while ((len = bis.read(buffer, 0, bufSize)) != -1) {
                System.out.write(buffer, 0, len);
            }
            
            BufferedInputStream errbis = new BufferedInputStream(p.getErrorStream(), bufSize);
            
            System.out.println("\n\n--stderr--\n");
            while ((len = errbis.read(buffer, 0, bufSize)) != -1) {
                System.out.write(buffer, 0, len);
            }
                        
            rc = p.waitFor();
        }
        catch (Throwable e) {
               e.printStackTrace();
               rc = -1;
        }
        finally    {
               return rc;
        }
    }
}
/


- the function:

create or replace
function TEST_EXTERNAL_PROGRAM return number
as
language java
name 'UsBblLoadingWrapper.load() return integer';
/


- the script:

#!/bin/sh
echo "test"


- the call:

SQL> set serveroutput on size 1000000
exec dbms_java.set_output(1000000)
DECLARE
           rc NUMBER;
BEGIN
         rc := TEST_EXTERNAL_PROGRAM();
         DBMS_OUTPUT.PUT_LINE('function returncode ' || rc);
END;
/SQL>
PL/SQL procedure successfully completed.

SQL>   2    3    4    5    6    7
---START---
java.lang.UnsatisfiedLinkError
at oracle.aurora.java.lang.OracleProcess.create(OracleProcess.java)
at oracle.aurora.java.lang.OracleProcess.construct(OracleProcess.java)
at java.lang.Runtime.execInternal(Runtime.java)
at java.lang.Runtime.exec(Runtime.java)
at java.lang.Runtime.exec(Runtime.java)
at java.lang.Runtime.exec(Runtime.java)
at UsBblLoadingWrapper.load(UsBblLoadingWrapper:13)
function returncode -1

PL/SQL procedure successfully completed.

SQL> 


Followup   January 27, 2004 - 10am Central time zone:

if you are on version 9013 or 9014, contact support and ask them to peek at bug 2598380 

4 stars   February 16, 2004 - 6am Central time zone
Reviewer: Sarada Priya from Chennai, India
Hi Tom,

I found this very useful, but I have a question to ask. I have a requirement wherein the Database 
Server, 9iAS server & Reports Server(We put all the reports output files in this after the nightly 
batch jobs) all in a networked environment and the Client system is web-enabled Forms9i forms. We 
need to build an interface wherein the user needs to see all the files available under a designated 
folder in the Reports Server and should be allowed to print the same. We are perplexed how to get 
the List of files from the Reports server. The above problem(for which you have answered) deals 
with the DB server itself, but this one???? Any idea? Please send in. 
Thanks and Regards
Sarada Priya 


Followup   February 16, 2004 - 7am Central time zone:

sorry, I don't work with reports but it seems to me that "mount" is the answer?  just attach a 
network drive and go at it -- whatever client you have would read the directory. 

3 stars How can we diagnose problems?   February 19, 2004 - 12am Central time zone
Reviewer: Ben from Quebec
Tom,
We've successfully implemented this on one database, and now I'm trying to implement it on a new 
one, but it seems the thing doesn't work. Is there an error log somewhere that would show me what 
went wrong?
Here's the code for the procedure that I implemented:
create or replace and compile java source named "Util" as
  import java.io.*;
  import java.lang.*;
  
  public class Util extends Object  {
   public static int RunThis(String[] args)    {
    Runtime rt = Runtime.getRuntime();
    int        rc = -1;
  
    try    {
       Process p = rt.exec(args[0]);
  
       int bufSize = 4096;
       BufferedInputStream bis =
        new BufferedInputStream(p.getInputStream(), bufSize);
       int len;
       byte buffer[] = new byte[bufSize];
  
       // Echo back what the program spit out
       while ((len = bis.read(buffer, 0, bufSize)) != -1)
          System.out.write(buffer, 0, len);
  
       rc = p.waitFor();
    }
    catch (Exception e)    {
       e.printStackTrace();
       rc = -1;
    }
    finally    {
       return rc;
    }
   }
  }
  /

create or replace
  function RUN_CMD( p_cmd  in varchar2) return number
  as
  language java
  name 'Util.RunThis(java.lang.String[]) return integer';
  /


As the SYS user, I granted the following privileges:
begin
      dbms_java.grant_permission
      ('ROCQ',
       'java.io.FilePermission',
       '/tahiti/bin/test.pl',
       'execute');
  
      dbms_java.grant_permission
      ('ROCQ',
       'java.lang.RuntimePermission',
       '*',
       'writeFileDescriptor' );
  end;
  /

The procedure that executes the system call:
CREATE OR REPLACE PROCEDURE rocq.test_runcmd IS

    resultat_rp        NUMBER;

BEGIN

    dbms_output.put_line('Beginning.');
    resultat_rp := RUN_CMD('perl /tahiti/bin/test.pl');
    dbms_output.put_line(resultat_rp);
    dbms_output.put_line('Ending.');

END;
/
show errors;

And the script that is called:
#!/usr/bin/perl -w

system "echo allo >allo";

Finally, the execution:
SQL> @ test_runcmd.pls

Procedure created.

No errors.
SQL> exec test_runcmd
Beginning.
-1
Ending.

PL/SQL procedure successfully completed.

Any ideas?
Thanks for your help! 


Followup   February 19, 2004 - 10am Central time zone:

you granted execute on the script.


you cannot run "perl", no grant on "perl"


if you do this:

set serveroutput on size 1000000
exec dbms_java.set_output(1000000)

you should see the java output "on screen"  

3 stars   February 19, 2004 - 11am Central time zone
Reviewer: Ben from Quebec
Just tried these grants:
begin
      dbms_java.grant_permission
      ('ROCQ',
       'java.io.FilePermission',
       'perl',
       'execute');

       dbms_java.grant_permission
      ('ROCQ',
       'java.io.FilePermission',
       '/usr/bin/perl',
       'execute');
 
      dbms_java.grant_permission
      ('ROCQ',
       'java.lang.RuntimePermission',
       '*',
       'writeFileDescriptor' );
  end;
  /

But the host call still doesn't work:

SQL> set serveroutput on size 1000000
exec dbms_java.set_output(1000000)
SQL> 
PL/SQL procedure successfully completed.

SQL> exec test_runcmd
Beginning.
java.lang.ArrayIndexOutOfBoundsException
at Util.RunThis(Util:8)
-1
Ending.

PL/SQL procedure successfully completed.


 


3 stars Permissions   February 19, 2004 - 12pm Central time zone
Reviewer: Ben from Quebec
Just did as you suggested, but now I'm running into a classic Permissions problem. 
SQL> begin
  2    dbms_java.grant_permission
  ('ROCQ',
   'SYS:java.io.FilePermission',
   'perl',
   'execute');

  dbms_java.grant_permission
  ('ROCQ',
   'SYS:java.io.FilePermission',
   '/usr/bin/perl',
   'execute');

  dbms_java.grant_permission
  ('ROCQ',
   'SYS:java.io.FilePermission',
  3    4    5    6    7     '/tahiti/bin/test.pl',
   'execute');

  dbms_java.grant_permission
  ('ROCQ',
   'SYS:java.lang.RuntimePermission',
   '*',
   'writeFileDescriptor' );
end;
/

PL/SQL procedure successfully completed.

SQL> 
SQL> exec test_runcmd
Beginning.
java.security.AccessControlException: the Permission (java.io.FilePermission
<<ALL FILES>> execute) has not been granted to ROCQ. The PL/SQL to grant this is
dbms_java.grant_permission( 'ROCQ', 'SYS:java.io.FilePermission', '<<ALL
FILES>>', 'execute' )
at
java.security.AccessControlContext.checkPermission(AccessControlContext.java:207
)
at java.security.AccessController.checkPermission(AccessController.java:403)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
at
oracle.aurora.rdbms.SecurityManagerImpl.checkPermission(SecurityManagerImpl.java
:267)
at java.lang.SecurityManager.checkExec(SecurityManager.java:788)
at java.lang.Runtime.exec(Runtime.java:270)
at java.lang.Runtime.exec(Runtime.java:195)
at java.lang.Runtime.exec(Runtime.java:152)
at Util.RunThis(Util:10)
-1
Ending.

PL/SQL procedure successfully completed.
 


Followup   February 19, 2004 - 12pm Central time zone:

sorry -- i cannot reproduce on 9ir2 myself (did you log out and back in after granting?)


ops$tkyte@ORA920PC> grant dba to rt_test identified by rt_test;
 
Grant succeeded.
 
ops$tkyte@ORA920PC>
ops$tkyte@ORA920PC> begin
  2    dbms_java.grant_permission
  3    ('RT_TEST',
  4     'java.io.FilePermission',
  5     '/usr/bin/perl',
  6     'execute');
  7
  8    dbms_java.grant_permission
  9    ('RT_TEST',
 10     'java.lang.RuntimePermission',
 11     '*',
 12     'writeFileDescriptor' );
 13  end;
 14  /
 
PL/SQL procedure successfully completed.
 
ops$tkyte@ORA920PC>
ops$tkyte@ORA920PC>
ops$tkyte@ORA920PC> @connect rt_test/rt_test
ops$tkyte@ORA920PC> set termout off
rt_test@ORA920PC> REM GET afiedt.buf NOLIST
rt_test@ORA920PC> set termout on
rt_test@ORA920PC>
rt_test@ORA920PC> create or replace and compile
  2  java source named "Util"
  3  as
  4  import java.io.*;
  5  import java.lang.*;
  6
  7  public class Util extends Object
  8  {
  9    public static int RunThis(String args)
 10    {
 11    Runtime rt = Runtime.getRuntime();
 12    int        rc = -1;
 13
 14    try
 15    {
 16       Process p = rt.exec(args);
 17
 18       int bufSize = 4096;
 19       BufferedInputStream bis =
 20        new BufferedInputStream(p.getInputStream(), bufSize);
 21       int len;
 22       byte buffer[] = new byte[bufSize];
 23
 24       // Echo back what the program spit out
 25       while ((len = bis.read(buffer, 0, bufSize)) != -1)
 26          System.out.write(buffer, 0, len);
 27
 28       rc = p.waitFor();
 29    }
 30    catch (Exception e)
 31    {
 32       e.printStackTrace();
 33       rc = -1;
 34    }
 35    finally
 36    {
 37       return rc;
 38    }
 39    }
 40  }
 41  /
 
Java created.
 
rt_test@ORA920PC>
rt_test@ORA920PC>
rt_test@ORA920PC> create or replace
  2  function RUN_CMD(p_cmd in varchar2) return number
  3  as
  4  language java
  5  name 'Util.RunThis(java.lang.String) return integer';
  6  /
 
Function created.
 
rt_test@ORA920PC>
rt_test@ORA920PC>
rt_test@ORA920PC> create or replace procedure RC(p_cmd in varchar2)
  2  as
  3    x number;
  4  begin
  5    x := run_cmd(p_cmd);
  6  end;
  7  /
 
Procedure created.
 
rt_test@ORA920PC>
rt_test@ORA920PC>
rt_test@ORA920PC> variable x number;
rt_test@ORA920PC> set serveroutput on
rt_test@ORA920PC> exec dbms_java.set_output(100000);
 
PL/SQL procedure successfully completed.
 
rt_test@ORA920PC>
rt_test@ORA920PC>
rt_test@ORA920PC> exec :x := RUN_CMD('/usr/bin/perl /home/tkyte/test.pl' );
Hello World
 
PL/SQL procedure successfully completed.
 
 

2 stars   February 19, 2004 - 1pm Central time zone
Reviewer: Ben from Quebec
Yes - actually, the grant was in one terminal window as the SYS user, and the script execution was 
in another terminal, as a regular user. I just tried to disconnect/reconnect, and it still fails, 
but now I've lost the error messages:

@tahiti/export/home/hebben01>sqlplus

SQL*Plus: Release 9.0.1.4.0 - Production on Thu Feb 19 13:25:34 2004

(c) Copyright 2001 Oracle Corporation.  All rights reserved.

Enter user-name: rocq     
Enter password: 

Connected to:
Oracle9i Enterprise Edition Release 9.0.1.4.0 - Production
JServer Release 9.0.1.4.0 - Production

SQL> set serveroutput on size 1000000
exec dbms_java.set_output(1000000)
SQL> 
PL/SQL procedure successfully completed.

SQL> exec test_runcmd
Beginning.
-1
Ending.

PL/SQL procedure successfully completed.

 


Followup   February 19, 2004 - 2pm Central time zone:

put some System.out.println( "hello world" ) messages in your java.

I think you have gotten around your "permission issue" (else we'd see that) and it is now failing 
'for some other reason' 

2 stars   February 19, 2004 - 2pm Central time zone
Reviewer: Ben from Quebec
This is what I tried:

create or replace and compile java source named "Util" as
  import java.io.*;
  import java.lang.*;
  
  public class Util extends Object {
    public static int RunThis(String args) {
    Runtime rt = Runtime.getRuntime();
    int        rc = -1;
    try    {
        System.out.println("Hello world 1");
       Process p = rt.exec(args);
  
       int bufSize = 4096;
       BufferedInputStream bis =
        new BufferedInputStream(p.getInputStream(), bufSize);
       int len;
       byte buffer[] = new byte[bufSize];
        System.out.println("Hello world 2");
  
       // Echo back what the program spit out
       while ((len = bis.read(buffer, 0, bufSize)) != -1)
          System.out.write(buffer, 0, len);
        System.out.println("Hello world 3");
  
       rc = p.waitFor();
    }
    catch (Exception e)  {
        System.out.println("Hello world 4");
       e.printStackTrace();
       rc = -1;
    }
    finally {
       return rc;
    }
   }
  }
/

Re-granted privileges as the sys user:
SQL> begin
      dbms_java.grant_permission
      ('ROCQ',
       'SYS:java.io.FilePermission',
       '/usr/bin/perl',
       'execute');
 
     dbms_java.grant_permission
      ('ROCQ',
       'SYS:java.lang.RuntimePermission',
       '*',
       'writeFileDescriptor' );
  end;
/

PL/SQL procedure successfully completed.

Checked permissions at the OS level to make sure Oracle had the required privileges to execute the 
script.
But I'm still getting the same result:
SQL> exec test_runcmd
Beginning.
-1
Ending.

I'm not seeing the "hello world" messages. 


Followup   February 19, 2004 - 3pm Central time zone:

are you sure you made the call to dbms_java to enable output (else it gets written to a trace file 
on the database server).

Until you get "output", nothing is working -- get it to get output on your screen first.  Just 
write a hello world java snippet if you have to. 

2 stars   February 19, 2004 - 3pm Central time zone
Reviewer: Ben from Quebec
Disregard my last posting. I had neglected to logout/login again.
The new Java:
create or replace and compile java source named "Util" as
  import java.io.*;
  import java.lang.*;
  
  public class Util extends Object {
    public static int RunThis(String args) {
    Runtime rt = Runtime.getRuntime();
    int        rc = -1;
    try    {
        System.out.println("Hello world 1");
       Process p = rt.exec(args);
        System.out.println("Hello world A");
  
       int bufSize = 4096;
       BufferedInputStream bis =
        new BufferedInputStream(p.getInputStream(), bufSize);
       int len;
       byte buffer[] = new byte[bufSize];
        System.out.println("Hello world 2");
  
       // Echo back what the program spit out
       while ((len = bis.read(buffer, 0, bufSize)) != -1)
          System.out.write(buffer, 0, len);
        System.out.println("Hello world 3");
  
       rc = p.waitFor();
    }
    catch (Exception e)  {
        System.out.println("Hello world 4");
       e.printStackTrace();
       rc = -1;
    }
    finally {
       return rc;
    }
   }
  }
/


Here is what I'm seeing:
SQL> exec test_runcmd
Beginning.
Hello world 1
-1
Ending.

PL/SQL procedure successfully completed.
 


Followup   February 19, 2004 - 3pm Central time zone:

put something in the finally block -- it is not making sense yet.  If the rt.exec was failing -- it 
would jump to the catch block -- but apparently - it is not.   

2 stars   February 19, 2004 - 3pm Central time zone
Reviewer: Ben from Quebec
    finally {
         System.out.println("Goodbye cruel world");
      return rc;
   }


SQL> exec test_runcmd
Beginning.
Hello world 1
Goodbye cruel world
-1
Ending.
 


Followup   February 19, 2004 - 3pm Central time zone:

don't know -- sorry, i'll have to refer you to support.  we know the rt.exec was working at some 
point (you got the permissions thing) but now is not.  

Maybe try "ls" like I did to remove perl and scripting from the equation first tho 

2 stars   February 19, 2004 - 3pm Central time zone
Reviewer: Ben from Quebec
ok
Thanks for all your help, Tom. 


5 stars how to send message?   March 9, 2004 - 6am Central time zone
Reviewer: Sikandar Hayat from Pindi Bhattian - Pakistan
Hi,
I want to send message to different users when any insert in the table. I am using Oracle 9i r2 on 
Windows 2003 env. Please guide me as I am trying to use 

net send sikandar A record inserted....

But unable to use net send command in the trigger. 


Followup   March 9, 2004 - 12pm Central time zone:

did you install the above code that lets you run host commands? 

5 stars 3x for help!!!   March 21, 2004 - 10pm Central time zone
Reviewer: dibo from China
so good.
haho. 


4 stars Can PL/SQL submit a nohup job in unix shell   April 2, 2004 - 1am Central time zone
Reviewer: Stephen from Hong Kong
I try to submit a nohup shell script from pl/sql, but the session still wait unit the script end. 
How can I submit a nohup jobs in pl/sql? 

Please advise!  


Followup   April 2, 2004 - 10am Central time zone:

the script you run would call the script you want to run in the background

instead of you running:

  
  rc( 'some_script' );

you would run

  rc( 'some_other_script' );

and some_other_script would be

#!/bin/sh
some_script &

 

4 stars Can PL/SQL submit a nohup job in unix shell   April 2, 2004 - 8pm Central time zone
Reviewer: Stephen from Hong Kong
Hi, 

I had tried the following method already in the some_other_script:

1)
#!/bin/sh
some_script &

2)
#!/bin/sh
nohup some_script &

But the session in PL/SQL still wait until the last nohup job completed. 

Should you have any idea?  Please advise. 


Thanks, 
Stephen 

 


Followup   April 3, 2004 - 8am Central time zone:

maybe its the waitFor() call in the Process class.

in fact, google'ing waitfor process confirms.

your choices

o learn more java to find the exact solution you want
o remove the p.waitfor call so as to not block and hope that is the solution you want. 

4 stars why I hate windoz #101   April 13, 2004 - 2pm Central time zone
Reviewer: robert from CT
tom, 
The code below worked fine under *nix (9i) where instead of
"c:/winnt/system32/cmd", I had "/bin/sh".
But under 8i/W2K, it's not carrying out my commands:
Can you spot whats wrong, thanks

CREATE OR REPLACE AND COMPILE
JAVA SOURCE NAMED "Util"
AS
import java.io.*;
import java.lang.*;

public class Util extends Object
{
public static int RunThis(String args)
{
Runtime rt = Runtime.getRuntime();
int rc = -1;

try
{
String[] cmd = {"c:/winnt/system32/cmd", "/c", args};
Process p = Runtime.getRuntime().exec(cmd);
rc = p.waitFor();
}
catch (Exception e)
{
e.printStackTrace();
rc = -1;
}
finally
{
return rc;
}
}
}

/

CREATE OR REPLACE
FUNCTION run_host_cmd(p_cmd IN VARCHAR2) RETURN NUMBER
AS
LANGUAGE JAVA
NAME 'Util.RunThis(java.lang.String) return integer';
/

CREATE OR REPLACE PROCEDURE RC(p_cmd IN VARCHAR2)
AS
x NUMBER;
BEGIN
x := run_host_cmd(p_cmd);
END;
/

SQL> exec rc('del C:\temp\foo.pdf');

PL/SQL procedure successfully completed



----  BUT C:\temp\foo.pdf' is NOT deleted

GRANTED:
dbms_java.grant_permission('MANDA','java.io.FilePermission','c:\winnt\system32\cmd.exe','execute');
dbms_java.grant_permission('MANDA', 'java.io.FilePermission','C:/temp/*', 'read,write'); 
dbms_java.grant_permission('MANDA',  'java.lang.RuntimePermission','C:/temp/*',   
'writeFileDescriptor' ); 

 


Followup   April 13, 2004 - 6pm Central time zone:

look in the server for a trace file -- the prints from exceptions are going there. 

4 stars Disregard Prev Post - bug found   April 13, 2004 - 5pm Central time zone
Reviewer: robert from ct
tom pls disregard my prev posting.
found out what was wrong...shoulda have a space
before the parameter...duh
Thanks

SQL> exec rc(' del C:\temp\foo.pdf'); 


4 stars Does Oracle waits ?   April 14, 2004 - 9am Central time zone
Reviewer: Robert from CT
Tom, does Oracle, in PL/SQL processing, wait for the host call via Java SP to end then continue ?

Thanks 


Followup   April 14, 2004 - 10am Central time zone:

as coded, yes -- 

 26       while ((len = bis.read(buffer, 0, bufSize)) != -1)
 27          System.out.write(buffer, 0, len);
 28  
 29       rc = p.waitFor();
 30    } 

5 stars Just what we needed   April 28, 2004 - 7am Central time zone
Reviewer: Jack Boyle from New Jersey
We have implemented a solution for executing processes outside of the database that includes Oracle 
Queues, detached processes, etc.  This solution looks like a much cleaner, more straightforward 
approach. 


3 stars Need to run sqlldr command from within the procedure   April 29, 2004 - 7pm Central time zone
Reviewer: Anurag Mehrotra from MD USA
I have already implemented the solution mentioned here to run OS commands successfully. However in 
spite of my best efforts I have been unable to invoke sql loader command using this method.

my exec command is:
exec :x := RUN_CMD('/export/home/oracle/test-sqlldr/load-data-test.sh mytestctl.ctl 
mydatafile.dat')

load-data-test.sh looks something like:

USAGE="load-data-test.sh ctlfilename.ctl datafilename.dat"
if [ $# -lt 2 ] ; then          
     echo "$USAGE"            
     exit 1         fi                                                               
ORACLE_SID=dbtest                                           
ORACLE_HOME=/usr/app/oracle/product/8.1.7                   export ORACLE_SID
export ORACLE_HOME
     
$ORACLE_HOME/bin/sqlldr username/pwd $1 data=$2    

I have also assigned the following privilege to the user:

    dbms_java.grant_permission
    ('USERNAME',
    'java.io.FilePermission',
    '/usr/bin/ls',
    'execute');
    
    dbms_java.grant_permission
    ('USERNAME',
    'java.io.FilePermission',
    '/export/home/oracle/test-sqlldr/load-data-test.sh',
    'execute');

    dbms_java.grant_permission
    ('USERNAME',
    'SYS:java.io.FilePermission',
    '/export/home/oracle/test-sqlldr/*',
    'read,write,execute');

    dbms_java.grant_permission
    ('USERNAME',
    'java.lang.RuntimePermission',
    '*',
    'writeFileDescriptor' );
    
end;
/

Somehow it does not seem to create the log file or the bad file in the directory I am expecting it 
to create (/export/home/oracle/test-sqlldr). The response I get after executing the RUN_CMD is: 
"PL/SQL procedure successfully completed."

Could there be some permission that I am missing on the directory?

 


Followup   April 30, 2004 - 7am Central time zone:

well, I see no explicit "cd" anywhere -- do you have any idea what directory might be the "current 
working one"?

I would add a bit of "debug" to the script.  redirect its output to /tmp/something, put cd's in 
there to be exactly where you think you should be and so on.

and don't forget, it'll run "as oracle", not as "you" so yes, permissions play into this big time. 

5 stars It worked   April 30, 2004 - 9am Central time zone
Reviewer: Anurag Mehrotra from MD USA
'cd' did the trick. 
You can write all the complex code in the world, but can forget simplest of all things, that can 
cause undesirable results.

Your help is greatly appreciated.
 


5 stars to call a Pro*C executables   May 19, 2004 - 10am Central time zone
Reviewer: Pushparaj A from NJ,USA
Tom,

Can I use this Java approach to call a Pro*C executables
from the stored procedures. Since Pro*C needs to connect back to the database, I am not sure if 
this is the best way.
Currently we don't have JVM installed in our database and if calling a Pro*C executable from stored 
procedure is feasible by this way then I can ask the manager to have the
JVM installed in the database.

We currently using,
Oracle9i Enterprise Edition Release 9.2.0.5.0 - 64bit Production
With the Partitioning option
JServer Release 9.2.0.5.0 - Production

Thanks
Pushparaj
 


Followup   May 19, 2004 - 11am Central time zone:

you can use this approach to call "any executable"

but if I had pro*c code I needed to invoke -- i would be looking at EXTERNAL PROCEDURES and just 
call the c code as a subroutine instead, it'll use the same connection, it'll use the same 
transaction. 

3 stars Background execution   May 25, 2004 - 7pm Central time zone
Reviewer: andrew from usa
In relpy to Stephen's posting above, I've successfully used this for background execution:

#!/usr/bin/ksh
# Script: at_now.ksh
/usr/bin/echo "$1 $2 $3 $4 $5 $6 $7 $8 $9" | /usr/bin/at now

begin
  RC('/full_path/at_now.ksh /usr/bin/sleep 10');
end;
/
 


4 stars Java procedure for host calls   May 26, 2004 - 10am Central time zone
Reviewer: RameshG from UK
I'm getting the following error when i run it:

SQL> exec rc('/usr/bin/ps -ef');
java.lang.ArrayIndexOutOfBoundsException
at Util.RunThis(Util.java:11)

DBA's have granted the permissions that you have specified.

Could explain me if anything else needs to be done.

Thanks
RameshG
 


Followup   May 26, 2004 - 12pm Central time zone:

ctl-f and enter ArrayIndexOutOfBoundsException into the text field... 

4 stars Java procedure for host calls on Unix environment   May 27, 2004 - 1pm Central time zone
Reviewer: Jose Luis Sanchez from Madrid, Spain
hi tom.

I don´t know anything about java or unix and i would like to know if i could use this procedures 
whit sqlldr on windows xp and Oracle 9i. I´m not DBA an i would like to know if is obligatory 
anyone grant me permission with dbms_java.grant_permission.

thank you very much for your help

 


Followup   May 27, 2004 - 8pm Central time zone:

works on windows.

you need the grant permission on any OS 

3 stars Works but Sqlloader is hanging and bringing the Databse down   June 8, 2004 - 2pm Central time zone
Reviewer: Rajesh Chundi from Golden Colorado
Hi Tom ,
I am using the procedure RC to call sqlloader in a loop in anothe rstored proc for each input file.
if the input file is small it works 

even for multiple files, but its hanging and bringing the database down  whne the number of records 
 is increased to 6000 of 1column  or type number.

what am I missing please help
here is the stroed proc iam Using .

CREATE OR REPLACE  PROCEDURE "TKMSYS"."LG2" AS
  l_file         UTL_FILE.file_type;
  l_location     VARCHAR2(100) := 'GRADESDIR';
  l_filename     VARCHAR2(100) := 'fileList.txt';
  l_exists       BOOLEAN;
  l_file_length  NUMBER;
  l_blocksize    NUMBER;
  l_text         VARCHAR2(32767);
    cmdStr         varchar2(4000);
    procId         varchar2(100);
    fileSeq        number(10);
    retVal number(10);
 
BEGIN
  -- Open file.
  l_file := UTL_FILE.fopen(l_location, l_filename, 'r', 32767);
    
    select 'LG' ||to_char(sysdate,'mmddyyyyhhmiss') into procId from dual;
    
  
  -- Read and output first line.
  UTL_FILE.get_line(l_file, l_text, 32767);
  DBMS_OUTPUT.put_line('First Line: |' || l_text || '|');

  -- Read through the file until we reach the last line.
  BEGIN
      fileSeq:= 1 ;
      retVal := RUN_CMD('mkdir c:\UPHS\'||procId);
    LOOP
         retVal :=  -99;
      UTL_FILE.get_line(l_file, l_text, 32767);
          
          cmdStr := ' sqlldr TKMSYS/do1od3le5@rchundi data=c:\UPHS\' ||l_text ||
                       ' control=c:\UPHS\test.ctl log=c:\UPHS\'||procId 
||'\'||replace(l_text,'.txt','.log')||
                    ' bad=c:\UPHS\'||procId ||'\'||replace(l_text,'.txt','.bad') ||
                    ' discard=c:\UPHS\'||procId ||'\'||replace(l_text,'.txt','.dis') ;
    --     if(fileSeq =1) then
        -- RC('echo ' || cmdStr || '>    c:\UPHS\'||procId ||'\loadRaw.bat');
    --     else
        -- RC('echo ' || cmdStr || ' >> c:\UPHS\'||procId ||'\loadRaw.bat');
    --     end if;             
          DBMS_OUTPUT.put_line( cmdStr );
         retVal:=  RUN_CMD(cmdStr);
         --Rc('exit');
        --  DBMS_OUTPUT.put_line( l_text );
        fileSeq := fileSeq + 1;
    END LOOP;

        
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
     null;
  END;
 --  Rc('echo CHR(10)');
  -- Output the last line.
  DBMS_OUTPUT.put_line('Last Line : |' || l_text || '|');
    DBMS_OUTPUT.put_line( 'c:\UPHS\'||procId ||'\loadRaw.bat' );
            
    --RC('c:\UPHS\'||procId ||'\loadRaw.bat CHR(10)');
        
         

  -- Close the file.
  UTL_FILE.fclose(l_file);
END;
/
 


Followup   June 8, 2004 - 3pm Central time zone:

sqlldr will not "hang" or "bring down" your database.


run sqlldr from the command line (remove pieces). what happens then? 

4 stars spurious OutOfMemoryException   June 16, 2004 - 3pm Central time zone
Reviewer: A reader 
Hi Tom,

I'm running the code practically identical to yours, and it gets called several times in 
succession. And sometimes I'm getting OutOfMemoryException, which gets thrown from

Process p = Runtime.getRuntime().exec(cmd);

Once I catch the first OutOfMemoryException, all the next attempts also fail, until I 
logout/re-login again.
Do you have any idea what could be causing it?

The command itself is a shell script that calls chmod.

The oracle version is 9.2 and it's running under AIX.

Any ideas would be much appreciated.

thanks,
ilya 


Followup   June 16, 2004 - 4pm Central time zone:

"practically identical"

care to share?  does it always reproduce? (eg: if you go into a hard loop and just call it over and 
over and ask it to run "uptime" or something innocent -- does it eventually bomb?) 

4 stars spurious OutOfMemoryException   June 16, 2004 - 4pm Central time zone
Reviewer: Ilya from New York
OK, here's the java code:

public static void executeCommand(String cmd)
        throws IOException, java.sql.SQLException {
        Process p = Runtime.getRuntime().exec(cmd);
        int res;

        int bufSize = 4096;
        int len;
        byte[] buffer = new byte[bufSize];

        try {

            BufferedInputStream bis =
                new BufferedInputStream(p.getInputStream(), bufSize);

            //Echo back what the program spit out
            while ((len = bis.read(buffer, 0, bufSize)) != -1) {
                System.out.write(buffer, 0, len);
            }

            res = p.waitFor();
            p = null;
            bis.close();
            bis = null;
        } catch (InterruptedException ex) {
            throw new RuntimeException(
                "exception while waiting for the process to complete: "
                    + ex.getMessage());
        }

    }


and here's pl/sql test code:

begin
dbms_java.set_output(1000000);
dbms_output.enable(1000000);

for i in 1 .. 100
loop
fileutils_pkg.executecommand('/homedev/ilyam/giftsedd/chmod_edd.sh');
end loop;
end;

and there's also a package fileutils_pkg with
PROCEDURE executecommand(
      cmd IN VARCHAR2
   )
   AS
     LANGUAGE JAVA
     NAME 'gifts.edd.FileUtils.executeCommand(java.lang.String)';

This runs fine the first time (calling the program 100 times in succession), but usually bombs the 
second time with this error:

ORA-04030: out of process memory when trying to allocate 4032 bytes 
(ioc_make_sub2,ioc_allocate_pal)
and the printstack is
java.lang.OutOfMemoryError
  at java.lang.Thread.start(Thread.java)
  at oracle.aurora.java.lang.OracleProcess.newOutputStream(OracleProcess.java)
  at oracle.aurora.java.lang.OracleProcess.construct(OracleProcess.java)
  at java.lang.Runtime.execInternal(Runtime.java)
  at java.lang.Runtime.exec(Runtime.java)
  at java.lang.Runtime.exec(Runtime.java)
  at java.lang.Runtime.exec(Runtime.java)
  at java.lang.Runtime.exec(Runtime.java)
  at gifts.edd.FileUtils.executeCommand(FileUtils.java:241)

where line 241 is

Process p = Runtime.getRuntime().exec(cmd);

I also tried commenting out all the BufferedInputStream stuff, so that it's simply
public static void executeCommand(String cmd)
        throws IOException, java.sql.SQLException {
        Process p = Runtime.getRuntime().exec(cmd);
        int res;

        //int bufSize = 4096;
        //int len;
        //byte[] buffer = new byte[bufSize];

        try {
            /*
            BufferedInputStream bis =
                new BufferedInputStream(p.getInputStream(), bufSize);

            //Echo back what the program spit out
            while ((len = bis.read(buffer, 0, bufSize)) != -1) {
                System.out.write(buffer, 0, len);
            }
            */
            res = p.waitFor();
            p = null;
            //bis.close();
            //bis = null;
        } catch (InterruptedException ex) {
            throw new RuntimeException(
                "exception while waiting for the process to complete: "
                    + ex.getMessage());
        }

    }


but the result is exactly the same: succeeds on the first run, fails with OutOfMemoryException the 
second time.

thanks,
ilya

 


Followup   June 16, 2004 - 4pm Central time zone:

how is your java pool size?   

4 stars spurious OutOfMemoryException   June 16, 2004 - 5pm Central time zone
Reviewer: Ilya from New York
sorry, I don't know much about java pool size. What do I need to check?

 


Followup   June 16, 2004 - 6pm Central time zone:

SQL> show parameter java 

4 stars spurious OutOfMemoryException   June 16, 2004 - 8pm Central time zone
Reviewer: Ilya from New York
NAME                                 TYPE        VALUE
------------------------------------ ----------- ----------
java_max_sessionspace_size           integer     0
java_pool_size                       big integer 218103808
java_soft_sessionspace_limit         integer     0 


Followup   June 17, 2004 - 7am Central time zone:

I'll have to request you file a tar with support.  possible memory leak.   

4 stars spurious OutOfMemoryException   June 17, 2004 - 10am Central time zone
Reviewer: A reader 
while in the process of creating a tar, I found a similar report of memory leak problem with 
oracle's JVM, reproducible in 9.2.0.2; it was fixed in 10.0.0 


4 stars ArrayIndexOutOfBounds   June 17, 2004 - 5pm Central time zone
Reviewer: Chris Fischer from Raleigh, NC USA
I've read all the suggestions of going back and doing a ctrl-f to find the comment about this 
exception.

Here's my problem though.  The documented construct for passing an array of strings to a java 
method in a pl/sql wrapper is to have it declared like this:

public class EchoInput {
  public static void main (String[] args) {
    for (int i = 0; i < args.length; i++)
      System.out.println(args[i]);
  }
}


To publish method main, you might write the following call spec:

CREATE OR REPLACE PROCEDURE echo_input (
  s1 VARCHAR2,
  s2 VARCHAR2,
  s3 VARCHAR2)
AS LANGUAGE JAVA
NAME 'EchoInput.main(java.lang.String[])';

This is taken directly from the 9iR2 Java Stored Procedure Developers Guide.

In addition, I have an 8i app that I'm trying to upgrade to 9i, and all my calls to methods 
similarly fail with ArrayIndexOutOfBounds.  I can't believe that Oracle would make a change to the 
callspec in such a way as to BREAK everyone's app?  Oh, I guess everyone being the 5 foolish people 
to actually USE java in the database. 


Followup   June 17, 2004 - 6pm Central time zone:

in my case, i had a bug in the code (i did it wrong).  I was not passing an array of strings.

I'm not sure what you are trying to say?  

can you give me a complete test case in the fashion I give to you? with the create or replace java, 
etc etc etc. 

4 stars Memory leak   July 14, 2004 - 9am Central time zone
Reviewer: John Dunn from U.K.
I am using the following code to run unix commands. I have minimised the memory issues by including 
a call to the garbage collector, but occasionally it is returning a rc of 3. However I do not know 
how to output details of the exception. I would like to output the error details to a file. Can 
anyone help with that?

CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED "function_os_command" AS

import java.io.*;

import java.util.*;

public class function_os_command

{

public static int Run(String Command)

{

int rc = 0;

try

{

Runtime rt = Runtime.getRuntime();

Process p = rt.exec(Command);

try {

rc = p.waitFor();

} catch (InterruptedException intexc) { rc = 2; }

rt.gc();

} catch (Throwable t) { rc = 3; }

return(rc);

}

}

/

 


4 stars This Example is Not working On Oracle 9i R2 on Windows   July 14, 2004 - 11am Central time zone
Reviewer: Harshad Savot from Tanzania (East Africa)
 I have tried this example on Oracle 9i R2 Windows.

java.lang.ArrayIndexOutOfBoundsException
at Util.RunThis(Util:14).

What Should change in code so It can works on Windows Platform. Please give any example .
Thanks

Harshad  


Followup   July 14, 2004 - 12pm Central time zone:

ctl-f for arrayindexoutofbounds on this page.........  search for that word -- asked and answered. 

5 stars Having an issue calling a sqlplus shell...   July 23, 2004 - 9pm Central time zone
Reviewer: Kelly Taylor from Petaluma, CA USA
Tom,

I'm having a problem using run_cmd in my package for starting dynamic SQL*Plus sessions; I want to 
pass a connection string and PL/SQL block to a shell script for execution. Everything works fine 
when calling exp or others, which I've included below. I think it's a quoting problem but I can't 
seem to find a solution other than completely reformatting the SQL and using sed. If you would 
provide any insight or advice, I'd seriously appreciate it. :)  RDBMS/OS --> 9.2.0.4/Solaris 8

My code:
--
-- TEST TABLE
--
create table exp_test(id number(22));

--
-- THIS PROC WORKS SHOWING JAVA AND PERMS ARE CORRECT,
-- I USED YOUR LATEST CODE.
--
create or replace procedure run_exp(
    p_exp_conn     in  varchar2,                          -- USERID= 
    p_table_name   in  varchar2,                          -- TABLES= 
    p_dmp_file     in  varchar2,                          -- FILE= 
    p_log_file     in  varchar2 )                         -- LOG= 
is
--
-- Example call: 
--     exec run_exp('user/pass@sid',
--                  'exp_test',
--                  '/tmp/exp_test.dmp',
--                  '/tmp/exp_test.log');  
--
    l_exp_cmd      varchar2(2000) := '/tmp/run_exp.sh';
    l_return       number         := 0;
    
begin
    l_exp_cmd := l_exp_cmd ||'  "'|| p_exp_conn
                           ||'" "'|| p_table_name
                           ||'" "'|| p_dmp_file
                           ||'" "'|| p_log_file
                           ||'"'; 

    l_return := run_cmd(l_exp_cmd);
     
    if l_return = 0 then
        dbms_output.put_line('Exp session succeeded.');
    else
        dbms_output.put_line('Exp session failed.');
    end if;

exception
when others then
    raise;
end run_exp;
/
--
-- THIS IS THE PROBLEM PROC OR QUOTING PROBLEM
--
create or replace procedure run_sqlplus(
    p_sqlplus_conn     in  varchar2,
    p_sqlplus_qry      in  varchar2,
    p_spool_file       in  varchar2 )
is
--
-- Sample call: 
--     exec run_sqlplus('user/pass@sid',
--                      'begin dbms_output.put_line(''Hello''); end;',   
--                      '/tmp/run_sqlplus.log');  
--
    l_sqlplus_cmd      varchar2(2000) := '/tmp/run_sqlplus.sh';
    l_return           number         := 0;
    
begin
    l_sqlplus_cmd := l_sqlplus_cmd ||'   '|| p_sqlplus_conn
                                   ||'  "'|| p_sqlplus_qry
                                   ||'" "'|| p_spool_file
                                   ||'"';
                                   
    dbms_output.put_line(l_sqlplus_cmd);
                  
    l_return := run_cmd(l_sqlplus_cmd);
     
    if l_return = 0 then
        dbms_output.put_line('SQL*Plus session succeeded.');
    else
        dbms_output.put_line('SQL*Plus session failed.');
    end if;

exception
when others then
    raise;
end run_sqlplus;
/

--
-- SAMPLE SHELL SCRIPTS
--
#!/bin/sh
#
# run_exp.sh
# -------------------------
# 
echo userid = $1
echo tables = $2
echo file = $3
echo log = $4

exp userid=$1 tables=$2 file=$3 log=$4 statistics="none" direct="yes"

#!/bin/sh
#
# run_sqlplus.sh
# -------------------------
#
echo conn = $1
echo query = $2
echo spoolfile = $3

sqlplus -s /NOLOG << EOF
connect $1
set serverout on
spool $3
set timing on
begin
    $2
end;
/
spool off
exit
EOF

--
-- TEST sh SCRIPTS
--
$ /tmp/run_exp.sh "user/pass@sid" "exp_test" "/tmp/exp_test.dmp" "/tmp/exp_test.log"

result:
-------
. . exporting table                       EXP_TEST          0 rows exported
Export terminated successfully without warnings.

$ /tmp/run_sqlplus.sh "user/pass@sid" "begin dbms_output.put_line('Hello'); end;" 
"/tmp/run_sqlplus.log"

result:
-------
conn = user/pass@sid
query = begin dbms_output.put_line('Hello'); end;
spoolfile = /tmp/run_sqlplus.log
Connected.

Hello

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.16

--
-- TEST PROCS
--
set serveroutput on size 1000000
exec dbms_java.set_output(1000000);

SQL> exec run_exp('user/pass@sid', 'exp_test', '/tmp/exp_test.dmp', '/tmp/exp_test.log');

PL/SQL procedure successfully completed. (new dmp file and log were created)

SQL> exec run_sqlplus('user/pass@sid','begin dbms_output.put_line(''Hello''); 
end;','/tmp/run_sqlplus.log');
/tmp/run_sqlplus.sh   user/pass@sid  "begin dbms_output.put_line('Hello'); end;" 
"/tmp/run_sqlplus.log"
conn = user/pass@sid
query = "begin
spoolfile = dbms_output.put_line('Hello');
Connected.
ERROR:
ORA-01740: missing double quote in identifier
Elapsed: 00:00:00.00
SQL*Plus session succeeded.

PL/SQL procedure successfully completed. 


Followup   July 24, 2004 - 11am Central time zone:

whitespace will kill you everytime when you have sh's calling shells and so on.

easiest to just "avoid the issue"

user/pass@connect should never have whitespace
we'll make the reasonable assumption that your spool file name won't either

but the query will....

so arg1 and arg2 are "one word"
arg3 is the rest.  

we change the script to be:

#!/bin/sh
#
# run_sqlplus.sh
                                                                                                   
conn=$1
shift
spoolfile=$1
shift
query=$*
                                                                                                   
echo conn = $conn
echo query = $query
echo spool = $spoolfile
                                                                                                   
sqlplus -s /NOLOG << EOF
connect $conn
set serverout on
spool $spoolfile
set timing on
begin
    $query
end;
/
spool off
exit
EOF


and the plsql to be:

ops$tkyte@ORA9IR2> create or replace procedure run_sqlplus(
  2      p_sqlplus_conn     in  varchar2,
  3      p_sqlplus_qry      in  varchar2,
  4      p_spool_file       in  varchar2 )
  5  is
  6  --
  7  -- Sample call:
  8  --     exec run_sqlplus('user/pass@sid',
  9  --                      'begin dbms_output.put_line(''Hello''); end;',
 10  --                      '/tmp/run_sqlplus.log');
 11  --
 12      l_sqlplus_cmd      varchar2(2000) := '/tmp/run_sqlplus.sh';
 13      l_return           number         := 0;
 14
 15  begin
 16      l_sqlplus_cmd := l_sqlplus_cmd ||' '|| p_sqlplus_conn
 17                                     ||' '|| p_spool_file
 18                                     ||' '|| p_sqlplus_qry;
 19
 20      dbms_output.put_line(l_sqlplus_cmd);
 21
 22      l_return := run_cmd(l_sqlplus_cmd);
 23
 24      if l_return = 0 then
 25          dbms_output.put_line('SQL*Plus session succeeded.');
 26      else
 27          dbms_output.put_line('SQL*Plus session failed.');
 28      end if;
 29
 30  exception
 31  when others then
 32      raise;
 33  end run_sqlplus;
 34  /
 
Procedure created.
 
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> set serveroutput on
ops$tkyte@ORA9IR2> exec dbms_java.set_output(100000);
 
PL/SQL procedure successfully completed.
 
ops$tkyte@ORA9IR2> exec run_sqlplus('/', 'begin dbms_output.put_line(''Hello''); end;', 
'/tmp/run_sqlplus.log' );
/tmp/run_sqlplus.sh / /tmp/run_sqlplus.log begin dbms_output.put_line('Hello');
end;
conn = /
query = begin dbms_output.put_line('Hello'); end;
spool = /tmp/run_sqlplus.log
Connected.
Hello
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.00
SQL*Plus session succeeded.
 
PL/SQL procedure successfully completed.
 





 

4 stars More permissions problems   July 26, 2004 - 11am Central time zone
Reviewer: Mike from Vermont
Tom, this is great stuff.  As usual.  However, I've read all the various permissions solutions in 
the article so far, but am still having problems.

Calling ls, ps, etc all works great.  However, I cannot get any user scripts to run.  I created a 
test script in the Oracle users home directory, owned by Oracle (who also owns and started the 
database) and checked the execute permissions.  Script runs fine at the command line as Oracle, but 
I get nothing in SQL*Plus and nothing in my debug.txt file when I run it via pl/sql.  I granted 
permissions on /usr/bin/whoami just to verify that Oracle is the user executing these scripts and 
it is.

Here's my test script:
ls
echo "This is a test..."
date > debug.txt

Any additional thoughts?  I'm stumped. 


Followup   July 26, 2004 - 1pm Central time zone:

put a #!/bin/sh at the top, and echo $PATH and other things, check out the environment. 

5 stars Thanks!   July 26, 2004 - 1pm Central time zone
Reviewer: Mike from Vermont
#!/bin/sh solves the problem.  Obviously didn't even think of that one.  Sorry to bug you with 
something so simple. 


5 stars run remotely   October 18, 2004 - 3am Central time zone
Reviewer: fz 
It runs fine locally, but the result does not show up when running remotely through a db_link.  did 
I miss sth?

LOCAL:
SQL> exec rc('/bin/sar -u 3 3');
....
23:54:34    %usr    %sys    %wio   %idle
23:54:37       0       2       2      96
23:54:40       0       0       2      98
23:54:43       0       0       1      99
Average        0       1       1      98
PL/SQL procedure successfully completed.

REMOTE:
SQL> set serveroutput on size 1000000
SQL> exec dbms_java.set_output(1000000)
PL/SQL procedure successfully completed.
SQL> exec rc@xxx('/bin/sar -u 3 3');
PL/SQL procedure successfully completed.
SQL>

 


Followup   October 18, 2004 - 8am Central time zone:

when you run the remote procedure -- its "dbms_output" stuff (java output stuff) goes to the REMOTE 
dbms_output package too. 

sqlplus runs dbms_output.get_lines() after each statement to see if there is anything to print -- 
there isn't anything "local".  It doesn't know to look at dbms_output@xxx to get the output.

You'd have to do that yourself -- call dbms_output@xxx to get the lines and use the "local" 
dbms_output to print them. 

4 stars Is calling Unix shell from Java sp a reliable way in prod?   October 18, 2004 - 2pm Central time zone
Reviewer: Mark Gokman from Stamford CT
In reference to the original question and examples in this thread. Is this a safe and reliable way 
of communicating with the OS? I'm not that familiar with JVM in general and the way Oracle runs it, 
but if JVM is a part of Oracle kernel, then allowing the application to talk almost directly to the 
OS seems to be strange. For example, what if i call a shell script that changes the structure of 
the database, or something else that can affects the entire instance? Is there any protection 
against such operations?
 


Followup   October 19, 2004 - 7am Central time zone:

what if you call a stored procedure that alters the structure of the database??
what if you call a stored procedure that affects the entire instance??


not sure what you are concerned about -- YOU write the script, YOU own the script.  the script does 
what you told it to do.  This is no less safe than running a pro*c application as Oracle on the 
database server (well, wait, it is probably lots more safe) 

1 stars Why is it more secure?   October 19, 2004 - 1pm Central time zone
Reviewer: mark Gokman from Stamford CT
Could you please explain why running os calls from Java sp is more secure and safe than running 
pro*c on the server as Oracle?  


Followup   October 19, 2004 - 1pm Central time zone:

Pro*c running on the server as Oracle can issue:

  system( "rm -rf /home/oracle/" );


Java stored procedures can only run RM if the DBA has said "ok, you can run rm", you have the 
ability to grant execute on individual OS programs to java stored procedures.  

A C program can run anything it wants.

Heck, the C program running as Oracle could attache the SGA if it felt like it (fun stuff maybe...)


you have very very granual access control over the java stored procedure, making it more securable 
(as long as you don't grant access to "*" or something. 

4 stars How can pass the parameters ?   October 20, 2004 - 5pm Central time zone
Reviewer: raman 
Hello Tom,

This topic has given me an idea how I can execute host calls from PL/SQL in Oracle server. Finally, 
I am using like this:

SET SERVEROUTPUT ON SIZE 1000000
CALL DBMS_JAVA.SET_OUTPUT(1000000);
BEGIN
  Host_Command (p_command => 'sdelayer -o delete -l TRM_RP_GEOMETRICS_MV,GEOMETRY -i esri_sde9i -s 
jj00WB316 -u gisteam -p gisteam -N -q');
END;
/

It does SDE registration in Oracle Spatial database.

Table name: TRM_RP_GEOMETRICS_MV
Column Name: Geometry
Username:GISTEAM
Pwd:GISTEAM
Database: JJ00WB316

It is executed successfully. I have to execute such Host_Command procedure 12 times in part of a 
PL/SQL script for different purposes.

Like that, I have 40 PL/SQL scripts with different table name,column name etc...

Now, I would like to create a procedure which will accept the parameters like tablename,columnname 
etc....pass them to HOST_COMMAND procedure to execute the DOS command. So, that I don't need to 
maintain in those 40 scripts.

So, how can I make the HOST_COMMAND procedure accept these parameters?? 

Example:
CREATE OR REPLACE PROCEDURE A (TABLENAME,COLUMNNAME)
AS
BEGIN
  
Host_Command (p_command => 'sdelayer -o delete -l <TABLENAME>,<COLUMNNAME> -i esri_sde9i -s 
jj00WB316 -u gisteam -p gisteam -N -q');


Host_Command (...);
Host_Command (...);
..
..
End;



It would be very helpful to me, if you could give me a solution.

regards,
-raman 


Followup   October 20, 2004 - 8pm Central time zone:

... p_command => 'sdelayer -o delete -l ' || l_table_name || ',' || l_column_name || ' -i ....


just concatenate them into the string. 

4 stars   October 25, 2004 - 11am Central time zone
Reviewer: raman from TN,USA
Thankyou verymuch ... 


5 stars but what about this....   November 25, 2004 - 9am Central time zone
Reviewer: Roel from Netherlands
I created a java program and wrapped it in PL/SQL. I would like to use it to unzip a certain file:

In SQLPLUS > 
exec host.run('/bin/unzip -L /app/dphrmo/pvc/f0016741.113 -d /app/dphrmo/pvc/');

Archive:  /app/dphrmo/pvc/f0016741.113

PL/SQL-procedure succesfully completed.

But no extraction is made. When I execute the complete command at the Unix prompt the unzip is 
succesful. When I try to unzip a file - in PLSQL - that already exists, the program 'hangs' 
logically, because it's waiting to enter a Yes/No/Cancel action for overwriting.

But why is the unzip-action not succesfull? 


Followup   November 25, 2004 - 10am Central time zone:

umm, hows about the entire example.  for all i know you are catching and hiding all errors in your 
java program. 

4 stars   November 26, 2004 - 3am Central time zone
Reviewer: Roel from Netherlands
The entire (java) program is:

CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "Host" AS
import java.io.*;
  import java.sql.*;
  import java.util.*;

  public class Host
  {
   public static void Dir(String directory)
                      throws SQLException
   {
     File path = new File( directory );
     String[] list = path.list();
     String element;

     for(int i = 0; i < list.length; i++)
     {
       element = list[i];
       #sql { INSERT INTO DIR_LIST (FILENAME)
              VALUES (:element) };
     }
   }

    public static int Run(String Command)
    {
     Runtime rt = Runtime.getRuntime();
     int     rc = -1;
     try
     {
       Process p = rt.exec(Command);

       int bufSize = 4096;
       BufferedInputStream bis =
         new BufferedInputStream( p.getInputStream(), bufSize );
       int len;
       byte buffer[] = new byte[ bufSize ];
       // Echo back what the program spit out
       while (( len = bis.read(buffer, 0, bufSize)) != -1 )
          System.out.write(buffer, 0, len);
       rc = p.waitFor();
     }
     catch (Exception e)
     {
       e.printStackTrace();
       rc = -1;
     }
     finally
     {
       return rc;
     }
    }
   }
/


So (IMHO) the errors are catched but not hided...
Before running the PL/SQL command I also ran:
>exec dbms_java.set_output(1000000)

So what can be wrong?
 


Followup   November 26, 2004 - 9am Central time zone:

add debug -- lots of System.out.println's and make sure you can see them.

did you set serveroutput on as well? 

5 stars Solved!   November 26, 2004 - 10am Central time zone
Reviewer: Roel from Netherlands
I moved the p.waitFor() direct after the exec(Command) and read out the ErrorStream. Apparently the 
user (Oracle?) was not allowed to write in the specified directory....

Now it works! Thanx a lot!
 


1 stars Run Java program at Unix file system using Java Stored Procedure using same example.   December 8, 2004 - 6pm Central time zone
Reviewer: Mayank from Viginia, USA
I tried the same steps mention by you and grant permissions to all the files.

I am able to run a shell script which contains unix commands, but I am not able to run a small 
HelloWorld Java program from the shell script.

I want to run a java program from the shell script and call that shell script from the stored 
procedure in question.



 


Followup   December 9, 2004 - 12pm Central time zone:

then you need to figure out why?

your environment is most likely NOT AT ALL what you think it is.  Your path is going to be Oracle's 
path, your environment is going to be Oracle's environment.


read the followup above that can be found by ctl-f'ing for

ran as ORACLE

on this page. 

2 stars   December 8, 2004 - 6pm Central time zone
Reviewer: Mayank from Virginia, USA
SQL> exec rc('/usr/bin/sh /home/dhscrp/pass.sh');
run_cmd returned : 1   for /usr/bin/sh /home/dhscrp/pass.sh

PL/SQL procedure successfully completed.
------------------------------------------------
create or replace procedure RC(p_cmd in varchar2)
as
x number;
begin
    x := run_cmd(p_cmd);
    --execute immediate('set serveroutput on size 1000000');
    --dbms_java.set_output(1000000);
    DBMS_OUTPUT.PUT_LINE ( 'run_cmd returned : '||rpad(x, 3, ' ')||' for '||p_cmd);
end;
/

----------------------------------------------------
SQL> create or replace function RUN_CMD( p_cmd  in varchar2) return number
  2  AUTHID CURRENT_USER as  language java
  3  name 'OSUtil.RunThis(java.lang.String) return integer';
  4  /


-------------------------------------------------------

create or replace and compile java source named "OSUtil" as
  import java.io.*;
  import java.lang.*;
  public class OSUtil extends Object
  {
    public static int RunThis(String args)
    {
         Runtime rt = Runtime.getRuntime();
         int        rc = -1;
         try
         {
            Process p = rt.exec(args);
            int bufSize = 4096;
            BufferedInputStream bis =
            new BufferedInputStream(p.getInputStream(), bufSize);
            int len;
             byte buffer[] = new byte[bufSize];
           // Echo back what the program spit out
            while ((len = bis.read(buffer, 0, bufSize)) != -1)
           System.out.write(buffer, 0, len);
              rc = p.waitFor();
      }
      catch (Exception e)
      {
        e.printStackTrace();
        rc = -1;
      }
      finally
      {
         return rc;
      }
     }
   }
/
-------------
I used the same to call a shell script contains java commands to run one java class from Unix OS. 
It is not doing any thing though it is working for the shell script which contains unix commands 
only.
 


Followup   December 9, 2004 - 12pm Central time zone:

see above 

5 stars   December 16, 2004 - 1pm Central time zone
Reviewer: Tom you are the best!!! from Richmond ,usa
Tom,
Host command via java stored procedures works fine for us.But each time it generates a .trc (trace 
files) in user dump destination like show below.How we can stop generating this sort of trace 
files?

dump file c:\oracle\admin\reds\udump\reds_ora_11844.trc
Thu Dec 16 13:10:56 2004
ORACLE V9.2.0.5.0 - Production vsnsta=0
vsnsql=12 vsnxtr=3
Windows 2000 Version 5.2 , CPU type 586
Oracle9i Enterprise Edition Release 9.2.0.5.0 - Production
With the OLAP and Oracle Data Mining options
JServer Release 9.2.0.5.0 - Production
Windows 2000 Version 5.2 , CPU type 586
Instance name: reds

Redo thread mounted by this instance: 1

Oracle process number: 33

Windows thread id: 11844, image: ORACLE.EXE


*** 2004-12-16 13:10:56.590
*** SESSION ID:(35.2353) 2004-12-16 13:10:56.497


C:\oracle\ora92\DATABASE>cmd /k "c:\reds_lims_labels\print_commands\warehouse_medium.cmd 
C:\reds_lims_labels\13105656CHENNK.lbl > c:\reds_lims_labels\warehouse_medium.log" 

 


Followup   December 16, 2004 - 1pm Central time zone:

you didn't open up cmd did you???


keys, kingdom come to mind -- you didn't dbms_java and give permissions on cmd? 

5 stars as usual you are the best tom   December 16, 2004 - 2pm Central time zone
Reviewer: you are the best tom from Richmond
.cmd file is working via this java procedure.Can we turn off the trace file generations? 


Followup   December 16, 2004 - 3pm Central time zone:

i'm talking about 

...> cmd /k ...


are you using cmd????!?  that would be "the keys to the kingdom". 

5 stars   December 16, 2004 - 3pm Central time zone
Reviewer: A reader 
Thanks! We didn't give permission on cmd /k .
We only gave execute permission on the following file.
c:\reds_lims_labels\print_commands\warehouse_medium.cmd .



 


Followup   December 16, 2004 - 5pm Central time zone:

why do i see cmd /k in there then?

C:\oracle\ora92\DATABASE>cmd /k 
"c:\reds_lims_labels\print_commands\warehouse_medium.cmd 
C:\reds_lims_labels\13105656CHENNK.lbl > 
c:\reds_lims_labels\warehouse_medium.log" 

?

but all you are seeing is the system.out. stuff -- meaning, you didn't call the dbms_java.setoutput 
to redirect stdout to the dbms_output buffer.

if you run the example "as is" from sqlplus - do you get the trace file then? 

5 stars   December 16, 2004 - 4pm Central time zone
Reviewer: A reader 
Let me explain again.Sorry I din't make it clear.

We didn't give direct permission to cmd /k .

We gave permission to execute the following file

c:\reds_lims_labels\print_commands\submit_warehouse_medium.cmd

submit_warehouse_medium.cmd has the following lines :

cmd /k "c:\reds_lims_labels\print_commands\warehouse_medium.cmd %1 > 
c:\reds_lims_labels\warehouse_medium.log"

Thanks Tom! Do we have anyway to turn off these trace file generations. 


Followup   December 16, 2004 - 5pm Central time zone:

ok, do you have the stdout redirection going -- do you see this if you run the example as is from 
sqlplus with all of the commands I've got there. 

5 stars   December 17, 2004 - 2pm Central time zone
Reviewer: A reader 
SQL> execute dbms_java.set_output(99999);

PL/SQL procedure successfully completed.

SQL> set serverout on;
SQL> variable a number;

SQL> execute :a := java_mail_stuff.run_cmd('c:\reds_lims_labels\print_commands\call_ware
.cmd c:\reds_lims_labels\13032121AGARWALAR.lbl');
C:\oracle\ora92\DATABASE>cmd /k
"c:\reds_lims_labels\print_commands\warehouse_medium.cmd
c:\reds_lims_labels\13032121AGARWALAR.lbl >
c:\reds_lims_labels\warehouse_medium.log"

PL/SQL procedure successfully completed.


It didn't generate the trace file when I execute it from the sqlplus. Thanks! 


Followup   December 17, 2004 - 3pm Central time zone:

you needed to redirect system.out ... 

5 stars   December 17, 2004 - 4pm Central time zone
Reviewer: A reader 
Did you mean that if we do "2>>&1 " like shown below then it would not generate the trace files?

cmd /k "c:\reds_lims_labels\print_commands\warehouse_medium.cmd %1 > 
c:\reds_lims_labels\warehouse_medium.log" 2>>&1  
 


Followup   December 18, 2004 - 8am Central time zone:

no, i mean the dbms_java setoutput command redirected the system.out stuff to "dbms_output", by 
default, that stuff goes to the tracefile.

did you see how in sqlplus you saw on the screen what you normally see in the trace file? 

5 stars Is it a good idea starting backup script using this technique   December 18, 2004 - 7pm Central time zone
Reviewer: A reader from Turkey
I have writen a Java SP to run a host script as mentioned above, and this scripts starts my backup 
script (since SP waits for the first script to end I wrote an intermadiate script). I have 
scheduled the SP to start my backup script using DBMS_JOB. All works fine. 
Before going to distribute it to 2046 Oracle sites, I want to ask that, is this a good idea for 
starting backup using this technique? 


Followup   December 19, 2004 - 10am Central time zone:

People typically use scripts outside of the database (eg: via rman or someother backup utility) to 
do this.  It would be unusual to initial the backup from inside the database.


Not having reviewed you code (not saying that we want youy to post it all here!) I cannot say if 
this is a good idea (tm) or not.  If you have tested this 100% and have a backout plan in place, 
sure. 

4 stars   December 20, 2004 - 8pm Central time zone
Reviewer: A reader from Turkey
Thank you for your response.

We have more than 2000 oracle remote sites. Operators of these sites even don't know (and dont 
care) if they have a DB. We have to perform backups on behalf of the site users.
The users' creativity on destruction  made the simple backup script to a backup and one click 
recovery program. 

Most of the sites have only one computer, so rman cannot be used. Using third party backup tools is 
not feasable for small sites. 

Therefore we have to use the backup scripts. The problem comes out managing start time of backup 
(If we dont start backups, clients never take a backup). Scheduling backup using OS tools (eg. at 
command) needs administrator password that users dont know, even if they know it is hard to force 
them to schedule. But scheduling using Oracle job is as simple as running a sql script.

I know scheduling backup using oracle jobs is unusual, that is why I am asking if it is a good 
idea.

I don't know if here is the right place for the story. Any way here is the code that I use.

------------------------------------------------------------
the java code
------------------------------------------------------------
import java.io.*;

public class Dba {
  public Dba() {
  }

  public static void main(String[] args) {
    Dba dba = new Dba();
    String arg="";
    System.out.println(args[0]);
    if (args.length>0) arg=args[0];
    runDba(arg);
  }

  public static void runProcess (String program){
    Process proc;
    Runtime rt;

    rt = Runtime.getRuntime();
    try {
      proc = rt.exec(program);  
      Thread.sleep(1000);  
    }
    catch (Exception ex) {
      ex.printStackTrace();
    }

  }

  public static void runDba(String param){
    runProcess(param);
  }

}
------------------------------------------------------------
load java -user <username>/<password> Dba.class
------------------------------------------------------------

create or replace procedure jrun(param varchar2)
as language java
name 'Dba.runDba(java.lang.String)';
/

------------------------------------------------------------
startbackup.bat
------------------------------------------------------------
c:
cd c:\
start %1 %2 %3 (%2 & %3 are optional parameters)
exit
------------------------------------------------------------
backup.bat
------------------------------------------------------------

c:
cd c:\
@setlocal
set CommonProgramFiles=C:\Program Files\Common Files
set COMPUTERNAME=IBRAHIM
set HOMEDRIVE=C:
set HOMEPATH=\Documents and Settings\iozturk
set LOGONSERVER=\\IBRAHIM
set OS=Windows_NT
set Os2LibPath=C:\WINNT\system32\os2\dll;
set Path=C:\Program 
Files\Java\jdk1.5.0\bin;D:\oracle\product\10.1.0\db\bin;D:\oracle\product\10.1.0\db\jre\1.4.2\bin\cl
ient;D:\oracle\product\10.1.0\db\jre\1.4.2\bin;C:\jdk1.5.0\jre\bin;C:\j2sdk1.4.2_05\jre\bin;D:\JBuil
derX\jdk1.4\bin;C:\WINNT\system32;C:\WINNT;C:\WINNT\System32\Wbem;C:\Program 
Files\Symantec\pcAnywhere\;D:\JBuilderX\jdk1.4\bin;D:\Program Files\Adabas\bin;D:\Program 
Files\Adabas\pgm; D:\Program Files\StarOffice7\program;
set PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH
set ProgramFiles=C:\Program Files
set SystemDrive=C:
set SystemRoot=C:\WINNT
set TEMP=C:\DOCUME~1\iozturk\LOCALS~1\Temp
set TMP=C:\DOCUME~1\iozturk\LOCALS~1\Temp
set USERDOMAIN=IBRAHIM
set USERNAME=iozturk
set USERPROFILE=C:\Documents and Settings\iozturk
C:\j2sdk1.4.2_05\bin\java -cp 
"%HOMEPATH%\dba_scripts\bin;%HOMEPATH%\dba_scripts\bin\lib\jbcl.jar;%HOMEPATH%\dba_scripts\bin\lib\c
lasses12.jar;%HOMEPATH%\dba_scripts\bin\lib\jdom.jar" dbaController.DbaController backup
REM C:\j2sdk1.4.2_05\bin\java -cp 
C:\dba_scripts\bin;c:\dba_scripts\bin\lib\jbcl.jar;C:\dba_scripts\bin\lib\classes12.jar;c:\dba_scrip
ts\bin\lib\jdom.jar dbaController.DbaController backup
@endlocal
exit

------------------------------------------------------------

finally schedule it to every friday at 19 PM

VARIABLE jobno NUMBER 
BEGIN
   DBMS_JOB.SUBMIT(:jobno, 
      'jrun(''c:\startbackup.bat c:\backup.bat OraLisener stop'');', 
      SYSDATE, 'NEXT_DAY(TRUNC(SYSDATE), ''CUMA'') + 19/24');
   COMMIT;
END;
/
------------------------------------------------------------



 


Followup   December 20, 2004 - 8pm Central time zone:

<quote>
I know scheduling backup using oracle jobs is unusual, that is why I am asking 
if it is a good idea.
</quote>


the definition of catch-22 here....

It is unusual, therefore I have no real experience with it, hence I cannot commit to saying "good 
thing" or "bad thing".

I'd probably rather (especially with 2000 of these things) rather have a program that is a little 
more "in tune with what is happening".  How can you tell if this worked or not?


So, using dbms_job -- probably OK

but using a bat file?  probably not ok, i'd want something more sophisticated.  Maybe your actual 
backup program is, but I cannot see that here.  I'd want a log reported into a central repository 
or something. 

4 stars partly successful, but running into a problem   February 5, 2005 - 11am Central time zone
Reviewer: Anurag Mehrotra 
In the past I have successfully implemented the solution mentioned here, now I am trying to take it 
to the next level.

I am trying to generate Sql loader control file and shell script (on Unix platform) based on 
parameters passed to a sp and then call the solution mentioned here to launch the shell script.

At first I was running into the following problem:
java.security.AccessControlException: the Permission (java.io.FilePermission <<ALL FILES>> execute 
has not been granted.

I resolved this by granting the following permision:
dbms_java.grant_permission
    ('IMPORTUSER', 
    'SYS:java.io.FilePermission',
      '<<ALL FILES>>', 
    'read,write,execute')

In order to execute the generated shell script, I need to assign the 'x' privilege at the os level, 
so I granted the following privilege:

dbms_java.grant_permission
    ('IMPORTUSER',
    'java.io.FilePermission',
    '/usr/bin/chmod',
    'execute');

In spite of all this when I issue the chmod command, and try to launch the shell script, it does 
nothing:

cmd_return_code := osCommandRun('chmod 744 ' || v_FileDirectory || '/' || v_ShFileName );

  cmd_return_code := osCommandRun(v_FileDirectory || '/' || v_ShFileName || ' ' || 
            v_CtlFileName || ' ' || a_Data_File_Name );

Sqlplus simply reports "PL/SQL procedure successfully completed", but the permission is neither 
changed nor the shell script is executed.

Am I missing something here?

 


Followup   February 5, 2005 - 11am Central time zone:

why aren't you just using the much easier external table capability???


lauching shell scripts -- and not having them work -- always means "your environment isn't at all 
what you anticipated"

remember, it is NOT your environment
it is NOT your shell.
it is not alot of things


but --tell me, why no external tables?  

4 stars followup about shell script   February 5, 2005 - 11am Central time zone
Reviewer: Anurag Mehrotra 
I would have loved to use external tables, but using external tables is not an options.

Damn Corporate security standards. External tables are not on the approved list.

In the meantime I added some debugging statements right as follows:

  cmd_return_code := osCommandRun('chmod 744 ' || v_FileDirectory || '/' || v_ShFileName );


DBMS_OUTPUT.PUT_LINE('chMod Command= ' ||  to_char(cmd_return_code));

  cmd_return_code := osCommandRun(v_FileDirectory || '/' || v_ShFileName || ' ' || 
            v_CtlFileName || ' ' || a_Data_File_Name );

DBMS_OUTPUT.PUT_LINE('SqlLoader Launch Command= ' ||  to_char(cmd_return_code));


both return the code of 255.
 


Followup   February 6, 2005 - 3am Central time zone:

it is always an option.


would you mind pointing out to the security dudes that external tables are somewhat SAFER then 
permitting you to run a script as "oracle", on the OS, able to do anything "oracle" is allowed to 
do, including rm -rf $ORACLE_HOME

your script is not running due to differences in the environment, could be as simple as "i don't 
know what shell to run" - eg: a missing #!/bin/sh for exmaple....  to the environment is not really 
setup right.


start small, just try to get:

#!/bin/sh
env


to run or something.  

3 stars problem somewhat isolated   February 6, 2005 - 9am Central time zone
Reviewer: Anurag Mehrotra 
I will again try to convince the security team about external tables.

I can successfully execute any shell script from within a PL/Sql procedure as mentioned here as 
long as it has the ‘x’ (execute) privilege set for oracle.

My problem is that I have to create shell script and the control file on the fly (within the stored 
procedure), I need to first make it ‘x’ executable to be able to run it.

In spite of granting exclusive ‘x’ privilege on ‘chmod’ it does not change the permission and hence 
cannot execute the shell script.  I get a return code of 255 as opposed to 0.

cmd_return_code := osCommandRun('chmod 744 ' || v_FileDirectory || '/' || v_ShFileName );

If I change the permission to 744 for the same file manually at the os level, and re-run the stored 
procedure, asking for the same file name to be generated, it preserves the execute permission and 
the successfully executes the shell script to launch the sql loader.

This makes me believe that I am having some trouble running ‘chmod’ command due to some file 
permissions.

Any ideas? 
 


4 stars figured my problem   February 6, 2005 - 1pm Central time zone
Reviewer: Anurag Mehrotra 
I finally figured out my problem:

I had granted the following java permission: 

dbms_java.grant_permission
    ('IMPORTUSER',
    'java.io.FilePermission',
    '/usr/bin/chmod',
    'execute');

but the command to change the permission would not work.

  cmd_return_code := osCommandRun('chmod 744 ' || v_FileDirectory || '/' || v_ShFileName );

so I changed the command to:

  cmd_return_code := osCommandRun('/usr/bin/chmod 744 ' || v_FileDirectory || '/' || v_ShFileName 
);

All I did was to prefix chmod with /usr/bin/ and it started working. Even though 'oracle' path was 
setup correctly with /usr/bin:/usr/ccs/bin:/usl/local/bin: and so on.

I am thinking that when an OS command is executed from within PL/Sql Procedure, it runs in it's own 
shell and does not inherit any environment/path variables of the parent (in this case 'oracle' 
user).

Please correct me if I am wrong here.



 


Followup   February 7, 2005 - 3am Central time zone:

/usr/bin/chmod <> chmod

that was the cause.  if you granted yourself chmod, chmod would work.  you granted /usr/bin/chmod, 
not chmod, so only /usr/bin/chmod will work (if you are specific in one place, you must be so in 
others)


it makes me laugh in a sad way that your "security" team lets you create any arbitrary shell script 
and execute it as Oracle - but you cannot use external tables.


How sad and misguided is that.  There is zero percent chance I would let anyone create a shell 
script on the fly like that in real life.  How dangerous is that?  How insecure is that?  How 
totally POWERFUL is that ability.  You can do pretty much anything you want (on purpose by by 
accident!!!!!) 

5 stars Trying to exeute a batch file that calls windows scheduler 'AT'   February 7, 2005 - 10am Central time zone
Reviewer: Steve Montgomerie from fl
Tom,
I am using your procedure here with some success.
I have tested with a simple batch file that does time /t>> c:\temp\test.log. That works fine. 

What I want to do is to schedule a job to run on another server 
through windows AT. For this my batch file contents looks like 'at \\AAAAAAAA 10:34 
C:\TEMP\STOP_APP_SERVER.BAT'. I can run this through the command line and also double click the 
batch file to schedule the job. When Oracle however executes the batch file it does not get 
scheduled - the procedure completes to success but no joy on the scheduling. 

I execute it through Oracle like so


SQL> variable x number;
SQL> set serveroutput on
SQL> exec dbms_java.set_output(100000);

PL/SQL procedure successfully completed.

SQL> exec :x := RUN_CMD('C:\TEMP\SCHEDULE_APP_SERVER_SHUT.BAT');
D:\oracle\ora92\DATABASE>at \\orlq1aza 14:26 C:\TEMP\STOP_APP_SERVER.BAT

PL/SQL procedure successfully completed.

SQL> commit; 


Followup   February 7, 2005 - 11am Central time zone:

on windows -- the oracle process is executing as a very "low privileged" user.  Not as "you", not 
as "admin" - as a very low privileged user.

Ask your windows experts onsite how a service running as a low privileged user can get access to 
remote services

( i would suggest you don't get too carried away with this, this is not looking like a "robust" 
implementation, there are lots of real job scheduling tools out there -- enterprise manager for 
example, with error handling and so on) 

3 stars mapping a network drive on windows within a procedure   February 10, 2005 - 4pm Central time zone
Reviewer: Justin from PA
Tom,

I am trying to map a network drive from within a stored proc.

Here is what I have done and what I get at the end:

1) Run these as sys

exec 
dbms_java.grant_permission('PHAME','java.io.FilePermission','C:\WINDOWS\system32\net.exe','execute')
;

exec dbms_java.grant_permission('PHAME','java.lang.RuntimePermission','*','writeFileDescriptor' );

2) run this as our schema owner

    create or replace and compile
    java source named "Util"
    as
    import java.io.*;
    import java.lang.*;

    public class Util extends Object
    {
      public static int RunThis(String args)
      {
      Runtime rt = Runtime.getRuntime();
      int        rc = -1;

      try
      {
          Process p = rt.exec(args);

          int bufSize = 4096;
          BufferedInputStream bis =
            new BufferedInputStream(p.getInputStream(), bufSize);
          int len;
          byte buffer[] = new byte[bufSize];

          // Echo back what the program spit out
          while ((len = bis.read(buffer, 0, bufSize)) != -1)
              System.out.write(buffer, 0, len);

          rc = p.waitFor();
      }
      catch (Exception e)
      {
          e.printStackTrace();
          rc = -1;
      }
      finally
      {
          return rc;
      }
      }
    }
/

3) run this as our schema owner
    create or replace procedure call_net_use(p_cmd in varchar2)
    as
      x number;
    begin
      x := NET_USE(p_cmd);
    end;
/

4) run this as our schema owner
    exec call_net_use('net use j: \\servername\d$ password /user:domain\username');

(  The net use command works at the command line of the database server (I have changed the parms 
to be generic))

I get:

java.security.AccessControlException: the Permission (java.io.FilePermission <<ALL FILES>> execute) 
has not been granted to PHAME. The PL/SQL to grant this is dbms_java.grant_permission( 'PHAME',
'SYS:java.io.FilePermission', '<<ALL FILES>>', 'execute' )

Do you see the problem?

Thanks very much! 


Followup   February 11, 2005 - 7pm Central time zone:

sorry -- not even going to try to touch this one.  network shares and stuff like that under windows 
is just plain "magic, especially when you involve an underprivileged service like the Oracle 
service"

services make everything a little different.


that command line test -- totally unrelated to the security/privilege environment the database is 
running as.


I'm thinking "you don't want to do this" -- really. 

3 stars ok.. thanks for the input   February 14, 2005 - 9am Central time zone
Reviewer: Justin from PA


5 stars Works like a charm!!!   March 8, 2005 - 6pm Central time zone
Reviewer: Deepak Haldiya from FL, USA
Hi Tom,

I have been using the code from this thread. It works great!!!

We have a tmp folder from which we want to delete all the files after certain operation. 

When I use 

exec :x := RUN_CMD('/usr/bin/rm /tmp/xyz.txt') ;

if works fine. 

But what I really like to run is 
exec :x := RUN_CMD('/usr/bin/rm /tmp/*.txt') ;

to delete all the files from the tmp foler. This does not work. 

Any suggestions!!! 


Followup   March 8, 2005 - 7pm Central time zone:

define "does not work" 

3 stars   March 9, 2005 - 10am Central time zone
Reviewer: Deepak Haldiya from FL, USA
when I meant by "does not work" is that '/usr/bin/rm *.txt' passed as an argument to RUN_CMD does 
not delete a single file from /tmp folder. Although the procedure successfully completes and i do 
not get anything in DBMS JAVA OUTPUT.

If I pass the '/usr/bin/rm xyz.txt' then the procedure deletes the file from xyz.txt from the tmp 
folder.

Thanks

 


Followup   March 9, 2005 - 12pm Central time zone:

so, sounds like the * isn't getting expanded because it isn't going through a "shell" and the shell 
expands * and ?.


it tried to delete a file named "*.txt"


the safest solution is to not use * or ? -- for to fix this, we might have to use a shell script 
and that gets nasty (security wise) 

4 stars See Erdal's link above   March 9, 2005 - 1pm Central time zone
Reviewer: andrew from usa
This link from Erdal (above) might help Deepak: 
http://www.mountainstorm.com/publications/javazine.html


Followup   March 9, 2005 - 1pm Central time zone:

please -- consider the ramifications of /bin/sh access!!!!!

think about it, that is why I specifically say "safe" above.


(you want to give an Oracle shell to everyone? think of what can happen) 

5 stars OS from Jave store procedure   March 22, 2005 - 2pm Central time zone
Reviewer: Laxman Kondal from Springfield, VA
<code>Hi Tom

I read you book and this page and wanted to create Java OS command to do export and landed up in many errors.

This one is the one I can not figure out and need your help.
Oracel 9R2 on Redhat Server2.1 and client from where I ran this Windows XP.

I search this page for dbms_java.grant_permission and unable to figure out my own mistake.


scott@TUNE> connect sys/xxxx@TUNE as sysdba;
Connected.
scott@TUNE> begin
2    dbms_java.revoke_permission
3    ('SCOTT',
4      'java.io.FilePermission',
5      '/opt/oracle/9.2.0.1.0/bin/exp',
6      'execute');
7
8    dbms_java.revoke_permission
9    ('SCOTT',
10    'java.lang.RuntimePermission',
11    '*',
12    'writeFileDescriptor' );
13 end;
14 /

PL/SQL procedure successfully completed.

scott@TUNE> rem show err
scott@TUNE> show err
No errors.
scott@TUNE> begin
2    dbms_java.grant_permission
3    ('SCOTT',
4      'java.io.FilePermission',
5      '/opt/oracle/9.2.0.1.0/bin/exp',
6      'execute');
7
8    dbms_java.grant_permission
9    ('SCOTT',
10    'java.lang.RuntimePermission',
11    '*',
12    'writeFileDescriptor' );
13 end;
14 /

PL/SQL procedure successfully completed.

scott@TUNE> show err
No errors.
scott@TUNE> connect scott/tiger@TUNE
Connected.
scott@TUNE> create or replace and compile
2    java source named "Util"
3    as
4    import java.io.*;
5    import java.lang.*;
6
7    public class Util extends Object
8    {
9    public static int RunThis(String args)
10    {
11    Runtime rt = Runtime.getRuntime();
12    int    rc = -1;
13
14    try
15    {
16      Process p = rt.exec(args);
17
18      int bufSize = 4096;
19      BufferedInputStream bis =
20      new BufferedInputStream(p.getInputStream(), bufSize);
21      int len;
22      byte buffer[] = new byte[bufSize];
23
24      // Echo back what the program spit out
25      while ((len = bis.read(buffer, 0, bufSize)) != -1)
26        System.out.write(buffer, 0, len);
27
28      rc = p.waitFor();
29    }
30    catch (Exception e)
31    {
32      e.printStackTrace();
33      rc = -1;
34    }
35    finally
36    {
37      return rc;
38    }
39    }
40  }
41 /

Java created.

scott@TUNE> show err
No errors.
scott@TUNE> create or replace
2    function RUN_CMD( p_cmd in varchar2) return number
3    as
4    language java
5    name 'Util.RunThis(java.lang.String) return integer';
6 /

Function created.

scott@TUNE> show err
No errors.
scott@TUNE> create or replace procedure RC(p_cmd in varchar2)
2    as
3    x number;
4    begin
5    x := run_cmd(p_cmd);
6    end;
7 /

Procedure created.

scott@TUNE> show err
No errors.
scott@TUNE> create or replace procedure run_exp(p_exp_cmd varchar2)
2 is
3
4    l_exp_cmd    varchar2(500);
5    l_return    number      := 0;
6
7 begin
8    --
9    l_return := run_cmd(p_exp_cmd);
10    --
11    if l_return = 0 then
12      dbms_output.put_line('Export session succeeded.');
13    else
14      dbms_output.put_line('Export session failed.');
15    end if;
16
17 exception
18    when others then
19      raise;
20 end run_exp;
21 /

Procedure created.

scott@TUNE> show err
No errors.
scott@TUNE> set serveroutput on size 1000000
scott@TUNE> exec dbms_java.set_output(1000000)

PL/SQL procedure successfully completed.

scott@TUNE>
scott@TUNE> exec run_exp('exp scott/tiger@TUNE, TABLES=(emp, dept), FILE=/tmp/exp_test.dmp, LOG=/tmp/exp_test.log');
java.security.AccessControlException: the Permission (java.io.FilePermission <<ALL FILES>> execute) has not been granted
to SCOTT. The PL/SQL to grant this is dbms_java.grant_permission( 'SCOTT', 'SYS:java.io.FilePermission', '<<ALL FILES>>', 'execute' )                                                             
at java.security.AccessControlContext.checkPermission(AccessControlContext.java)                         
at java.security.AccessController.checkPermission(AccessController.java)                               
at java.lang.SecurityManager.checkPermission(SecurityManager.java)                                   
at oracle.aurora.rdbms.SecurityManagerImpl.checkPermission(SecurityManagerImpl.java)                       
at java.lang.SecurityManager.checkExec(SecurityManager.java)                                       
at java.lang.Runtime.exec(Runtime.java)                                                     
at java.lang.Runtime.exec(Runtime.java)                                                     
at java.lang.Runtime.exec(Runtime.java)                                                     
at java.lang.Runtime.exec(Runtime.java)                                                     
at Util.RunThis(Util.java:13)                                                           
Export session failed.                                                               

PL/SQL procedure successfully completed.

scott@TUNE> show user
USER is "SCOTT"
scott@TUNE> begin
2    dbms_java.grant_permission
3    ('SCOTT',
4      'java.io.FilePermission',
5      '/opt/oracle/9.2.0.1.0/bin/exp',
6      'execute');
7
8    dbms_java.grant_permission
9    ('SCOTT',
10    'java.lang.RuntimePermission',
11    '*',
12    'writeFileDescriptor' );
13 end;
14 /

PL/SQL procedure successfully completed.

scott@TUNE> show err
No errors.
scott@TUNE> connect scott/tiger@tune
Connected.
scott@TUNE> set serveroutput on size 1000000
scott@TUNE> exec dbms_java.set_output(1000000)

PL/SQL procedure successfully completed.

scott@TUNE> exec run_exp('exp scott/tiger@TUNE, TABLES=(emp, dept), FILE=/tmp/exp_test.dmp, LOG=/tmp/exp_test.log');
java.security.AccessControlException: the Permission (java.io.FilePermission <<ALL FILES>> execute) has not been granted
to SCOTT. The PL/SQL to grant this is dbms_java.grant_permission( 'SCOTT', 'SYS:java.io.FilePermission', '<<ALL FILES>>', 'execute' )                                                                 
at java.security.AccessControlContext.checkPermission(AccessControlContext.java)                         
at java.security.AccessController.checkPermission(AccessController.java)                               
at java.lang.SecurityManager.checkPermission(SecurityManager.java)                                   
at oracle.aurora.rdbms.SecurityManagerImpl.checkPermission(SecurityManagerImpl.java)                       
at java.lang.SecurityManager.checkExec(SecurityManager.java)                                       
at java.lang.Runtime.exec(Runtime.java)                                                     
at java.lang.Runtime.exec(Runtime.java)                                                     
at java.lang.Runtime.exec(Runtime.java)                                                     
at java.lang.Runtime.exec(Runtime.java)                                                     
at Util.RunThis(Util.java:13)                                                           
Export session failed.                                                               

PL/SQL procedure successful

Followup   March 22, 2005 - 6pm Central time zone:

you gave privs to run

/x/y/z

and ran

z

/z/y/z <> z 

5 stars OS Command from Java Pl Sql   March 22, 2005 - 2pm Central time zone
Reviewer: Laxman Kondal from Springfield, VA
Hi Tom 

This was my first Java program and one mistakle I found was that path was not correct and then 
reconnected and worked fine.

begin      
      dbms_java.grant_permission
      ('SCOTT',
       'java.io.FilePermission',
       '/opt/oracle/product/9.2.0.1.0/bin/exp',
       'execute');
    
      dbms_java.grant_permission
      ('SCOTT',
      'java.lang.RuntimePermission',
      '*',
      'writeFileDescriptor' );
end;

I orginally missed /product/ in path.

I will appriciate if you could help me to make it better or your any suggestion.

Thanks

Regards.

 


Followup   March 22, 2005 - 6pm Central time zone:

well, it was mostly the orginal code from above, so I think I like it... 

5 stars OS Command from Pl Sql   March 22, 2005 - 9pm Central time zone
Reviewer: Laxman Kondal from Springfield, VA
Hi Tom 

Thanks for reply. I have few ....

In one of your follow-up you said

    "did you use dbms_java grant permission to grant yourself the needed privs?  like my example 
does?"

If sys as sysdba has granted 'java.lang.RuntimePermission', and execute permission then why do I 
need to grant it to me again? 

Is it required for all users to grant permission to ownself?

After granting privs what’s the reason for reconnecting again to execute? Java cannot see those 
grant/prives?

Once JAVA SOURCE NAMED "Util" is compiled where can I find compiled code in oracle?

I could not find dbms_java.grant_permission on any document, where is it?

Thanks for you help and wonderful source of knowledge.

Regards.


 


Followup   March 23, 2005 - 1am Central time zone:

I asked if you did, i never said "you have to do it twice???"

http://otn.oracle.com/pls/db92/db92.drilldown?remark=&word=dbms_java&book=&preference=

5 stars accessing xml file in OS filesystem   March 31, 2005 - 6am Central time zone
Reviewer: A Reader from UK
I am trying to use a java stored procedure in solaris environment. The java code is accessing a xml 
file and inserts the data within it into a table in oracle. I am using java.io.File class to create 
the file object. I am not able to create the file object using following code.

InputSource input = new InputSource(new FileReader(new 
File("/export/home/stniitd1/interface/inbound/a55progsched/a55_episode_sample.xml")));

when I used System.getProperty("user.dir"), I got following string 
/nas/orasoft/baracuda/product/9.2.0/
 


Followup   March 31, 2005 - 8am Central time zone:

why aren't you able to create the file object (i have as much information as you would if I said to 
you "my car won't start, why") 

5 stars Java Source   April 7, 2005 - 8am Central time zone
Reviewer: Stefan Knecht from Switzerland
Hello Tom,

i implemented the java code you've shown above, and it works great.

however, when i tried to modify it slightly to this:

CREATE OR REPLACE AND COMPILE JAVA SOURCE named "Util_zip"
as
import java.io.*;
import java.lang.*;

public class Util_zip extends Object
{

  public static int RunThis(String args)
  {
  Runtime rt = Runtime.getRuntime();
  int        rc = -1;

  try
  {
     Process p = rt.exec(args);

     int bufSize = 4096;
     BufferedInputStream bis =
      new BufferedInputStream(p.getInputStream(), bufSize);
     int len;
    byte buffer[] = new byte[bufSize];


     // Echo back what the program spit out
     while ((len = bis.read(buffer, 0, bufSize)) != -1)
        System.out.write(buffer,0,len);

        #sql {
                CALL scanning.insert_file (:buffer) };

     rc = p.waitFor();
  }
  catch (Exception e)
  {
    e.printStackTrace();
     rc = -1;
  }
  finally
  {
     return rc;
  }
  }
}
/
show errors;

oracle throws 01461, 00000, "can bind a LONG value only for insert into a LONG column". 
as the byte[] apparently maps to a LONG RAW (?).  What i am trying to do is insert the data that 
the unix command spits back out into a table for later processing. 

The procedure being called is very straight forward:

PROCEDURE insert_file (p_file IN VARCHAR2)
IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO ziplist (file_name) VALUES (p_file);
COMMIT;
END;

i use autonomous_transaction pragma, because this whole thing is being called inside a function. 
the data integrity should be fine, though as there's no concurrent accesses to this table at all.

The operating system command being called is also working fine, it's a simple shell script that 
does:
#!/bin/sh
/usr/local/bin/unzip -l $1 | /bin/awk '{ print $4 }' | /bin/grep '\.'

i tried to "fix" the above java to convert this to a datatype oracle would understand, but after 2h 
of failures (i know enough java to read the source and java.sun.com, but that's not enough anymore 
here :| ) ... i am hoping you might be able to tell me how to adjust the source to accomplish this 
task. or maybe you even see a much easier way to do the  same trick.

looking forward to your reply, and thanks in advance

Stefan
 


Followup   April 7, 2005 - 10am Central time zone:

why wouldn't you use a blob/clob and just stream it right in there in the java? 

1 stars Error   April 7, 2005 - 1pm Central time zone
Reviewer: Andy from Mexico
Hi Tom, I try use this example but when i execute the procedure rc, failure
SQL> exec rc('ls')
java.lang.ArrayIndexOutOfBoundsException
at Util.RunThis(UTIL.java:15) 

I see the other questions about the error java.lang.ArrayIndexOutOfBoundsException, but all have 
UTIL.java:14 and for me show UTIL.java.15 (change the number)

It's the same error!?

Thank's 


Followup   April 7, 2005 - 1pm Central time zone:

yes
5 stars Excellent Example   April 7, 2005 - 2pm Central time zone
Reviewer: Charlie from Omaha, NE
Out of all the examples of java calling a host command - this one has to be the best.  I needed to 
use logic like this and it works great.   


1 stars Permission Error   April 7, 2005 - 6pm Central time zone
Reviewer: Andy from Mexico
hi Tom again

   When i try execute the RUN_CMD function, show me the next error:

B@db9i> exec :x := RUN_CMD('/usr/lib ls')
java.security.AccessControlException: the Permission (java.io.FilePermission /usr/lib execute) has
not been granted to HT. The PL/SQL to grant this is dbms_java.grant_permission( 'HT',
'SYS:java.io.FilePermission', '/usr/lib', 'execute' )
at java.security.AccessControlContext.checkPermission(AccessControlContext.java)
at java.security.AccessController.checkPermission(AccessController.java)
at java.lang.SecurityManager.checkPermission(SecurityManager.java)
at oracle.aurora.rdbms.SecurityManagerImpl.checkPermission(SecurityManagerImpl.java)
at java.lang.SecurityManager.checkExec(SecurityManager.java)
at java.lang.Runtime.exec(Runtime.java)
at java.lang.Runtime.exec(Runtime.java)
at java.lang.Runtime.exec(Runtime.java)
at java.lang.Runtime.exec(Runtime.java)
at Util.RunThis(UTIL.java:13)

I saw the solution for this error: use 2 users, User A give the grants to user B and user B create 
all the programns (Util,RUN_CMD, RC).

But show me the same error!!! please help me!!

I tryed use SYS user for give grants too 


Followup   April 7, 2005 - 7pm Central time zone:

did you read the error message?  it actually shows you the permission you need.


but.... 

/usr/lib ls

what is that?

In that context, /usr/lib would be a program (but it isn't) and ls would be a parameter to it.

perhaps you meant to try and run something else? 

3 stars Permission Error - Ok   April 7, 2005 - 6pm Central time zone
Reviewer: Andy from Mexico
forgets the previous question, already arrange it...


thanks 


5 stars But what is the called script able to DO?   April 18, 2005 - 10am Central time zone
Reviewer: Tom Best from PA USA
Tom:

This is great for us - we need to call a script from pl/sql, and the external proc thing was giving 
us trouble.  This is cleaner.

One question though - I can get a script to run, such as:

echo Hello world.

But... if the script does something to a file - or creates a directory or anything - I see the echo 
output, but the file operation does not actually happen.

E.G.

echo Hello World
mv /home/oracle/this /home/oracle/that

I see Hello World (so I know it ran) but file "this" does not become "that".

Is this a permissions thing?  Do I need a DIRECTORY object created and have perms on it or 
something?

Thanks. 


Followup   April 18, 2005 - 10am Central time zone:

mv is a command, might not be in your path.  echo might have been.

but can surely be a permission issue, the script is running as the dedicated server userid in the 
OS.  It can only do what that user can do.


Try this, 

/bin/touch /tmp/testing


and make sure that /tmp/testing doesn't exist first, if it creates a file, it'll show you "who" you 
are. 

5 stars It was the path   April 18, 2005 - 2pm Central time zone
Reviewer: Tom Best from PA USA
That fixed it.  It was the path.  The user was indeed oracle, but the path was not setup in the 
script.

Thanks again. 


3 stars Execute command at client side(Windows XP)   April 27, 2005 - 3pm Central time zone
Reviewer: Morg from Morocco
Dear Tom,
 I want from client side (Windows XP,Plus80w) to execute a dos command like (Copy file) using 
PL/SQL and kindly note that client connect to database 9i on unix server. 


Followup   April 27, 2005 - 3pm Central time zone:

not going to happen.

PLSQL runs on the server, not on the client (unless you are running forms but even then it is 
running in the middle tier).

sqlplus can run a host command on the client.  but plsql cannot. 

5 stars Calling exp/imp from java   May 19, 2005 - 5pm Central time zone
Reviewer: Laxman Kondal from Springfield, VA
Hi Tom

 I need your help to solve this export/import from java class which I got from this site. It works 
fine and its realy great and when I wanted to test it with wrong username/password hangs, waitng 
for username/password. 

Since I am calling from pl/sql there is no way I can kill this.

Could you please help me to figure out how to fix this.

Thanks
 


Followup   May 20, 2005 - 7am Central time zone:

kill it at the OS level (and then understand what a mistake this could be -- calling a program that 
tries to interact with a user....) 

5 stars Calling exp/imp from java   May 20, 2005 - 7am Central time zone
Reviewer: Laxman Kondal from Springfield, VA
Hi Tom
Thanks for reply.

We did kill it from OS but I was trying to find if any way java code can be alterd to cater for 
this eventually. 

Anoter alternate was to hard code username/pwd which may not be desirable.

Thanks and regards. 


Followup   May 20, 2005 - 8am Central time zone:

only host out to things that will NEVER interact with the end user. 

5 stars off topic ...   May 20, 2005 - 10am Central time zone
Reviewer: Paul 
Tom - what's going on today? The 'last updated'for 20 May 2005 8am appears on one line for 
questions 1 to 10, and straddles 2 lines for questions 11 to 20?

 


Followup   May 20, 2005 - 6pm Central time zone:

changed nothing, window width perhaps on your screen? 

5 stars print to file   May 20, 2005 - 12pm Central time zone
Reviewer: rye from Flagstaff, AZ USA
hi tom,
execellent stuff.  what i'm trying to do is execute a .bat file that calls a vbscript that prints a 
ms word doc to pdf.  everything works great from the commandline.  when i try and run it using your 
proc, the word doc opens and gets sent to the pdf writer, but hangs there.  in other tests, i have 
been able to sucessfully print to a regular printer using the proc.  any ideas on what could be 
preventing me from printing using the pdf writer?
 


Followup   May 20, 2005 - 6pm Central time zone:

windows...
the database is running in a different environment -- it doesn't have your "printers", "shares" etc 
- it has IT'S set up --

it is running as a service, you'll need to find a windows guy to help you get a service to know 
about other stuff like that. 

5 stars Any addvice on remote progam calls?   May 30, 2005 - 5am Central time zone
Reviewer: Rene from Vienna, Austria
The initial solution is very cool! But what would I do, if I have to call a binary on a different 
server, that is not running an Oracle database? (Otherwise I could call a procedure on the remote 
oracle server, which then calls the program locally....)

The company's policy is to not allow anything else on the Oracle server (which is okay with me).

The environment is Oracle 9i (9.2.0.6.0) on Windows 2000 Server.
The "remote" program is on a different Windows 2000 Server.

So, how can I call a program that is on a different server in this environment? 

Do you have any ideas or hints (it seems to be a windows specific problem) how do I do a "remote 
call" from the Oracle database to the other server?

Sincerly, Rene 


Followup   May 30, 2005 - 9am Central time zone:

You'll have to ask your system and security folk (remote program execution can be very "virus 
like").

Say the remote machine has an application server, you could invoke it via a URL (utl_http).

Say the remote machine has no security, you could use some windows command line to to a remote 
program execution.


But this is something you need to solve "outside" of Oracle first.  Just make it so this database 
server can run that remote program.  Once you figure that out given you OS's, your security, your 
setup , we can proceed from there. 

3 stars host call fails on Linux 10.1.0.3/10.1.0.4   June 7, 2005 - 10pm Central time zone
Reviewer: Pete from CA US
Tom,

I've used the Util class since ver 817 ->10.1.0.2 with no issue at all. 
When running same code after the upgrade I'm getting 
ERROR:
ORA-03114: not connected to ORACLE

BEGIN rc('/bin/ps -ef'); END;

*
ERROR at line 1:
ORA-03113: end-of-file on communication channel

No trace files to find in udump/bdump. I also tried putting dbms_output and java system.out.. but 
the connection aborts and never finishes and I'm not getting any debug info at all.
In addition to the specific grants I've also granted javauserpriv, javasyspriv but no different 
result.
Is anyone aware of anything that has changed in the ojvm that makes this non backward compatible ?

 exec     dbms_java.grant_permission('IRIS', 'java.io.FilePermission', '/bin/ps','execute');
exec     dbms_java.grant_permission('IRIS', 'java.io.FilePermission', '*','read,write');


 create or replace and compile
   java source named "Util"
   as
   import java.io.*;
   import java.lang.*;
   
   public class Util extends Object
   {
     public static int RunThis(String args)
     {
     Runtime rt = Runtime.getRuntime();
     int        rc = -1;
   
     try
     {
        Process p = rt.exec(args);
   
        int bufSize = 4096;
        BufferedInputStream bis =
         new BufferedInputStream(p.getInputStream(), bufSize);
        int len;
        byte buffer[] = new byte[bufSize];
   
        // Echo back what the program spit out
        while ((len = bis.read(buffer, 0, bufSize)) != -1)
           System.out.write(buffer, 0, len);
   
        rc = p.waitFor();
     }
     catch (Exception e)
     {
        e.printStackTrace();
        rc = -1;
     }
     finally
     {
        return rc;
     }
     }
   }
   /
create or replace
    function RUN_CMD( p_cmd  in varchar2) return number
    as
    language java
    name 'Util.RunThis(java.lang.String) return integer';
    /
create or replace procedure RC(p_cmd in varchar2)
    as
      x number;
    begin
      x := run_cmd(p_cmd);
    end;
    /

set serveroutput on size 10000
exec dbms_java.set_output(1000)
exec rc('/bin/ps -ef');
 


Followup   June 8, 2005 - 8am Central time zone:

not sure on the 3114, I cannot reproduce that at all.

but in 9i and 10g for me -- I had to wrap the ps call in a script to get the environment set up 
properly.

Have you checked the execution environment (eg: run /bin/env instead?)



 
Connected to:
Oracle Database 10g Enterprise Edition Release 10.1.0.4.0 - Production
With the Partitioning, OLAP and Data Mining options
 
worked straight away for me. 

3 stars Further investigation of ORA-3113   June 8, 2005 - 1pm Central time zone
Reviewer: Pete from CA US
To further narrow down the issue - I created a new user and granted as sys
EXECUTE dbms_java.grant_permission( 'HST60','SYS:java.io.FilePermission','<<ALL 
FILES>>','execute'); 
EXECUTE dbms_java.grant_permission( 'HST60','SYS:java.io.FilePermission','*','read,write'); 
EXECUTE dbms_java.grant_permission( 
'HST60','SYS:java.lang.RuntimePermission','writeFileDescriptor','*' ); 
EXECUTE dbms_java.grant_permission( 
'HST60','SYS:java.lang.RuntimePermission','readFileDescriptor','*' );
Next I created the class and stored procs using above code

To verify that the host call gets executed I did:

SQL> set serveroutput on size 10000
exec dbms_java.set_output(1000)
exec rc('/bin/env');SQL> 
PL/SQL procedure successfully completed.

SQL> 
java.io.IOException: can't exec: /bin/env doesn't exist

-ok my host call is attempted - I then proceeded with

Oracle Database 10g Enterprise Edition Release 10.1.0.3.0 - Production
With the Partitioning, OLAP and Data Mining options

SQL> set serveroutput on size 10000
exec dbms_java.set_output(1000)
exec rc('/usr/bin/env');SQL> 
PL/SQL procedure successfully completed.

SQL> 
ERROR:
ORA-03114: not connected to ORACLE


BEGIN rc('/usr/bin/env'); END;

*
ERROR at line 1:
ORA-03113: end-of-file on communication channel


SQL> !/usr/bin/env
LESSKEY=/etc/lesskey.bin
MANPATH=/usr/local/man:/usr/share/man:/usr/X11R6/man:/opt/gnome/share/man
INFODIR=/usr/local/info:/usr/share/info:/usr/info
NNTPSERVER=news

Script without environment fails
I then tried a script that sets environment and then executes

SQL> set serveroutput on size 10000
exec dbms_java.set_output(1000)
exec rc('/opt/iris/bin/shell.sh /usr/bin/env');SQL> 
PL/SQL procedure successfully completed.

SQL> 
ERROR:
ORA-03114: not connected to ORACLE


BEGIN rc('/opt/iris/bin/shell.sh /usr/bin/env'); END;

*
ERROR at line 1:
ORA-03113: end-of-file on communication channel

Shell.sh - I noted that the file hallo didn't get created 
oracle@risqube:~> more /opt/iris/bin/shell.sh 
#!/bin/sh
PATH=${PATH}:/opt/iris/bin:/bin:/usr/bin
export PATH
system "echo hallo >/opt/iris/log/hallo";
eval $*


java_pool_size 64M
large_pool_size 16M
I was thinking that maybe the java parameters could affect this but the fact that the db is running 
java stored procedures and javamail just fine so the ojvm is working - there are no invalid classes 
- the host call is the problem - Any ideas to troubleshoot this much appreciated

Many Thanks
Pete 


Followup   June 8, 2005 - 1pm Central time zone:

you'll want to work with support, they can help you set events to create trace information and 
debug this. 

4 stars Executing shell scripts and passing parameters to   June 26, 2005 - 12pm Central time zone
Reviewer: Azmat from Lucknow, India
Tom,

I have a shell script which accepts two parameters and creates a text file, this works good on unix 
environment. I need to call this scripts from PL/SQL environment so that I can store the generated 
file in a BLOB column and later display it on browser. How would I do it? Here is my shell call in 
unix environment.

$ itg.sh -a P  -b 10 -out abc.txt

where itg.sh is a shell script, P and 10 are the two parameters value for -a and -b respectively 
and -out is is used for out parameter and result is abc.txt file. I want to store this text file on 
a BLOB column to display it on browser?

Thank you 


Followup   June 26, 2005 - 1pm Central time zone:

you want to store text in a clob.

but, this page shows you how to run a shell script from plsql and then dbms_lob.loadfromfile will 
be useful to get the generated text file into the database.

But, if you just want to display it on the browser, you could also just use a BFILE instead of a 
lob in the database -- if the data is not going to persist for any duration of time. 

3 stars executing shell script from DB   June 26, 2005 - 11pm Central time zone
Reviewer: Azmat from Lucknoe, India
Actually, I meant to ask if I can use following procedure ( created in this thred earlier) to run 
my shell script.

sql>exec run_exp('itg.sh -a P  -b 10 -out abc.txt');

I am not sure if this will run or not. I wanted to be sure about this before asking all the 
permission ( dbms_java.grant_permission)  from our DB group.

Thank you

  


Followup   June 27, 2005 - 7am Central time zone:

yes, you can run shell scripts. 

4 stars RE: mapping a network drive on windows within a procedure   June 27, 2005 - 2am Central time zone
Reviewer: Edgar from Latvia
Hi,

Oracle by default on Windows run as service under LOCAL_SYSTEM account.

Because of Windows security features, LOCAL_SYSTEM is prohibited to USE network mapped drives.

Because of that, for example, you cannot use RMAN to disk-to-disk backup to network mapped drive, 
you cannot set ARCHIVE_LOG_DEST_n to network mapped drive.

There is a workaround (i find on Metalink) : you can change ownership of Oracle services (database, 
listener) to someone another user account (Administrator).
I don't remember Note #.   


5 stars OS cp command   July 15, 2005 - 3pm Central time zone
Reviewer: Laxman Kondal from Springfield, VA
Hi Tom

I have used run_cmd function for exp, imp and sqlldr and this 'cp' command I need your help please 
to work. 

SQL> exec :x := run_cmd('cp /tmp/exh_hi.dmp /tmp/exp_hi_1.dmp')

PL/SQL procedure successfully completed.


         X
----------
        -1

SQL>

This is the permission granted as sys

begin      
      dbms_java.grant_permission
      ('OPO_USER',
       'java.io.FilePermission',
       '/bin/cp',
       'execute');
         

      dbms_java.grant_permission
      ('OPO_USER',
      'java.lang.RuntimePermission',
      '*',
      'writeFileDescriptor' );    
end;
/

I used different files to copy .dmp, .txt, and .log - all in /tmp/ but all exit codes are -1.

What's I am missing or doing something wrong.

Thanks and regards. 


Followup   July 15, 2005 - 6pm Central time zone:

/bin/cp <> cp

 

5 stars OS cp command   July 15, 2005 - 11pm Central time zone
Reviewer: Laxman Kondal from Springfield, VA
Hi Tom

Thanks for reply.

I am not sure about '/bin/cp <> cp' it should be in dbms_java.grant_permission and is it reqire to 
have '<>' for all os command?

Thanks and regards

 


Followup   July 16, 2005 - 9am Central time zone:

/bin/cp is not the same text as cp

cp might resolve to /usr/bin/cp or /home/badguy/cp or whatever


if you grant permission on /bin/cp, then you need to run /bin/cp. 

And you should grant on /bin/cp, not just cp, so you know the right cp is being used and not a 
trojan horse cp. 

4 stars What bout timeout   July 27, 2005 - 6pm Central time zone
Reviewer: Denis from Los Angeles, CA
Tom, if I run some command and it is hanging, it would be very helpfull to be able to set timeout. 
Could you advice how to do it?

I need to run "scp" command on windows to transfer files between servers using public and private 
keys. I need to cache the key under account oracle is running. What is Windows account name oracle 
is running under? 


Followup   July 27, 2005 - 8pm Central time zone:

commands typically do not "hang", they are doing something that takes a long time (AND it takes 
even longer in general to "undo" what they did).  

Some things like waiting for a row to lock it can be waited for (for update wait <n>) but you 
program that into the transaction.

No idea what "scp" is - but you pick the service attributes for Oracle, you pick who it runs as if 
you want.  If you are using 10g, you can look at dbms_file_transfer to move files between Oracle 
instances.  But look at your service and see what it is set to run as. 

3 stars timeout   July 28, 2005 - 2pm Central time zone
Reviewer: Denis from Los Angeles, CA
Tom,

For example, I call command which loads data from table to flat file using sqlplus (
http://asktom.oracle.com/~tkyte/flat/index.html
.  If I put there wrong filename and run manuallly from console, I will get an error message. If I 
run it from pl/sql using this java class, it will hang. is there any kind of timeout solution?

 


Followup   July 28, 2005 - 3pm Central time zone:

You must be excessively careful when calling interactive programs from any environment that isn't 
interactive though.  Period.

but you could change the java class to poll for output instead of block on output if you like and 
time out - but then you have that nasty problem of "that thing is still out there" to deal with. 

Best to ensure whatever you call is NOT interactive under any circumstances. 

3 stars Hang or not to hang   July 28, 2005 - 8pm Central time zone
Reviewer: Marcelo from Brazil
Extracted from the comment above...

/quote
commands typically do not "hang", they are doing something that takes a long time (AND it takes 
even longer in general to "undo" what they did).  
/quote

At the point of view of the database, it is true. But when running something in Windows it can (and 
surely will) hang. And I believe in this case the OS is really doing something, but that will never 
finish :)
 


Followup   July 29, 2005 - 8am Central time zone:

I was thinking of commands in the sense of a sql command.  But, you are free to rewrite the java 
stored procedure in a polling fashion -- it is just code, you can in fact make it do whatever you 
like!  

4 stars timeout and errors   July 28, 2005 - 9pm Central time zone
Reviewer: Denis from Los Angeles, CA
Tom, maybe then in this case using DBMS_SCHEDULER is better idea? If it command fails, job fails. 
Nothing is hanging.

From other hand I tried to incorporate timeout into your code 
and put this inside try block:

            if (timeout > 0) {
                Thread destroyProcess = new Thread() {
                    public void run() {
                        try {
                            sleep(timeout);
                        } catch (InterruptedException ie) {
                        } finally {
                            p.destroy();
                        }
                    }
                };
                destroyProcess.start();
            }

But started getting interesting behavior. If my commands where correct, command did succeded but I 
got an error(below). if command is incorrect, I was getting the same error right away:

ORA-29516: Aurora assertion failure: Assertion failure at sjonio.c:128
WaitForMultipleObjects failed: errno = 6

Maybe we can't do timeout because java in oracle PL/SQL is single-threaded? 

But even in case we don't need timeout, when we get error message right way, It is strange not to 
be able to through an error from Java (stop process and return -1) , if command failed. SQL server 
has similar functionality CMDSHELL extended stored procedure. But it throughs en error in case 
command is incorrect.

So using your code PL/SQL  will always hang if command through an error? Right?

Thanks

 


Followup   July 29, 2005 - 8am Central time zone:

the problem is, the job would hang forever.

They have a command running that is waiting for the user to hit the enter key.

The user never will hit the enter key.

The job will be stuck forever.


POLL for data, don't do anything that blocks. 

5 stars Trouble Executing Shell Script   August 3, 2005 - 11am Central time zone
Reviewer: TH from Nashville, TN
Hey Tom

Thanks so much for this script.  I think its going to change the way we do Data Warehousing forever 
because we can now do all of the things that we need to do from our Oracle packages.

One thing I have yet to figure out, is how to automate decryption of files using gpg.  I have a 
script that automatically decrypts all the files in the same folder as the script.  I can run the 
sh script that we have from a prompt, and it works fine, but when I run it via the procedure RC - 
it completes successfully, but does not actually execute the file.  The return value is 127.

Any ideas? 


Followup   August 3, 2005 - 12pm Central time zone:

well, if you are going to automate the decryption of something like this, one wonders why they are 
encrypted in the first place.


put debug into the script -- 999 times out of 1000 it is an environment issue.  printout your 
environment, echo commands, redirect it to a "trace" file in tmp 

2 stars Actually....   August 3, 2005 - 2pm Central time zone
Reviewer: TH from Nashville, TN
I was wondering what the return value from the java means.  I looked up the WaitFor() method, and 
it looks like is pauses the process, waiting for the thread to finish, and then kills it.  It says 
that a return of 0 is normal.  Anything other than that is not.  What does the number that it 
returns represent?

As for why we are trying to automate encryption - the encryption is only to get the file from an 
outside source into our network.

Thanks! 


Followup   August 3, 2005 - 5pm Central time zone:

I guess it means "not normal", it should probably be the return code from the shell script.

time to add debug to it! almost always an environment issue (bad path, missing something).  
remember the script runs in a "pristine, different, ORACLE environment separate from yours" 

3 stars Still stumped....   August 4, 2005 - 3pm Central time zone
Reviewer: TH from Nashville, TN
Tom - You can preface your response with how sick of me you are - i wont be offended.  Im sick of 
me on this issue too.

I have a .sh file that runs to decrypt some files automatically.  The problem is that the gpg 
binary is in a different directory, and even if I give the absolute path of the dir, it still does 
not work -- so the .sh looks like this...

!#/bin/sh
cd /stage/incoming
/usr/local/bin/gpg --decrypt-files *.pgp
exit

I know that the problem here is ennvironment, but I cannot figure out what to do to rectify it.  I 
have had the Unix guys look at this and do everything they can to rule out an environment issue.  I 
just dont know enough about Unix to know what to do next.  I think the problem has to do with the 
gpg residing in a different directory than the files I want to decrypt.


 


Followup   August 4, 2005 - 8pm Central time zone:

does gpg have a "verbose mode"

do you know how to redirect stdout AND stderr to a tmp file (capture any and all output from gpg)


oh, and how does gpg work?  where does it get the encryption keys from?  how does it know where to 
find them? 

3 stars calling Java program from PL/SQL.   August 22, 2005 - 10am Central time zone
Reviewer: Rajesh from India
I want to call a java program from my pl/sql block. When I wrote a small program like this

create or replace and compile
java source named "Util"
as
public class Util {
  public static String hi() {
    System.out.println ("tracing here");
    return "hello there";
  }
}


the following error occured. Why? what can be the cause. I am using oracle 9i. Please help me!!!!

ERROR at line 2:
ORA-00600: internal error code, arguments: [KSMASG1], [4032], [4032], [], [],
[], [], []

 


Followup   August 23, 2005 - 3am Central time zone:

ora-600 always means "please contact support"


ops$tkyte@ORA9IR2> create or replace and compile
  2  java source named "Util"
  3  as
  4  public class Util {
  5    public static String hi() {
  6      System.out.println ("tracing here");
  7
  }
  7      return "hello there";
  8    }
  9  }
 10  /

Java created.

especially since it doesn't reproduce universally

 

5 stars   August 23, 2005 - 6am Central time zone
Reviewer: dave from uk
take a look at metalink note 4014485.8

Looks like this could be for you 


4 stars calling Java programs from PL/SQL   August 23, 2005 - 8am Central time zone
Reviewer: Rajesh from India
Thank You very much. Java package was not installed initially. After installation it worked. 


4 stars Java Program from PL/SQL   August 24, 2005 - 5am Central time zone
Reviewer: Rajesh from India
I am importing these class files in my Java program.

import org.apache.commons.codec.binary.Base64; 
import org.apache.commons.codec.binary.Hex; 
import org.bouncycastle.openssl.PEMReader;

import java.security.interfaces.RSAPrivateKey;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.provider.JCERSAPublicKey;

The code is working in Windows NT in java compiler. 
My intention is to create a java source for this in oracle. So that i can access the methods 
described in the java program. which runs in unix box.

I have set the class path  in unix box like this

export CLASSPATH=$CLASSPATH:$HOME/bcmail-jdk13-129.jar:$HOME/bcpg-jdk13-129

But I am getting error like this...

Class org.apache.commons.codec.binary.Base64 not

         found in import.

 

0/0      Encropt:8: Class org.apache.commons.codec.binary.Hex not found

         in import.

 

0/0      Encropt:9: Class org.bouncycastle.openssl.PEMReader not found in

         import.

 

0/0      Encropt:11: Class

         org.bouncycastle.jce.provider.BouncyCastleProvider not found in

 

LINE/COL ERROR

-------- -----------------------------------------------------------------

         import.

 

0/0      Encropt:12: Class org.bouncycastle.jce.provider.JCERSAPublicKey

         not found in import.

 

0/0      Info: 5 errors



What is the problem here? Is it the problem with my classpath settings. I opened the jar file in 
winzip and searched for the class files. the class files are there.
 


Followup   August 24, 2005 - 10am Central time zone:

you have to load the jars into the database, your classpath isn't relevant, everything must be 
contained within the database. 

5 stars Loved it as always   September 6, 2005 - 5pm Central time zone
Reviewer: Dmitriy N. from CA USA
I found exactly what I needed 


4 stars Error: The handle is invalid.   September 7, 2005 - 3pm Central time zone
Reviewer: Raman from TN, USA
Hello Tim,

When I run this small program for testing .... get this error:

SET SERVEROUTPUT ON SIZE 1000000 
CALL DBMS_JAVA.SET_OUTPUT(1000000); 
BEGIN 
Host_Command (h_command => 'move C:\apr.txt D:\apr.txt'); 
END; 
/ 


The handle is invalid. 

PL/SQL procedure successfully completed.

What would be your suggetion ?? Any clue ??

regards,
-Raman 


Followup   September 7, 2005 - 3pm Central time zone:

that would not be the full error stack would it. 

4 stars   September 7, 2005 - 3pm Central time zone
Reviewer: Raman from TN, USA
This is the only error I get it ... At first I used to think, there's something wrong in my 
procedure where I used HOST command ... after debugging I found out that Java procedure is causing 
the error:

I have re-created every thing :

- Created Java Procedure
- PL/SQL wrapper
- Granted Privileges

EXEC Dbms_Java.Grant_Permission('SCHEMA-NAME', 'java.io.FilePermission', '<>', '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', '');

- Tested it.


Could you please suggest me what to do to get rid of this error:

thanks. 


Followup   September 7, 2005 - 7pm Central time zone:

no, because that error would not appear all by itself like that.


make a small 100% complete test case for us to look at. 

4 stars   September 9, 2005 - 12am Central time zone
Reviewer: Raman from TN, USA
I had to run 'rmjvm.sql' and 'initjvm.sql' scripts ....
With companion CD, got rid of 'JAccelerator' error ...
Finally it works ....

thanks. 


3 stars Command not executed   September 21, 2005 - 4am Central time zone
Reviewer: Mody 
Dear Tom,
I have create file mk in folder /home/oracle ,this file contains one line (mkdir 
/home/oracle/test),
then I use you example with some small modifications ,
the procedure runs well but the directory isn't created.

begin
        dbms_java.grant_permission
        ('MKT',
         'java.io.FilePermission',
         '/home/oracle/mk',
         'execute');
    
        dbms_java.grant_permission
        ('MKT',
         'java.io.FilePermission',
         '/home/oracle/mk',
         'execute');

        dbms_java.grant_permission
        ('MKT',
        'java.lang.RuntimePermission',
        '*',
        'writeFileDescriptor' );
   end;
/


create or replace and compile
java source named "Util"
as
import java.io.*;
import java.lang.*;

public class Util extends Object
{

    public static int RunThis(String args)
    {
        Runtime rt = Runtime.getRuntime();
        int        rc = -1;

        try
        {    
            Process p = rt.exec(args);

            int bufSize = 4096;
            BufferedInputStream bis =
                new BufferedInputStream(p.getInputStream(), bufSize);
            int len;
            byte buffer[] = new byte[bufSize];
            // Echo back what the program spit out
            while ((len = bis.read(buffer, 0, bufSize)) != -1)                
                System.out.write(buffer, 0, len);
            rc = p.waitFor();
        }
        catch (Exception e)
        {
            System.out.println("exception ya man");
            e.printStackTrace();
            rc = -2;
        }
        finally
        {
            return rc;
        }
    }
}
/

create or replace
    function RUN_CMD( p_cmd  in varchar2) return number
    as
    language java
    name 'Util.RunThis(java.lang.String) return integer';
/


create or replace procedure RC(p_cmd in varchar2)
as
  x number;
begin
  x := run_cmd(p_cmd);
end;
/

set serveroutput on size 1000000
exec dbms_java.set_output(1000000)
exec rc('/home/oracle/mk');
 


Followup   September 21, 2005 - 7pm Central time zone:

likely a path problem.

mkdir is a "program"

so, is mkdir in the path of the oracle dedicated servers environment (best for security and because 
of this to be explicit -- /path/to/mkdir

and make sure the script starts with #!/bin/sh or whatever. 

5 stars Run a Oracle Report through pl-sql   October 5, 2005 - 1am Central time zone
Reviewer: Nikhilesh from India
Dear Tom,
  I'm trying to run a Oracle Report from pl-sql(the report generates a .pdf file to a specific 
location).
Using java I'm able to run the commands like ps and ls but I'm not able to run rwclient.sh. I fact 
I want to run

exec rc('/u01/app/oracle/product/dev/bin/rwclient.sh server=myserver 
report=/export/home/myhome/my_rep.rdf userid=my_user/my_password@my_service desformat=pdf 
destype=file desname=/export/home/my_home/name/test.pdf')

Is it possible?? Should I keep on trying??
Please mention what will be the privileges I will require to run this.

Thanks a lot in advance........

 


Followup   October 5, 2005 - 7am Central time zone:

remember, the environment is "different" here - you might create a script that dumps the 
environment using '/bin/env' or whatever (use full qualified commands - you don't even know what 
the PATH is)

set all environment variables EXPLICITLY

and make sure the script starts with 

#!/bin/shellname


if you read through this page - we've discussed this times before - you can run scripts. 

5 stars What permissions are required??   October 6, 2005 - 12am Central time zone
Reviewer: Nikhilesh from India
Dear Tom,
 Thanks for your reply. Yesterday I could generate the report running script file through pl-sql. 
And as you said before running that I had run one extra script file which sets the environment 
before generating .pdf file report.
  But the problem is I have granted read permission (using dbms_java.grant_permission)to all the 
files i.e. script and .rdf.
  Now I want to know Do we need to grant the permission to the script file we are running or to all 
of the script files and the .rdf files we are using in the main script file?? Will this method be 
secure?? 
 


Followup   October 6, 2005 - 7am Central time zone:

you do not need the grants to read all of that, once the script is running, it is quite out of our 
control what you can and cannot access - the operating system is in charge at that point.

you only need to permissions to run the script. 

5 stars   October 6, 2005 - 1pm Central time zone
Reviewer: A reader 
If we want to send the control to background ( like & in unix) by using dbms_job.submit(a, 
'RC(something);') ,
Do we have any way to check the value of X varibale to see the run_cmd(p_cmd) is successfull or 
not?

create or replace procedure RC(p_cmd in varchar2)
   as
      x number;
    begin
      x := run_cmd(p_cmd);
    end;

 


Followup   October 6, 2005 - 1pm Central time zone:

sure, if the job you submit, that runs in the background were to notify you someway after the job 
completed (wrote a row into a table for example....) 

5 stars   October 11, 2005 - 6pm Central time zone
Reviewer: A reader 
To,

We just migrated our database from solaris to Linux. We had few java stored procedure (mostly copy 
from your site -like reading files from directory etc..). Suddenly it stops working in linux. Also 
I have notied that we have to grant permission on specifice file and directory permission is not 
working (java.io.FilePermission). for eg. if i have want to read file on /user/bin/ directory then 
i have grant permission on the file. directory permission is not working. Could you please help us.

note - We exported database from solaris and impored it into linux os using oracle export and 
import.
Do we have to recreate JVM? ie do we have to run 
 /javavm/install/rmjvm.sql 
 /javavm/install/initjvm.sql

again ?

appreciate any help
thanks


 


Followup   October 12, 2005 - 7am Central time zone:

examples?  (i developed almost all of my examples on linux in the first place)

did you also happen to change *versions* of the database whilst doing this? 

5 stars   October 11, 2005 - 6pm Central time zone
Reviewer: A reader 
To,

We just migrated our database from solaris to Linux. We had few java stored procedure (mostly copy 
from your site -like reading files from directory etc..). Suddenly it stops working in linux. Also 
I have notied that we have to grant permission on specifice file and directory permission is not 
working (java.io.FilePermission). for eg. if i have want to read file on /user/bin/ directory then 
i have grant permission on the file. directory permission is not working. Could you please help us.

note - We exported database from solaris and impored it into linux os using oracle export and 
import.
Do we have to recreate JVM? ie do we have to run 
 /javavm/install/rmjvm.sql 
 /javavm/install/initjvm.sql

again ?

appreciate any help
thanks


 


5 stars   October 12, 2005 - 9am Central time zone
Reviewer: A reader 
Hi Tom,
 
We upgraded our database from 8.1.7.4 to 9.2.0.6.

getting following errors

java.security.AccessControlException: the Permission (java.io.FilePermission /nfsprod2/mkt read) 
has not been granted to SBLINT. The PL/SQL to grant this is dbms_java.grant_permission( 'SBLINT', 
'SYS:java.io.FilePermission', '/nfsprod2/mkt', 'read' )
  at java.security.AccessControlContext.checkPermission(AccessControlContext.java)
  at java.security.AccessController.checkPermission(AccessController.java)
  at java.lang.SecurityManager.checkPermission(SecurityManager.java)
  at oracle.aurora.rdbms.SecurityManagerImpl.checkPermission(SecurityManagerImpl.java)
  at java.lang.SecurityManager.checkRead(SecurityManager.java)
  at oracle.aurora.rdbms.SecurityManagerImpl.checkRead(SecurityManagerImpl.java)
  at java.io.File.list(File.java)
  at java.io.File.listFiles(File.java)
  at DirListName.getDirList(DirListName.java:8)

we are reading file (test.txt) from '/nfsprod2/mkt' dir and we have already granted this permisson

dbms_java.grant_permission( 'SBLINT', 'SYS:java.io.FilePermission', '/nfsprod2/mkt', 'read' )


Do I have do 

dbms_java.grant_permission( 'SBLINT', 'SYS:java.io.FilePermission', '/nfsprod2/mkt/*', 'read' ) to 
select all files ??

Thanks


 


Followup   October 12, 2005 - 1pm Central time zone:

can you show me

a) you doing the grant
b) reconnecting
c) running the procedure and getting the failure

as a cut and paste from sqlplus 

4 stars Is there a problem with this in version 10.1.0.3 ?   October 14, 2005 - 10am Central time zone
Reviewer: Holger Schweichler from Frankfurt, Germany
Hello Tom,

I've been struggling with running ksh scripts from PL/SQL using java for a couple of days now 
(already opened a TAR on this issue and uploaded the class and test script we're using, but it 
couldn't be reproduced by your colleagues so far while I see the same behaviour on 3 instances). Do 
you know of any issues in 10.1.0.3 when calling a shell script and passing some parameters? It 
works fine with some combinations, but returns a 255 on others (which is bogus because the ksh 
script is where it belongs and permissions are set correct, otherwise it won't work when calling 
the ksh with different parameters).

I went through this thread now and verified just the same behavior occurs when I use your example 
class/function/procedure... so the problem seems to be really a general one.
I will upgrade one instance to 10.1.0.4 this weekend and see if it still happens (since support 
couldn't reproduce on either 10.1.0.2 or 10.1.0.4).

TIA,

Holger 


4 stars 10.1.0.4 patch fixed above problem   October 18, 2005 - 5am Central time zone
Reviewer: Holger Schweichler from Frankfurt, Germany
... just wanted to let you know upgrading to 10.1.0.4 indeed fixed the problem, so it really looks 
like there's a bug in 10.1.0.3.

Holger ;-) 


Followup   October 18, 2005 - 9am Central time zone:

Thank you very much for the followup! 

4 stars Trying to use a shell script   November 10, 2005 - 12pm Central time zone
Reviewer: Deba from UK
Hi Tom,

I am trying to run a shell script using specified code.

Under SYS user :
=================
SQL> begin
   2  dbms_java.grant_permission
   3  ('YMDBAADM',
    4  'java.io.FilePermission',
  '  5  /nas/orasoft/baracuda/oracle/scripts/x.sh',
   6   'execute');
  7
  8   dbms_java.grant_permission
 (  9  'YMDBAADM',
 10    'java.lang.RuntimePermission',
  '*',
  'writeFileDescriptor' );
end;
/ 11   12   13   14

PL/SQL procedure successfully completed.

Under Oracle OS user
====================
/nas/orasoft/baracuda/oracle/scripts> ls -l x.sh
-rwxrwxrwx   1 oracle   oinstall      66 Nov 10 17:11 x.sh

/nas/orasoft/baracuda/oracle/scripts> pg x.sh
echo executing
ls > /nas/orasoft/baracuda/oracle/scripts/java.txt

Under YMDBAADM :
================
SQL> edit
Wrote file afiedt.buf

  1  create or replace and compile java source named "DebaShellUtil"
  2    as
  3    import java.io.*;
  4    import java.lang.*;
  5    public class DebaShellUtil extends Object
  6    {
  7      public static int RunThis(String args)
  8      {
  9      Runtime rt = Runtime.getRuntime();
 10      int        rc = -1;
 11      try
 12      {
 13         Process p = rt.exec(args);
 14         int bufSize = 4096;
 15         BufferedInputStream bis =
 16          new BufferedInputStream(p.getInputStream(), bufSize);
 17         int len;
 18         byte buffer[] = new byte[bufSize];
 19         // Echo back what the program spit out
 20         while ((len = bis.read(buffer, 0, bufSize)) != -1)
 21            System.out.write(buffer, 0, len);
 22         rc = p.waitFor();
 23      }
 24      catch (Exception e)
 25      {
 26         e.printStackTrace();
 27         rc = -1;
 28      }
 29      finally
 30      {
 31         return rc;
 32      }
 33      }
 34*   }
 35  /

Java created.

SQL> edit
Wrote file afiedt.buf

  1  create or replace function RUN_CMD(p_cmd in varchar2) return number
  2    as
  3    language java
  4*   name 'DebaShellUtil.RunThis(java.lang.String) return integer';
SQL> /

Function created.

SQL> variable x number;
SQL> set serveroutput on;
SQL> exec dbms_java.set_output(100000);

PL/SQL procedure successfully completed.

SQL> exec :x := RUN_CMD('/nas/orasoft/baracuda/oracle/scripts/x.sh');

PL/SQL procedure successfully completed.

SQL> exec dbms_java.set_output(100000);

PL/SQL procedure successfully completed.

SQL> exec :x := RUN_CMD('/nas/orasoft/baracuda/oracle/scripts/x.sh');

PL/SQL procedure successfully completed.

You can see that there is no output. There is permission for the script on OS level. If I use 
follwoing 
exec :x := RUN_CMD('/usr/bin/sh /nas/orasoft/baracuda/oracle/scripts/x.sh');
Then it is running fine. But you have already said this is not good idea to use, so I would like to 
know where is the problem in above mentioned process ??

Thanks
Deba 


Followup   November 11, 2005 - 11am Central time zone:

you are missing an important line in the shell script

#!/bin/sh


on line one and remember, the environment might not be what you think in the shell script when run 
from the database (different environment) so best to fully qualify things (prevent trojan horses - 
find the right programs)

 

4 stars Trying to execute shell script   November 15, 2005 - 12pm Central time zone
Reviewer: A reader 
Hi Tom,

In OS I have created two files as follows :

/nas/orasoft/baracuda/oracle/scripts> pg x.sh
#!/bin/sh
echo executing
sleep 60
ls > /nas/orasoft/baracuda/oracle/scripts/java.txt
echo ending x.sh

/nas/orasoft/baracuda/oracle/scripts> pg y.sh
#!/bin/sh
echo calling x.sh
nohup /nas/orasoft/baracuda/oracle/scripts/x.sh &
echo calling y.sh

chomd 777 x.sh
chmod 777 y.sh

Under SYS account I have executed following code :

begin
 dbms_java.grant_permission
 ('YMDBAADM',
  'java.io.FilePermission',
  '/usr/bin/sh',
  'execute');
  
dbms_java.grant_permission
 ('YMDBAADM',
  'java.io.FilePermission',
  '/nas/orasoft/baracuda/oracle/scripts/y.sh',
  'execute');
  
 dbms_java.grant_permission
 ('YMDBAADM',
  'java.lang.RuntimePermission',
  '*',
  'writeFileDescriptor' );
end;
/

Connecting to the database thru STPS2 :

connect YMDBAADM/YMDBAADM
Connected.

create or replace and compile java source named "DebaShellUtil"
  as
  import java.io.*;
  import java.lang.*;
  
  public class DebaShellUtil extends Object
  {
    public static int RunThis(String args)
    {
    Runtime rt = Runtime.getRuntime();
    int        rc = -1;
  
    try
    {
       Process p = rt.exec(args);
  
       int bufSize = 4096;
       BufferedInputStream bis =
        new BufferedInputStream(p.getInputStream(), bufSize);
       int len;
       byte buffer[] = new byte[bufSize];
  
       // Echo back what the program spit out
       while ((len = bis.read(buffer, 0, bufSize)) != -1)
          System.out.write(buffer, 0, len);
  
       rc = p.waitFor();
    }
    catch (Exception e)
    {
       e.printStackTrace();
       rc = -1;
    }
    finally
    {
       return rc;
    }
    }
  }
/
  
create or replace function RUN_CMD(p_cmd in varchar2) return number
  as
  language java
  name 'DebaShellUtil.RunThis(java.lang.String) return integer';
/

variable x number;
set serveroutput on  
exec dbms_java.set_output(100000);

SQL> exec :x := RUN_CMD('/nas/orasoft/baracuda/oracle/scripts/y.sh');
calling x.sh
calling y.sh
executing
ending x.sh

PL/SQL procedure successfully completed.

Thanks for your any help.

Deba 


Followup   November 15, 2005 - 1pm Central time zone:

 dbms_java.grant_permission
 ('YMDBAADM',
  'java.io.FilePermission',
  '/usr/bin/sh',
  'execute');

that's not good - that means "run anything"


sort of wished you had included "the problem" though....


but if it is because "it is waiting till x is done", that is something you'll need to poke around 
with in the java code, likely the waitfor call. 

4 stars Trying to execute shell script   November 15, 2005 - 12pm Central time zone
Reviewer: A reader 
Hi Tom,

In the above post you can see that there is no effect of "&" . But I want to execute a sehll in the 
background . Now how we can get this ???

Deba 


2 stars execute in background   December 15, 2005 - 10am Central time zone
Reviewer: EBer from Italy
You can exec that command from a batch file and inside you write: command.sh &

If you want that command to be independent and hangup immune,
you can use command "nohup", but you can't have the output back.

Hope this hepls.
EBer  


3 stars Is it possible without Java ?   December 15, 2005 - 10am Central time zone
Reviewer: EBer from Italy
We haven't JServer in Production DB. 


Followup   December 15, 2005 - 10am Central time zone:

you can use C based external routines as well.

in 10g, the scheduler can run external jobs natively. 

5 stars You might want stderr as well as stdout   December 29, 2005 - 5pm Central time zone
Reviewer: Scott Swank from Las Vegas, NV
CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED "host"
AS
import java.io.*;
public class host
{
  public static int runCommand(String command, String[] output)
  {
    StringBuffer  outputBuffer = new StringBuffer();
    output[0] = "";
    Runtime rt = Runtime.getRuntime();
    int rc = -1;
    try
    {
      Process p = rt.exec(command);
      String line = new String();
      BufferedReader br;

      br = new BufferedReader(new InputStreamReader(p.getInputStream()));
      while ((line = br.readLine()) != null)
        outputBuffer.append(line);
      br.close();

      br = new BufferedReader(new InputStreamReader(p.getErrorStream()));
      while ((line = br.readLine()) != null)
        outputBuffer.append(line);
      br.close();

      if (outputBuffer.length() > 32000)
      {
        output[0] = new String(outputBuffer.substring(0,32000));
      }
      else
      {
        output[0] = new String(outputBuffer);
      }

      rc = p.waitFor();
      //rc = p.exitValue();
    }
    catch (Exception e)
    {
      output[0] = e.toString();
      rc = -1;
    }
    finally
    {
      return rc;
    }
  }
}
/
 


4 stars Is there any way to wrap java source   January 18, 2006 - 10am Central time zone
Reviewer: Ian from Amsterdam
Is there any way to wrap java source in the same way that you can wrap pl/sql packages?

Regards

Ian 


Followup   January 19, 2006 - 7am Central time zone:

you can load bytecode instead of java source. 

5 stars   March 5, 2006 - 2pm Central time zone
Reviewer: Su Baba from Ca, USA
Would Java procedures cache cursors so no soft parses are required much like PL/SQL does? 


Followup   March 6, 2006 - 8am Central time zone:

No, not unless you explicity make it happen in your own code. 

4 stars   March 6, 2006 - 12pm Central time zone
Reviewer: A reader 
When you say "not unless you explicity make it happen in your own code", do you mean opening a 
cursor in your Java code and keep using it until you don't need it any more? 


Followup   March 8, 2006 - 4pm Central time zone:

or using jdbc statement caching or something - but "something" has to be explicitly enabled, jdbc 
does not do it by itself. 

2 stars   March 31, 2006 - 6am Central time zone
Reviewer: Yogesh Shejwal from India,Pune
I want to Pass TableName and Column_name,But the Column_name Datatype is CLOB.FRONT End is 
Forms9iDS.

In Backend i have Created A funtion that accepts all the above.The Function i tested in Back end 
works fine.But at front end i just get a Blank screen.

(Note: I could not Find the Page to Submit the Question so i am writing my Question here. I am a 
regular User Of these Site..gets lot of information)
 


Followup   March 31, 2006 - 12pm Central time zone:

(note: the front page of this website sort of has the box that says:       

Sorry I have a large backlog right now, please ask a question later

See the "other resources" tab above and to the left for recommendations of places to go to get 
answers to questions!

when I'm not taking questions)



I've no idea why you would get a "blank screen", I don't really know what you are really even 
doing. 

2 stars cannot get this batch to run   May 1, 2006 - 3pm Central time zone
Reviewer: oracledb from CA
Tim,

i keeping getting null on windows 2000,but execute fine on windows 2003..


windows 2000
SQL> SET SERVEROUTPUT ON SIZE 1000000
SQL> CALL DBMS_JAVA.SET_OUTPUT(1000000);

Call completed.

SQL> BEGIN
  2    PAS_HOST_COMMAND (p_command => '\\point-code\code$\sql\dev\sqltam\misc\test.bat');
  3  EXCEPTION
  4        WHEN OTHERS
  5        THEN
  6           DBMS_OUTPUT.PUT_LINE (SQLCODE);
  7           DBMS_OUTPUT.PUT_LINE (SQLERRM);
  8  END;
  9  /
null

PL/SQL procedure successfully completed.

code for test.bat ==> move test1.txt test2.txt
------------------------------------------
windows 2003
SQL>  BEGIN
  2     PAS_HOST_COMMAND (p_command => '\\point-code\code$\sql\dev\sqltam\misc\test.bat');
  3    EXCEPTION
  4          WHEN OTHERS
  5          THEN
  6             DBMS_OUTPUT.PUT_LINE (SQLCODE);
  7             DBMS_OUTPUT.PUT_LINE (SQLERRM);
  8    END;
  9  /
Process out :
Process out :C:\oracle\ora81\DATABASE>SQLPLUS.EXE BT15/BT15@BT15
@\\point-code\code$\sql\dev\sqltam\misc\TEST.SQL

PL/SQL procedure successfully completed.

code for test.bat ==> move test1.txt test2.txt 


Followup   May 2, 2006 - 3am Central time zone:

what sort of debugging have you tried on your own?  

I mean - if you have two machines here (forget the OS version for a minute) who is to say they are 
remotely configured the "same".  that UNC name (that can be very tricky to use with services, if it 
can be used at all), does it really exist for the user that the database service is running as.

you don't even mention database versions :( 

2 stars cannot get this batch to run   May 2, 2006 - 6pm Central time zone
Reviewer: oracledb from CA
not sure if my post work so..

both are on oracle 8.1.7.4.1,

i don't know what the null means?  and i don't really know how to debug..i've tried it on the 2000 
using local path and network path.. 


Followup   May 3, 2006 - 1am Central time zone:

... and i don't really know how to debug ...


uh oh.  start by putting some DEBUG CODE into your java subroutine, to sort of try to figure out 
where it is going awry.

System.out.println()'s  

5 stars Error Bound   July 3, 2006 - 8am Central time zone
Reviewer: Tom from Madrid
   Hi Tom,

  I have tried your example on a Sun Machine and I have got the next:

   14:53:41 SQL> exec rc('/usr/bin/ps -ef');
java.lang.ArrayIndexOutOfBoundsException
at Util.RunThis(Util.java:14)

Procedimiento PL/SQL terminado correctamente.

14:53:49 SQL> exec rc('/usr/bin/id > f');
java.lang.ArrayIndexOutOfBoundsException
at Util.RunThis(Util.java:14)


   What could be the cause of this?

   I'll appreciate very much your help.
   


Followup   July 7, 2006 - 3pm Central time zone:

did you ctl-f for ArrayIndexOutOfBoundsException
 on this very page? 

5 stars I have just solved my problem   July 3, 2006 - 11am Central time zone
Reviewer: Jorge from Madrid
  Thanks for your help!. I found the solution above. 


5 stars Solution to tricky "env" problem   July 20, 2006 - 5am Central time zone
Reviewer: Jay Bostock from Edinburgh, Scotland
Okay - this thread is getting way out of hand, but I just wanted to contribute a quick solution 
that I've used to make running a script as a different user from oracle, where you have all the 
environment issues (I'm sure it's in AskTom somewhere!). I've done it using rsh (ssh would be 
better). the command executed from within oracle would be something like:
sql> exec rc('/usr/bin/rsh localhost -l <username> <myShellScript>');

It doesn't have to be localhost, you can use any host name. You have to create $HOME/.rhosts file 
in the account you want to connect to with the line 'localhost oracle' (again, if the two accounts 
are on different machines, use the hostname rather than localhost. This allows oracle to login 
without supplying the password. A remote shell is created as the user you are connecting with (with 
the correct env), the command is run (in my case myShellScript, but any command can be run) and 
then the remote shell is exited.

It works brilliantly for me and saves loads of bother/confusion!

Hope this helps someone.

Cheers
Jay 


3 stars Stored Proc Execution in Unix   August 9, 2006 - 8am Central time zone
Reviewer: A reader 
Hi ,

  Can you let me know the commands to be used to execute a oracle Stored Proc in C Shell script and 
to output the results of the execution as to whether the execution was successful or there was an 
Exception in the execution to a Text file 

Thanks for the same.
 


Followup   August 9, 2006 - 10am Central time zone:

same why you would execute anything and log the output in C shell.

anyway, create a script, eg

$ cat test.sql
exec dbms_output.put_line('hello world');
exit


so, the procedure I want to run is dbms_output.  You run it as follows:


$ sqlplus / @test
 
SQL*Plus: Release 10.2.0.1.0 - Production on Wed Aug 9 10:40:17 2006
 
Copyright (c) 1982, 2005, Oracle.  All rights reserved.
 
 
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
 
hello world
 
PL/SQL procedure successfully completed.
 
Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options




Then, you just use redirection to capture the output.  pipe to grep if you just one "success":

$ sqlplus / @test | grep 'successfully'
PL/SQL procedure successfully completed.


or better yet, egrep to get success or failure (I'll make it fail)

$ sqlplus / @test | egrep '(successfully|ORA-)'
PL/SQL procedure successfully completed.



$ cat test.sql
exec dbms_output.put_line('hello world'); raise PROGRAM_ERROR;
exit
$ sqlplus / @test | egrep '(successfully|ORA-)'
ORA-06501: PL/SQL: program error
ORA-06512: at line 1
 

5 stars Did something in Java change between 9i and 10g?   August 9, 2006 - 2pm Central time zone
Reviewer: Ron from Iowa
<code>Tom,

I have a java stored procedure that worked like a charm in 9i but when I try to use it on a 10g database, it doesn't seem to work. I use it to capture the UNIX TZ environment variable of the database and place it in a PL/SQL variable. Watch how it works in 9i and then doesn't in 10g:

12:37:34 SQL> connect sys@resd as sysdba
Enter password: *******
Connected.
12:37:35 SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.7.0 - 64bit Production
PL/SQL Release 9.2.0.7.0 - Production
CORE  9.2.0.7.0    Production
TNS for Solaris: Version 9.2.0.7.0 - Production
NLSRTL Version 9.2.0.7.0 - Production

Elapsed: 00:00:00.00
12:37:45 SQL> begin
12:38:06  2 dbms_java.grant_permission
12:38:06  3 ( 'MECSPY', 'SYS:java.io.FilePermission',
12:38:06  4 '/opt/app/oracle/admin/cadhd/create/test_tz.sh',
12:38:06  5 'execute' );
12:38:06  6
12:38:06  7 dbms_java.grant_permission
12:38:06  8 ('SYS',
12:38:06  9 'java.lang.RuntimePermission',
12:38:06 10 '*',
12:38:06 11 'writeFileDescriptor' );
12:38:06 12 end;
12:38:06 13 /

PL/SQL procedure successfully completed.

Elapsed: 00:00:02.08
12:38:11 SQL> connect mecspy@resd
Enter password: *******
Connected.
12:38:29 SQL> create or replace
12:38:52  2 FUNCTION run_command_java_fx (
12:38:52  3    fv_command  IN  VARCHAR2,
12:38:52  4    fv_output  OUT VARCHAR2
12:38:52  5  )
12:38:52  6    RETURN NUMBER
12:38:52  7  AS
12:38:52  8    LANGUAGE JAVA
12:38:52  9    NAME 'NcgOSj.runOsCmd( java.lang.String,
12:38:52 10                  java.lang.String[] ) return integer';
12:38:52 11 /

Function created.

Elapsed: 00:00:00.02
12:38:53 SQL>
12:38:53 SQL> create or replace
12:38:53  2  PROCEDURE run_command_java (
12:38:53  3    fv_command  IN    VARCHAR2,
12:38:53  4    fv_output  OUT    VARCHAR2
12:38:53  5  )
12:38:53  6  IS
12:38:53  7    ln_return_code  NUMBER;
12:38:53  8  BEGIN
12:38:53  9    ln_return_code  := run_command_java_fx (fv_command, fv_output);
12:38:53 10  END run_command_java;
12:38:53 11 /

Procedure created.

Elapsed: 00:00:00.00
12:38:53 SQL>
12:38:53 SQL> CREATE OR REPLACE AND COMPILE
12:38:53  2    JAVA SOURCE NAMED "NcgOSj"
12:38:53  3  AS
12:38:53  4    import java.io.*;
12:38:53  5    import java.lang.*;
12:38:53  6   
12:38:53  7    public class NcgOSj extends Object
12:38:53  8    {
12:38:53  9    public static int runOsCmd(String OsCmdLine,
12:38:53 10                      String[] CmdOutput)
12:38:53 11    {
12:38:53 12    Runtime rt = Runtime.getRuntime();
12:38:53 13    int  rc = -1;
12:38:53 14    String coutput = " ";
12:38:53 15    String ot = " " ;
12:38:53 16
12:38:53 17    if (OsCmdLine.length() < 1) {
12:38:53 18      System.out.println("USAGE: java NcgOSj.runOsCmd \'cmd\' OutputStringVariable"
);
12:38:53 19      System.exit(1);
12:38:53 20    }
12:38:53 21    try
12:38:53 22    {
12:38:53 23      // The exec() method in java.lang.Runtime is overloaded and
12:38:53 24      // can be called in different forms. The following use illustrates
12:38:53 25      // the simplest form of exec() which takes a string as a parameter.
12:38:53 26      //
12:38:53 27      // Execute the command using the Runtime object variable 'rt' and
12:38:53 28      // get the process 'p' which controls this command
12:38:53 29      Process p = rt.exec(OsCmdLine);
12:38:53 30 
12:38:53 31      int bufSize = 4096;
12:38:53 32      BufferedInputStream bis =
12:38:53 33      new BufferedInputStream(p.getInputStream(), bufSize);
12:38:53 34      int len;
12:38:53 35      byte buffer[] = new byte[bufSize];
12:38:53 36 
12:38:53 37      // Echo back what the program spit out
12:38:53 38      while ((len = bis.read(buffer, 0, bufSize)) != -1) {
12:38:53 39        System.out.write(buffer, 0, len);
12:38:53 40        ot = new String(buffer, 0, len) ;
12:38:53 41        coutput = coutput + ot ;
12:38:53 42      }
12:38:53 43      // Wait for the process 'p' to finish and get the return code
12:38:53 44      // from the process
12:38:53 45      rc = p.waitFor();
12:38:53 46    }
12:38:53 47    catch (Exception e)
12:38:53 48    {
12:38:53 49      e.printStackTrace();
12:38:53 50      rc = -1;
12:38:53 51    }
12:38:53 52    finally
12:38:53 53    {
12:38:53 54      CmdOutput[0] = coutput;
12:38:53 55      return rc;
12:38:53 56    }
12:38:53 57    }
12:38:53 58  }
12:38:53 59 /

Java created.

Elapsed: 00:00:04.06
12:38:59 SQL> connect mecspy@resd
Enter password: *******
Connected.
12:39:06 SQL> variable outpt varchar2(2000)
12:39:31 SQL> set serveroutput on
12:39:31 SQL> exec dbms_java.set_output(100000);

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.05
12:39:33 SQL> exec run_command_java('/opt/app/oracle/admin/cadhd/create/test_tz.sh', :outpt);
US/Central

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.02
12:40:34 SQL> print :outpt

OUTPT
----------------------------------------------------------------------------------------------------
US/Central

So that worked great - the :outpt variable contains the UNIX TZ setting. Now I go over to a 10g database running on the same server and run the exact same processes including the exact same shell script:

12:43:28 SQL> connect sys@cadhd as sysdba
Enter password: ***********
Connected.
12:43:29 SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.2.0 - 64bi
PL/SQL Release 10.2.0.2.0 - Production
CORE  10.2.0.2.0    Production
TNS for Solaris: Version 10.2.0.2.0 - Production
NLSRTL Version 10.2.0.2.0 - Production

Elapsed: 00:00:00.00
12:43:40 SQL> begin
12:43:53  2 dbms_java.grant_permission
12:43:53  3 ( 'MECSPY', 'SYS:java.io.FilePermission',
12:43:53  4 '/opt/app/oracle/admin/cadhd/create/test_tz.sh',
12:43:53  5 'execute' );
12:43:53  6
12:43:53  7 dbms_java.grant_permission
12:43:53  8 ('SYS',
12:43:53  9 'java.lang.RuntimePermission',
12:43:53 10 '*',
12:43:53 11 'writeFileDescriptor' );
12:43:53 12 end;
12:43:53 13 /

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.00
12:43:54 SQL> connect mecspy@cadhd
Enter password: *******
Connected.
12:44:02 SQL> create or replace
12:44:12  2 FUNCTION run_command_java_fx (
12:44:12  3    fv_command  IN  VARCHAR2,
12:44:12  4    fv_output  OUT VARCHAR2
12:44:12  5  )
12:44:12  6    RETURN NUMBER
12:44:12  7  AS
12:44:12  8    LANGUAGE JAVA
12:44:12  9    NAME 'NcgOSj.runOsCmd( java.lang.String,
12:44:12 10                  java.lang.String[] ) return integer';
12:44:12 11 /

Function created.

Elapsed: 00:00:00.00
12:44:12 SQL>
12:44:12 SQL> create or replace
12:44:12  2  PROCEDURE run_command_java (
12:44:12  3    fv_command  IN    VARCHAR2,
12:44:12  4    fv_output  OUT    VARCHAR2
12:44:12  5  )
12:44:12  6  IS
12:44:12  7    ln_return_code  NUMBER;
12:44:12  8  BEGIN
12:44:12  9    ln_return_code  := run_command_java_fx (fv_command, fv_output);
12:44:12 10  END run_command_java;
12:44:12 11 /

Procedure created.

Elapsed: 00:00:00.00
12:44:12 SQL>
12:44:12 SQL> CREATE OR REPLACE AND COMPILE
12:44:12  2    JAVA SOURCE NAMED "NcgOSj"
12:44:12  3  AS
12:44:12  4    import java.io.*;
12:44:12  5    import java.lang.*;
12:44:12  6   
12:44:12  7    public class NcgOSj extends Object
12:44:12  8    {
12:44:12  9    public static int runOsCmd(String OsCmdLine,
12:44:12 10                      String[] CmdOutpu

Followup   August 9, 2006 - 4pm Central time zone:

everything but the sh script :(

oh well.

anyway, are you SURE the TZ environment variable is in fact set?  Why not quickly test some other 
variable - like ORACLE_HOME, pretty sure that one would be.

(just because they are on the same machine doesn't mean they have the same environment) 

5 stars Here's the .sh script and the test using it   August 10, 2006 - 8am Central time zone
Reviewer: Ron from Iowa
Here's the contents of the test_tz.sh script that shows the value of the ORACLE_HOME followed by 
the java test too:

---- in unix

dm556:/opt/app/oracle/admin/cadhd/create:oracle >cat test_tz.sh
#!/bin/ksh
export VALUE=`env | grep ORACLE_HOME | awk -F= '{print $2}'`
echo $VALUE
dm556:/opt/app/oracle/admin/cadhd/create:oracle >test_tz.sh    
/opt/app/oracle/product/10.2.0.2.0

----- back to sql*plus

07:35:34 SQL> connect sys@cadhd as sysdba
Enter password: ***********
Connected.
07:44:26 SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.2.0 - 64bi
PL/SQL Release 10.2.0.2.0 - Production
CORE    10.2.0.2.0      Production
TNS for Solaris: Version 10.2.0.2.0 - Production
NLSRTL Version 10.2.0.2.0 - Production

Elapsed: 00:00:00.00
07:44:34 SQL> begin
07:45:19   2  dbms_java.grant_permission
07:45:19   3  ( 'MECSPY', 'SYS:java.io.FilePermission', 
07:45:19   4  '/opt/app/oracle/admin/cadhd/create/test_tz.sh',
07:45:19   5  'execute' );
07:45:19   6  
07:45:19   7  dbms_java.grant_permission
07:45:19   8  ('SYS',
07:45:19   9  'java.lang.RuntimePermission',
07:45:19  10  '*',
07:45:19  11  'writeFileDescriptor' );
07:45:19  12  end;
07:45:19  13  /

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.04
07:45:19 SQL> connect mecspy@cadhd
Enter password: *******
Connected.
07:46:57 SQL> create or replace
07:47:14   2  FUNCTION run_command_java_fx (
07:47:14   3      fv_command   IN   VARCHAR2,
07:47:14   4      fv_output    OUT  VARCHAR2
07:47:14   5    )
07:47:14   6      RETURN NUMBER
07:47:14   7    AS
07:47:14   8      LANGUAGE JAVA
07:47:14   9      NAME 'NcgOSj.runOsCmd( java.lang.String,
07:47:14  10                             java.lang.String[] ) return integer';
07:47:14  11  /

Function created.

Elapsed: 00:00:00.00
07:47:14 SQL> 
07:47:14 SQL> create or replace
07:47:14   2    PROCEDURE run_command_java (
07:47:14   3      fv_command   IN       VARCHAR2,
07:47:14   4      fv_output    OUT      VARCHAR2
07:47:14   5    )
07:47:14   6    IS
07:47:14   7      ln_return_code   NUMBER;
07:47:14   8    BEGIN
07:47:14   9      ln_return_code    := run_command_java_fx (fv_command, fv_output);
07:47:14  10    END run_command_java;
07:47:14  11  /

Procedure created.

Elapsed: 00:00:00.00
07:47:14 SQL> 
07:47:14 SQL> CREATE OR REPLACE AND COMPILE
07:47:14   2      JAVA SOURCE NAMED "NcgOSj"
07:47:14   3     AS
07:47:14   4      import java.io.*;
07:47:14   5      import java.lang.*;
07:47:14   6      
07:47:14   7      public class NcgOSj extends Object
07:47:14   8      {
07:47:14   9        public static int runOsCmd(String OsCmdLine,
07:47:14  10                                   String[] CmdOutput)
07:47:14  11       {
07:47:14  12       Runtime rt = Runtime.getRuntime();
07:47:14  13       int     rc = -1;
07:47:14  14       String  coutput = " ";
07:47:14  15       String  ot = " " ;
07:47:14  16  
07:47:14  17       if (OsCmdLine.length() < 1) {
07:47:14  18           System.out.println("USAGE: java NcgOSj.runOsCmd \'cmd\' 
OutputStringVariable"
);
07:47:14  19           System.exit(1);
07:47:14  20       } 
07:47:14  21       try
07:47:14  22       {
07:47:14  23          // The exec() method in java.lang.Runtime is overloaded and
07:47:14  24          // can be called in different forms.  The following use illustrates
07:47:14  25          // the simplest form of exec() which takes a string as a parameter.
07:47:14  26          //
07:47:14  27          // Execute the command using the Runtime object variable 'rt' and
07:47:14  28          // get the process 'p' which controls this command
07:47:14  29          Process p = rt.exec(OsCmdLine);
07:47:14  30     
07:47:14  31          int bufSize = 4096;
07:47:14  32          BufferedInputStream bis =
07:47:14  33           new BufferedInputStream(p.getInputStream(), bufSize);
07:47:14  34          int len;
07:47:14  35          byte buffer[] = new byte[bufSize];
07:47:14  36     
07:47:14  37          // Echo back what the program spit out
07:47:14  38          while ((len = bis.read(buffer, 0, bufSize)) != -1) {
07:47:14  39             System.out.write(buffer, 0, len);
07:47:14  40             ot = new String(buffer, 0, len) ;
07:47:14  41             coutput = coutput + ot ;
07:47:14  42          }
07:47:14  43          // Wait for the process 'p' to finish and get the return code
07:47:14  44          // from the process 
07:47:14  45          rc = p.waitFor();
07:47:14  46       }
07:47:14  47       catch (Exception e)
07:47:14  48       {
07:47:14  49          e.printStackTrace();
07:47:14  50          rc = -1;
07:47:14  51       }
07:47:14  52       finally
07:47:14  53       {
07:47:14  54          CmdOutput[0] = coutput;
07:47:14  55          return rc;
07:47:14  56       }
07:47:14  57       }
07:47:14  58     }
07:47:14  59  /

Java created.

Elapsed: 00:00:01.01
07:47:16 SQL> connect mecspy@cadhd
Enter password: *******
Connected.
07:47:26 SQL> variable outpt varchar2(2000)
07:47:51 SQL> set serveroutput on
07:47:51 SQL> exec dbms_java.set_output(100000);

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.01
07:48:17 SQL> exec run_command_java('/opt/app/oracle/admin/cadhd/create/test_tz.sh', :outpt);

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.01
07:52:07 SQL> print :outpt

OUTPT
----------------------------------------------------------------------------------------------------


 


Followup   August 10, 2006 - 9am Central time zone:

can you tell if the script is being executed at all?  touch a file or something (eg: debug it, add 
trace/diagnostic information) 

5 stars The script's not being executed.   August 10, 2006 - 10am Central time zone
Reviewer: Ron from Iowa
That's a good idea.  I touched a file within the .sh script.  When I run it from the 9i database I 
can see the touched file on the file system - when I run it in the 10g database the touched file 
isn't there proving that the script isn't being executed.  Now I just have to figure out why. 


5 stars Cannot compile ...   August 23, 2006 - 9am Central time zone
Reviewer: Stefanie from Germany
Trying to compile the Java code I get errors:

 create or replace and compile
     java source named "Util"
     as
     import java.io.*;
     import java.lang.*;
     public class Util extends Object
     {
       public static int RunThis(String args)
       {
       Runtime rt = Runtime.getRuntime();
       int        rc = -1;
       try
        {
           Process p = rt.exec(args);
           int bufSize = 4096;
           BufferedInputStream bis =
            new BufferedInputStream(p.getInputStream(), bufSize);
           int len;
           byte buffer[] = new byte[bufSize];
           // Echo back what the program spit out
           while ((len = bis.read(buffer, 0, bufSize)) != -1)
              System.out.write(buffer, 0, len);
           rc = p.waitFor();
        }
        catch (Exception e)
        {
           e.printStackTrace();
           rc = -1;
        }
        finally
        {
           return rc;
        }
        }
 *    }
   /



Oracle tells me the following:

Util:7: Class string not found.
Util:9: Class runtime not found.
Util:9: Undefined variable or class name: runtime
Util:14: Class process not found.

And so on.

There are public synonyms and execution grants on all Java stuff under sys. My user has every 
Java-ish role assigned.
Where does this error come from?

Thanks for your help,

Steff 


Followup   August 27, 2006 - 3pm Central time zone:

can we see a cut and paste?

ops$tkyte%ORA10GR2>  create or replace and compile
  2       java source named "Util"
  3       as
  4       import java.io.*;
  5       import java.lang.*;
  6       public class Util extends Object
  7       {
  8         public static int RunThis(String args)
  9         {
 10         Runtime rt = Runtime.getRuntime();
 11         int        rc = -1;
 12         try
 13          {
 14             Process p = rt.exec(args);
 15             int bufSize = 4096;
 16             BufferedInputStream bis =
 17              new BufferedInputStream(p.getInputStream(), bufSize);
 18             int len;
 19             byte buffer[] = new byte[bufSize];
 20             // Echo back what the program spit out
 21             while ((len = bis.read(buffer, 0, bufSize)) != -1)
 22                System.out.write(buffer, 0, len);
 23             rc = p.waitFor();
 24          }
 25          catch (Exception e)
 26          {
 27             e.printStackTrace();
 28             rc = -1;
 29          }
 30          finally
 31          {
 32             return rc;
 33          }
 34          }
 35      }
 36  /

Java created.
 

5 stars Scheiss Gallier   August 23, 2006 - 10am Central time zone
Reviewer: Stefanie 
It was the asterix in the second last line ... *aaargh* ... ;o) 


5 stars unable to print out put of oerr command in pl/sql   August 28, 2006 - 3am Central time zone
Reviewer: V Bhavani Sankar from India
Dear Tom,
Thank you very much for u r example . with that example i was able to run almost all os commans.  
but i'm unable to print the output of "oerr " tool.

 Does any other settings are required for running tools like oerr.

here is sample output 
LAB65>select test1_call_cmd('/bin/ls -la') from dual;

TEST1_CALL_CMD('/BIN/LS-LA')
---------------------------------------------------------------------------------
 total 28320
drwxr-xr-x   2 oracle dba      4096 Aug 14 10:24 .
drwxr-xr-x  55 oracle dba      4096 Apr 20 17:10 ..
-rwxr-xr-x   1 oracle dba      1544 Apr 15 16:16 hc_aplab65.dat
-rwxr-xr-x   1 oracle dba      1544 Apr 13 17:05 hc_ora10g.dat
-rwxr-xr-x   1 oracle dba      1400 Jul 15 13:18 initaplab65.ora
-rwxr-xr-x   1 oracle dba     12920 May  3  2001 initdw.ora
-rwxr-xr-x   1 oracle dba      8385 Sep 11  1998 init.ora
-rwxr-xr-x   1 oracle dba        24 Apr 15 16:16 lkAPLAB65
-rw-r-----   1 oracle dba      1536 Aug 24 14:28 orapwaplab65
-rw-r-----   1 oracle dba      1536 Aug  3 16:41 orapwaplab65.bak
-rw-r-----   1 oracle dba      1536 Aug  3 17:01 orapwaplab65.bak1
-rw-r-----   1 oracle dba      1536 Aug  4 10:11 orapwaplab65.bak2
-rw-r-----   1 oracle dba  28819456 Aug 25 14:40 snapcf_aplab65.f
-rwxr-xr-x   1 oracle dba      3584 Apr 20 22:06 spfileaplab65.bak
-rw-r-----   1 oracle dba      3584 Aug 28 12:01 spfileaplab65.ora
-rwxr-xr-x   1 root   root     2622 Apr 19 15:33 sqlnet.log

LAB65>select test1_call_cmd('/apps/app/oracle/product/10.2.0/bin/oerr ora 1003') from dual;

TEST1_CALL_CMD('/APPS/APP/ORAC
-----------------------------------------------------------------------------------------------



Thank you very much for the help

 


Followup   August 28, 2006 - 10am Central time zone:

u r ???  


/bin/ls - that is an executable

/.../oerr - that is a shell script

ctl-f for cnelson and try some of that. 

5 stars Thank you for the responce.   August 29, 2006 - 3am Central time zone
Reviewer: Bhavani Sankar from India
Dear Tom,
 sorry for that "u r" in last reply.   

 i dont think my problem with enironment. because simple echo command from a script also not giving 
output. 
 when i run any script for pl/sql function  the wait status of Process p.waitfor() coming as 255.

here is what i've done.

exec 
dbms_java.grant_permission('DOTSOFT','SYS:java.io.FilePermission','/home/oracle/sayhi','execute');

contents of sayhi file
[oracle@lab65 ~]$ cat sayhi
echo hello

permission of the file
[oracle@lab65 ~]$ ll sayhi
-rwxrwxrwx  1 oracle dba 24 Aug 29 12:19 sayhi

select test_call_cmd('/home/oracle/showerr') from dual;
TEST_CALL_CMD('/HOME/ORACLE/SH
------------------------------
                           255

later i changed sayhi to 
[oracle@lab65 ~]$ cat sayhi
/usr/bin/env
echo hello

once again i run the function
SQL> select test_call_cmd('/home/oracle/sayhi') from dual;

TEST_CALL_CMD('/HOME/ORACLE/SA
------------------------------
                           255

output is same.

if i directly call 'echo' then it is ok

select test_call_cmd('/bin/echo hello') from dual;
TEST_CALL_CMD('/BIN/ECHOHELLO
-----------------------------
                            0

SQL> exec test_call_fun('/bin/echo hello');
hello

PL/SQL procedure successfully completed.

SQL> exec test_call_fun('/home/oracle/sayhi');

PL/SQL procedure successfully completed.




i got oerr output with direct grep command. my problem is solved. but i want to know why scripts 
are not running even though they are by oracle itself.

Thank you very much for your help 


Followup   August 29, 2006 - 7am Central time zone:

put a SHELL in the beginng of that script

#!/bin/sh


 

4 stars Thank you   August 30, 2006 - 3am Central time zone
Reviewer: A reader 
Thank you very much 


4 stars One More time   October 18, 2006 - 4pm Central time zone
Reviewer: Dick Goulet from Marlborough, Mass, USA
Tom,

  I found this very useful & thank you for it, but as a few above me have said I'm no JAVA head.  
What I want is to issue a 'df -k' on a file system(solaris) and get back the available disk space.  
What I get today is:

/dev/md/dsk/d2       12397228 3936915 8336341    33%    /

What I want is: 8336341

Anyway to get there from here? 


Followup   October 18, 2006 - 4pm Central time zone:

get that string from java....

and then substr it in sql/plsql :)

that is what *I* would do...

 

4 stars Host Command In Java   October 19, 2006 - 10am Central time zone
Reviewer: Dick Goulet from m
Tom,

  Can't we be a little more elegant??  I've done this with external C procedures before, but I'm 
trying to move into the 21st century.  Thanks anyway, it was worth the effort to ask. 


Followup   October 19, 2006 - 2pm Central time zone:

you may well be able to - but the problem is "i am not a java guru" either, I'm much better with 
plsql/sql and C :) 

5 stars Running o/s commands from pl/sql   November 20, 2006 - 6am Central time zone
Reviewer: a reader from england
I used the scripts from above to run the operating system command from within pl/sql. It doesn't 
return anything back to pl/sql program, it doesn't throw any error either. Below is the script that 
I have used. I know that granting privilege to /usr/bin/ksh is not a good idea, so if there is a 
workaround then please let me know.

Basically I am trying to get the available disk space on our file system. At the moment, my korn 
shell script contains hard coded file system but I ideally want to pass this as a parameter. 
However, I am not being able to run this even with the hardcoded file system, so need your help. 
Please let me know why it is not returning any result back to pl/sql program unit.

Thanks in advance


drop user rt_test cascade;

create user rt_test identified by rt_test;

grant connect, resource to rt_test;

begin
  -- Grant execute permission on df to rt_test user.
  dbms_java.grant_permission(
  'rt_test', 'java.io.FilePermission',
  '/usr/xpg4/bin/df',
  'execute');

  -- Grant execute permission on grep to rt_test user.
  dbms_java.grant_permission(
  'rt_test', 'java.io.FilePermission',
  '/usr/xpg4/bin/grep',
  'execute');

  -- Grant execute permission on awk to rt_test user.
  dbms_java.grant_permission(
  'rt_test', 'java.io.FilePermission',
  '/usr/xpg4/bin/awk',
  'execute');

  -- Grant execute permission on ksh to rt_test user.
  dbms_java.grant_permission(
  'rt_test', 'java.io.FilePermission',
  '/usr/bin/ksh',
  'execute');

  -- Grant execute permission on dfp to rt_test user.
  dbms_java.grant_permission(
  'rt_test', 'java.io.FilePermission',
  '/projects/atlas/dba/part/scripts/.temp/dfp',
  'execute');
  dbms_java.grant_permission
  ('rt_test',
  'java.lang.RuntimePermission',
  '*',
  'writeFileDescriptor' );
end;
/

-- The korn shell script /projects/atlas/dba/part/scripts/.temp/dfp contains
#!/usr/bin/ksh                                          
df -k /export/data/db1|grep "^/" | awk '{print $4;}'

------------------------------------
connect rt_test/rt_test

create or replace and compile
  java source named "Util"
  as
  import java.io.*;
  import java.lang.*;
  public class Util extends Object
  {
   public static int RunThis(String args, String[] cmdOutput)
   {
    Runtime rt = Runtime.getRuntime();
    int        rc = -1;
    String coutput = " ";
    String ot = " ";
    try
    {
     Process p = rt.exec(args);
     int bufSize = 4096;
     BufferedInputStream bis =
     new BufferedInputStream(p.getInputStream(), bufSize);
     int len;
     byte buffer[] = new byte[bufSize];
     // Echo back what the program spit out
     while ((len = bis.read(buffer, 0, bufSize)) != -1) {
       System.out.write(buffer, 0, len);
       ot = new String(buffer, 0, len);
       coutput = coutput + ot;
     }
       rc = p.waitFor();
     }
     catch (Exception e)
     {
      e.printStackTrace();
      rc = -1;
     }
    finally
    {
     cmdOutput[0] = coutput;
     return rc;
    }
   }
 }
/

create or replace function RUN_CMD( p_cmd  in varchar2, p_cmd_out out varchar2) return number as
language java
name 'Util.RunThis(java.lang.String, java.lang.String[]) return integer';
/

create or replace procedure RC(p_cmd in varchar2, p_cmd_out out varchar2) as
  x number;
begin
  x := run_cmd(p_cmd, p_cmd_out);
dbms_output.put_line('Cmd output:' || p_cmd_out);
end;
/

set serveroutput on size 1000000
execute dbms_java.set_output(1000000)
declare
  r varchar2(4000);
begin
  rc('/projects/atlas/dba/part/scripts/.temp/dfp', r);
  dbms_output.put_line('Return value:' || r);
end;
/
 


4 stars running o/s commands using java   November 21, 2006 - 7am Central time zone
Reviewer: a reader from england
Hi Tom,

Please could you reply to the above query. I am using 10.2.0.1 database.

Thanks
 


4 stars running o/s command using java   November 23, 2006 - 7am Central time zone
Reviewer: a reader from england
Hi Tom,,

Please could you reply to the query above where I am trying to return the available disk space on a 
file system?

Thanks 


2 stars Exception error   November 27, 2006 - 1am Central time zone
Reviewer: Krishna 
Hi Tom,

I am using Oracle9i Enterprise Edition Release 9.2.0.6.0 ver, I used the same code but while 
executing the procedure I am getting Exception errors 

SQL> exec rc('/u13/mdrdev/ps');
java.lang.NoSuchMethodException: No applicable method found
at
oracle.aurora.util.JRIExtensions.getMaximallySpecificMethod(JRIExtensions.java)
at
oracle.aurora.util.JRIExtensions.getMaximallySpecificMethod(JRIExtensions.java)
BEGIN rc('/u03/radartst/ps'); END;

*
ERROR at line 1:
ORA-29531: no method RunThis in class util
ORA-06512: at "MDR.RUN_CMD", line 0
ORA-06512: at "MDR.RC", line 5
ORA-06512: at line 1  

Thanks in Advance 


Followup   November 27, 2006 - 7am Central time zone:

you did something, well, wrong.

look at the code again.  You seem to be missing the "RunThis" method. 

2 stars Exception error   November 27, 2006 - 2am Central time zone
Reviewer: user 
Hi Tom,

In continuation with the above problem, I am including all the code
create or replace procedure java_permission
as
begin
        dbms_java.grant_permission
         ('MDR',
         'java.io.FilePermission',
         '/bin/ps',
         'execute');

         
         dbms_java.grant_permission
        ('MDR',
         'java.io.FilePermission',
         '/bin/sh',
         'execute');dbms_java.grant_permission
        ('MDR',
        'java.lang.RuntimePermission',
        '*',
        'writeFileDescriptor' );

   end;
--- executed sucessfully

create or replace and compile java source named util as
import java.io.*;
    import java.lang.*;
    
    public class Util extends Object
    {
      public static int RunThis(String args)
     {
     Runtime rt = Runtime.getRuntime();
     int        rc = -1;
   
     try
     {
        Process p = rt.exec(args);
   
        int bufSize = 4096;
        BufferedInputStream bis =
         new BufferedInputStream(p.getInputStream(), bufSize);
        int len;
        byte buffer[] = new byte[bufSize];
   
        // Echo back what the program spit out
        while ((len = bis.read(buffer, 0, bufSize)) != -1)
           System.out.write(buffer, 0, len);
   
        rc = p.waitFor();
     }
     catch (Exception e)
     {
        e.printStackTrace();
        rc = -1;
     }
     finally
     {
        return rc;
     }
     }
   }

-- compiled sucessfully
create or replace function RUN_CMD( p_cmd  in varchar2) return number
    as
    language java
    name 'Util.RunThis(java.lang.String[]) return integer';

-- compiled sucessfully   
create or replace procedure RC(p_cmd in varchar2)
    as
      x number;
    begin
      x := run_cmd(p_cmd);
    end;
-- compiled sucessfully 
SQL> exec rc('/bin/ps');
java.lang.NoSuchMethodException: No applicable method found
at
oracle.aurora.util.JRIExtensions.getMaximallySpecificMethod(JRIExtensions.java)
at
oracle.aurora.util.JRIExtensions.getMaximallySpecificMethod(JRIExtensions.java)
BEGIN rc('/bin/ps'); END;

*
ERROR at line 1:
ORA-29531: no method RunThis in class util
ORA-06512: at "MDR.RUN_CMD", line 0
ORA-06512: at "MDR.RC", line 5
ORA-06512: at line 1  

Thanks in Advance 
  

  


 


Followup   November 27, 2006 - 8am Central time zone:

you need to put the "" around util again in the create or replace and lose the [] in the run_cmd 
function - ctl-f on this page for ArrayI and look at the code again, you are not using what I had 
last (for 9i) 

4 stars running system commands using java   November 27, 2006 - 11am Central time zone
Reviewer: a reader from england
could you reply to my query, the one before the last question (on returning the amount of disk 
space available in a file system using java).

thanks
 


Followup   November 27, 2006 - 7pm Central time zone:

back up and simplify it.  what have you done to "debug" - have you had the script redirect to a 
file for example just to verify it "works", print out the environment, and so on. 

3 stars Run time permission error   November 28, 2006 - 7am Central time zone
Reviewer: A reader 
Hi Tom,

Thanks for your code, this is very much helpful, I am getting errors when I want to run a sh file

I got the following permissions from DBA

     dbms_java.grant_permission
         ('MDR',
         'java.io.FilePermission',
         '/bin/ps',
         'execute');

     dbms_java.grant_permission
         ('MDR',
         'java.io.FilePermission',
         '/bin/pwd',
         'execute');
         
     dbms_java.grant_permission
        ('MDR',
         'java.io.FilePermission',
         '/bin/sh',
         'execute');
     
      dbms_java.grant_permission
        ('MDR',
        'java.lang.RuntimePermission',
        '*',
        'writeFileDescriptor' );

I was able to run the following commands

exec rc('/bin/ps'); ---sucess with output
exec rc('/bin/pwd'); --output /opt/oracle/product9206/dbs 

so every command is referring to this /opt/oracle/product9206/dbs directory

Actually I need to execute a sh file which is in /u13/mdrdev directory

I got the permission for this execution from dba as
execute dbms_java.grant_permission 

('MDR','java.io.FilePermission','/bin/sh /u13/mdrdev/sample.sh', 'execute'); 

When I ran from linux this command is working 
]$ /bin/sh /u13/mdrdev/sample.sh

but when I tried to execute the same as 
exec rc('/bin/sh /u13/mdrdev/sample.sh'), I couldn't get any output

I feel the problem is in giving the permissions statement from DBA.

Your suggestions are very much needful,please help me in framing the DBA permission

Thanks in Advance

 
 


Followup   November 28, 2006 - 9am Central time zone:

do not use /bin/sh - you would give permission on /bin/sh and THAT WOULD LET YOU RUN VIRTUALLY 
ANYTHING.

grant execute on /u13/mdrdev/sample.sh

and make sure the first line of the script is

#!/bin/sh 

5 stars running o/s commands using java   December 1, 2006 - 9am Central time zone
Reviewer: a reader from england
Hi Tom,

Regarding available disk space, please see the scripts and the output below. I am using 10g 
database. The problem I am seeing is that the returned value is not captured. Please advise where 
is it going wrong.

1. Content of the korn shell script

#!/usr/bin/ksh                                      
df -k /export/data/db1|grep "^/" | awk '{print $4;}'

2. Output of the korn shell script when ran from the unix.

$ /projects/atlas/dba/part/scripts/.temp/dfp
2208752

The above korn shell script returns the size of the file system /export/data/db1 in KBytes.

3. Scripts used:

connect dbauser/dbapassword

drop user rt_test cascade;
create user rt_test identified by rt_test;
grant connect, resource to rt_test;

begin
  -- Grant execute permission on dfp to rt_test user.
  dbms_java.grant_permission(
  'RT_TEST', 'java.io.FilePermission',
  '/projects/atlas/dba/part/scripts/.temp/dfp',
  'execute');

  dbms_java.grant_permission
  ('RT_TEST',
  'java.lang.RuntimePermission',
  '*',
  'writeFileDescriptor' );
end;
/

connect rt_test/rt_test
SQL> l
  1  create or replace and compile
  2    java source named "Util"
  3    as
  4    import java.io.*;
  5    import java.lang.*;
  6    public class Util extends Object
  7    {
  8     public static int RunThis(String args, String[] cmdOutput)
  9     {
 10      Runtime rt = Runtime.getRuntime();
 11      int        rc = -1;
 12      String coutput = " ";
 13      String ot = " ";
 14      try
 15      {
 16       Process p = rt.exec(args);
 17       int bufSize = 4096;
 18       BufferedInputStream bis =
 19       new BufferedInputStream(p.getInputStream(), bufSize);
 20       int len;
 21       byte buffer[] = new byte[bufSize];
 22       // Echo back what the program spit out
 23       while ((len = bis.read(buffer, 0, bufSize)) != -1) {
 24         System.out.write(buffer, 0, len);
 25         ot = new String(buffer, 0, len);
 26         coutput = coutput + ot;
 27       }
 28         rc = p.waitFor();
 29       }
 30       catch (Exception e)
 31       {
 32  System.out.println("Error running command: " + args + "\n" + e.getMessage());
 33        e.printStackTrace();
 34        rc = -1;
 35       }
 36      finally
 37      {
 38       cmdOutput[0] = coutput;
 39       return rc;
 40      }
 41     }
 42*  }
SQL> /

Java created.

SQL> create or replace function RUN_CMD( p_cmd  in varchar2, p_cmd_out out varchar2) return number 
as
language java                                                                                       
 
name 'Util.RunThis(java.lang.String, java.lang.String[]) return integer';                           
 
/                                                                                                   
 
                                                                                                    
 
  2    3    4                                                                                       
 
Function created.


SQL> create or replace procedure RC(p_cmd in varchar2, p_cmd_out out varchar2) as 
  x number;                                                                       
begin                                                                             
  x := run_cmd(p_cmd, p_cmd_out);                                                 
dbms_output.put_line('Cmd output:' || p_cmd_out);                                 
end;                                                                              
/                                                                                 
  2    3    4    5    6    7                                                      
Procedure created.

4. Output from the procedure RC:

SQL> set serveroutput on size 1000000                           
SQL> execute dbms_java.set_output(1000000)                      
                                                                
PL/SQL procedure successfully completed.                        
                                                                
SQL> declare                                                    
  2    r varchar2(4000);                                        
  3  begin                                                      
  4    rc('/projects/atlas/dba/part/scripts/.temp/dfp', r);     
  5    dbms_output.put_line('Return value:' || r);              
  6  end;                                                       
  7  /                                                          
Cmd output:                                                     
Return value:                                                   
    
PL/SQL procedure successfully completed.
 


Followup   December 1, 2006 - 10am Central time zone:

so, echo somethings out - start simple, add stuff. see what you see.

DEBUG IT. 

5 stars a reader   December 1, 2006 - 10am Central time zone
Reviewer: a reader from england
ok. i have added few println statements as shown in the script below. the output also is shown 
below. it looks like it is not going inside the while loop. i don't know why.

create or replace and compile
  java source named "Util"
  as
  import java.io.*;
  import java.lang.*;
  public class Util extends Object
  {
   public static int RunThis(String args, String[] cmdOutput)
   {
    Runtime rt = Runtime.getRuntime();
    int        rc = -1;
    String coutput = " ";
    String ot = " ";
    try
    {
     Process p = rt.exec(args);
     int bufSize = 4096;
     BufferedInputStream bis =
     new BufferedInputStream(p.getInputStream(), bufSize);
     int len;
     byte buffer[] = new byte[bufSize];
     // Echo back what the program spit out
System.out.println("Before the loop. ");
     while ((len = bis.read(buffer, 0, bufSize)) != -1) {
       System.out.write(buffer, 0, len);
       ot = new String(buffer, 0, len);
       coutput = coutput + ot;
System.out.println("Within the loop. coutput:" + coutput);
     }
System.out.println("Before wait");
       rc = p.waitFor();
     }
     catch (Exception e)
     {
      System.out.println("Error running command: " + args + "\n" + e.getMessage());
      e.printStackTrace();
      rc = -1;
     }
    finally
    {
     cmdOutput[0] = coutput;
System.out.println("coutput in finally:" + coutput);
     return rc;
    }
   }
 }
/

SQL> l                                                     
  1  declare                                               
  2    r varchar2(4000);                                   
  3  begin                                                 
  4    rc('/projects/atlas/dba/part/scripts/.temp/dfp', r);
  5    dbms_output.put_line('Return value:' || r);         
  6* end;                                                  
SQL> /                                                     
Before the loop.                                           
Before wait                                                
coutput in finally:                                        
Cmd output:                                                
Return value:                                              
                                                           
PL/SQL procedure successfully completed.                   
 


Followup   December 1, 2006 - 10am Central time zone:

i meant put DEBUG IN THE SCRIPT.

do a couple of /bin/echo'es in there - touch a file, echo something to a file - prove that the 
script is running for example.

 

5 stars running os commands using java   December 1, 2006 - 11am Central time zone
Reviewer: a reader from england
the korn shell script is now changed to redirect the output to output.txt under the same directory. 
i ran the script from unix prompt and it did produce the file and contained the expected output. 
the output.txt file was deleted before running the procedure. after running the procedure, it did 
generate the output.txt file but it is empty. so it did call the korn shell script. the file size 
for output.txt as shown below is zero.

Korn shell script dfp:
#!/usr/bin/ksh
df -k /export/data/db1|grep "^/" | awk '{print $4;}' > 
/projects/atlas/dba/part/scripts/.temp/output.txt


SQL> declare
  2    r varchar2(4000);
  3  begin
  4    rc('/projects/atlas/dba/part/scripts/.temp/dfp', r);
  5    dbms_output.put_line('Return value:' || r);
  6  end;
  7  /
Before the loop.
Before wait
coutput in finally:
Cmd output:
Return value:

PL/SQL procedure successfully completed.

SQL> !ls -lrt /projects/atlas/dba/part/scripts/.temp/

drwxrwxr--   4 oracle   dba         2048 Sep 29 13:46 ..
-rwxrwxrwx   1 oracle   dba          120 Dec  1 16:26 dfp
-rw-rw-r--   1 oracle   dba            0 Dec  1 16:30 output.txt
drwxrwxr--   3 oracle   dba         1024 Dec  1 16:30 .
 


Followup   December 1, 2006 - 12pm Central time zone:

maybe it cannot find df and maybe stderr (which is not captured) is saying "no program df"

maybe put an explicit path on df. 

5 stars running os command using java   December 4, 2006 - 5am Central time zone
Reviewer: a reader from england
You were right, it wasn't capturing the error message.

I put the full path for df and it still wouldn't work. So I decided to trap the error message by 
adding "2> /projects/atlas/dba/part/scripts/.temp/err.txt" at the end of the df command. It 
correctly showed the error message as "awk:not found". So I put the full path for grep and awk 
commands in the shell script and it worked like a treat.

I want to thank you very much as you got me to think in the right direction. You are just the best.
 


5 stars replace string by passing parameters in unix script   December 4, 2006 - 1pm Central time zone
Reviewer: Lily from NY,USA
Tom,
We are write some unix script for our DBA tasks.when I write some unix script to 
replace string, I can use sed to accomplish it.
For example, if I want to replase string of REUSE with SET in some text file, I may do:

<dbdev2.ny.sothebys.com:oracle:anetdev:/tmp> cat rp_string.txt
REUSE

<dbdev2.ny.sothebys.com:oracle:anetdev:/tmp> vi t.ksh

#!/usr/bin/ksh

file=/tmp/rp_string.txt

cat rp_string.txt| sed 's/REUSE/SET/' > rp_string.txt.tmp

<dbdev2.ny.sothebys.com:oracle:anetdev:/tmp> chmod u+x t.ksh

<dbdev2.ny.sothebys.com:oracle:anetdev:/tmp> t.ksh

<dbdev2.ny.sothebys.com:oracle:anetdev:/tmp> more rp_string.txt.tmp
SET

But if I want to replace the string by using parameter with $ sign,
how can I do it? For example, I have some ORACLE_SID as 'prd' in the text file,
I want to replace all 'prd' to 'stg' in the text file by passing parameters $SID_1 (represents prd) 
and $SID_2( represents stg), the way using sed with string won't work. Please see below:

<dbdev2.ny.sothebys.com:oracle:anetdev:/tmp> cat rp_string.txt.2
/db/db02/oradata/prd
/db/db01/oradata/prd

<dbdev2.ny.sothebys.com:oracle:anetdev:/tmp> vi t2.ksh
"t2.ksh" 8 lines, 102 characters 
#!/usr/bin/ksh

SID_1=$1
SID_2=$2

file=/tmp/rp_string.txt.2

cat rp_string.txt.2| sed 's/$1/$2/' > rp_string.txt.tmp.2

<dbdev2.ny.sothebys.com:oracle:anetdev:/tmp> chmod u+x t2.ksh

<dbdev2.ny.sothebys.com:oracle:anetdev:/tmp> t2.ksh prd stg
<dbdev2.ny.sothebys.com:oracle:anetdev:/tmp> more  rp_string.txt.tmp.2
/db/db02/oradata/prd
/db/db01/oradata/prd

You are not only the expert for ORACLE, but also the expert for unix script, 
so could you please help me for it?

Thanks in advance.
 


Followup   December 5, 2006 - 9pm Central time zone:

hey, look at that, I've been promoted....

[tkyte@desktop ~]$ cat ./test.ksh
#!/bin/ksh

echo 'hello world' | sed "s/$1/$2/"
[tkyte@desktop ~]$ ./test.ksh hello bye
bye world
[tkyte@desktop ~]$
 

5 stars excellent answer   December 6, 2006 - 10am Central time zone
Reviewer: Lily from USA
Tom
You example is very helpful for replace the string. But how about if I want to keep all other stuff 
in the new file, like 

from

/db/db02/oradata/prd
/db/db01/oradata/prd


to

/db/db02/oradata/stg
/db/db01/oradata/stg


Thanks again.


 


5 stars Watch those quotes   December 6, 2006 - 2pm Central time zone
Reviewer: Greg from Reston, VA
Lily - if you didn't catch the change from Tom's example:

you have to use double quotes (") in ksh to get parameter substitution.  Your script has single 
quotes (').  Also - you reference an invalid file in your 'cat' command, and you set variables in 
your script, but don't use them.
  
check out this example:
#!/bin/ksh
SID_1=$1
SID_2=$2

file=/tmp/rp_string.txt.2

cat $file | sed 's/$SID_1/$SID_2/' > rp_string.txt.tmp.2
cat rp_string.txt.tmp.2

cat $file | sed "s/$SID_1/$SID_2/" > rp_string.txt.tmp.2
cat rp_string.txt.tmp.2

when I run it:
sands> ./t2.ksh prd stg
/db/db02/oradata/prd
/db/db01/oradata/prd

/db/db02/oradata/stg
/db/db01/oradata/stg
 


5 stars Excellent answer and it solved my problem   December 6, 2006 - 5pm Central time zone
Reviewer: Lily 
Tom and Greg,
Thanks sooooo much for your helps. I was so careless and didn't catch Tom's answer with double 
quotes -- I still used single quotes when testing. Thanks to Greg pointed it out.

I feel very happy and believe it is the best web site for DBA.


 


5 stars CREATE OR REPLACE AND COMPILE vs. loadjava   December 26, 2006 - 10am Central time zone
Reviewer: Stewart Bryson from Atlanta, GA
Tom:

I know you're not a Java expert, but I simply cannot find another online resource that discusses Java stored procedures. OTN has relegated it to boutique status, I guess.

What is the difference between defining the class in this manner (create or replace and compile) versus writing a class file and using loadjava to load it to the database? Is the class you've defined here able to be imported in other java stored code?

Thanks.

Followup   December 26, 2006 - 9pm Central time zone:

well, loadjava will just typically load bytecode (no source code) and doesn't compile. (normal way to use it)

create or replace and compile takes the source code, compiles it into bytecode and loads the source and bytecode.

loadjava is a standalone command line program, create or replace needs a "sqlplus like environment" to work.


http://tkyte.blogspot.com/2006/07/first-there-was.html


that is a book written by the guy that "owns" java in the database here at Oracle.

5 stars Thanks Tom   December 26, 2006 - 10pm Central time zone
Reviewer: Stewart Bryson from Atlanta, GA
I had about 20 follow-up questions, but i decided to just buy the book instead.

Thanks as always.

5 stars The Mensah book is excellent   January 4, 2007 - 12pm Central time zone
Reviewer: Stewart Bryson from Atlanta, GA
I'm only 50 pages in, and it's already worth the money. There's a nice little forward by one Mr. Tom Kyte as well.

4 stars Running OS cmd using java   January 15, 2007 - 4am Central time zone
Reviewer: praguefish from london
Hi, I get the following error when trying to run the 1st example (usr/bin/ps):
java.lang.CloneNotSupportedException
at java.lang.Object.clone(Object.java)
at java.lang.Runtime.exec(Runtime.java)
at java.lang.Runtime.exec(Runtime.java)
at java.lang.Runtime.exec(Runtime.java)
at Util.RunThis(Util.java:14)

can anyone help??

3 stars java.lang.CloneNotSupportedException   January 20, 2007 - 2am Central time zone
Reviewer: Kuassi Mensah from San Francisco, CA ,USA
> Hi, I get the following error when trying to run the 1st > example (usr/bin/ps):
> java.lang.CloneNotSupportedException
> at java.lang.Object.clone(Object.java)
> at java.lang.Runtime.exec(Runtime.java)
> at java.lang.Runtime.exec(Runtime.java)
> at java.lang.Runtime.exec(Runtime.java)
> at Util.RunThis(Util.java:14)

This looks like a bug; which version of the RDBMS (and therefore Java VM) are you using?

Kuassi,
http://db360.blogspot.com


4 stars Java SP vs PL/SQL SP   February 12, 2007 - 7am Central time zone
Reviewer: Priyanka Baxi from India
Hi Tom,

I was working on Java Stored Procedure(SP) and comparing it with PL/SQL SP.While executing the respective procedures I found that Java SP takes less time as compared to PL/SQL SP.Could you please explain why it is so?The script that I executed is as follows:


create table test_java_sp as select * from all_objects;

insert into test_java_sp select * from all_objects;

insert into test_java_sp select * from all_objects;

insert into test_java_sp select * from all_objects;

insert into test_java_sp select * from all_objects;

insert into test_java_sp select * from all_objects;

insert into test_java_sp select * from all_objects;

insert into test_java_sp select * from all_objects;

insert into test_java_sp select * from all_objects;

commit;

CREATE OR REPLACE AND COMPILE
java source named "Demo"
as
import java.sql.*;
import oracle.jdbc.driver.*;
import java.util.ArrayList;
public class Demo {
    //Call to Stored Procedure To Count The Rows
  public static int Ob(){
        try{
        Connection conn = (new oracle.jdbc.OracleDriver()).defaultConnection();
        conn.setAutoCommit(false);
        String sql = "SELECT * from test_java_sp";
        PreparedStatement prepStatement = conn.prepareStatement(sql);
        ResultSet result = prepStatement.executeQuery();
                int count1 = 0;
        if(result!=null){
          while(result.next()){
              count1++;
                        }
                      result.close();
              prepStatement.close();
          conn.commit();
            conn.setAutoCommit(true);
                      return count1;
        }
            else
              {
              return 1;
              }

    }
    catch(SQLException sqlException){
        sqlException.printStackTrace();
                return 1;
    }
   
  }

}
/




Create or replace FUNCTION Java_Demo return number is language java name 'Demo.Ob() return integer';
/



CREATE OR REPLACE FUNCTION Pl_Demo RETURN NUMBER
AS
CURSOR test_cur IS SELECT * FROM test_java_sp;
test_rec test_cur%ROWTYPE;
count1 NUMBER:=0;
BEGIN
OPEN test_cur;
LOOP
  FETCH test_cur INTO test_rec;
  EXIT WHEN test_cur%NOTFOUND;
  count1:=count1+1;
END LOOP;
CLOSE test_cur;
RETURN count1;
EXCEPTION
WHEN OTHERS THEN
  IF test_cur%ISOPEN
  THEN
        CLOSE test_cur;
    RETURN NULL;
  END IF;
    Raise_Application_Error (-20000,SQLCODE ||SQLERRM);
END;
/


set timing on

set serveroutput on
ALTER SYSTEM FLUSH SHARED_POOL;
ALTER SYSTEM FLUSH BUFFER_CACHE;
ALTER SESSION SET TRACEFILE_IDENTIFIER = 'pl_sql';

VARIABLE pl_count number

CALL Pl_Demo() into :pl_count;

ALTER SYSTEM FLUSH SHARED_POOL;
ALTER SYSTEM FLUSH BUFFER_CACHE;
ALTER SESSION SET TRACEFILE_IDENTIFIER = 'java';

VARIABLE java_count number

CALL Java_Demo() into :java_count;

Print java_count

Print pl_count

Regards,
Priyanka Baxi

Followup   February 12, 2007 - 10am Central time zone:

well, you are comparing apples to toasters.

You don't actually do anything of use here - did you trying for example accessing the data??

You would never do this code in real life, in real life a real programmer would

select count(*) from (select ....);

if they needed to count the rows.

the "reason", java is array fetching and you have (due to inefficient plsql coding) removed PLSQL's ability to do that.

In 10g, we just code:

CREATE OR REPLACE FUNCTION Pl_Demo RETURN NUMBER
AS
    count1 number := 0;
BEGIN
    for x in ( select * from test_java_sp )
    loop
        count1 := count1+1;
    end loop;
    return count1;
END;
/


and:



ops$tkyte%ORA10GR2> ALTER SYSTEM FLUSH SHARED_POOL;

System altered.

Elapsed: 00:00:00.31
ops$tkyte%ORA10GR2> ALTER SYSTEM FLUSH BUFFER_CACHE;

System altered.

Elapsed: 00:00:12.87
ops$tkyte%ORA10GR2> ALTER SESSION SET TRACEFILE_IDENTIFIER = 'pl_sql';

Session altered.

Elapsed: 00:00:00.01
ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> VARIABLE pl_count number
ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> CALL Pl_Demo() into :pl_count;

Call completed.

Elapsed: 00:00:02.56
ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> ALTER SYSTEM FLUSH SHARED_POOL;

System altered.

Elapsed: 00:00:00.28
ops$tkyte%ORA10GR2> ALTER SYSTEM FLUSH BUFFER_CACHE;

System altered.

Elapsed: 00:00:07.71
ops$tkyte%ORA10GR2> ALTER SESSION SET TRACEFILE_IDENTIFIER = 'java';

Session altered.

Elapsed: 00:00:00.03
ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> VARIABLE java_count number
ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> CALL Java_Demo() into :java_count;

Call completed.

Elapsed: 00:00:03.27
ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> Print java_count

JAVA_COUNT
----------
    451099

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> Print pl_count

  PL_COUNT
----------
    451099

ops$tkyte%ORA10GR2> set echo off
ops$tkyte%ORA10GR2>



and in 9i, we might use bulk collect - but in ALL RELEASES I WOULD ENCOURAGE YOU (demand actually) that you actually compare something "useful" - no one would write code that does this in real life, benchmarks should reflect what you need to do.
4 stars What is difference between this logic and DBMS_SCHEDULER   February 15, 2007 - 2am Central time zone
Reviewer: GopiKrishna from UAE
Hi Tom,

This is an excellent piece of work, but I heard in 10g there is DBMS_SCHEDULER PACKAGE, please explain how it differs with this logic.

Also I want to know whether any of Oracle 9i versions support DBMS_SCHEDULER package

Thanks 

Followup   February 15, 2007 - 11am Central time zone:

you can use dbms_scheduler in 10g to execute code in the operating system, yes.
5 stars   February 15, 2007 - 3pm Central time zone
Reviewer: A reader 
Tom,

I need to unzip file from Oracle PL/SQL. I am using java stored procedure from this post.

Zip file is located at UTL_FILE folder /mhsiebeldev/siebel/data/BIDAILY_MH_CUSTADDR_20070214.ZIP.
if I run below commnad from SQL*Plus nothing happens

SQL> exec rc('/bin/tar -xvZf /mhsiebeldev/siebel/data/BIDAILY_MH_CUSTADDR_20070214.ZIP')

PL/SQL procedure successfully completed.


If i run '/bin/ls -ltr' I get the below output.

Looks like I need to give correct path as command will be executed as Oracle system user

Can you please help?


SQL> exec rc('/bin/ls -ltr');
total 424
-rw-r--r--  1 oracle  amontfx  12920 Mar 8 2002 initdw.ora
-rw-rw-r--  1 oracle  amontfx    8385 Mar 9 2002 init.ora
-rw-r--r--  1 oracle  amontfx    1677 Aug 29 2005 initCRMDEV2.ora
-rw-r--r--  1 oracle  amontfx    1514 May 17 2006 initRMANDEV.temp
-rw-r--r--  1 oracle  amontfx    1574 May 17 2006 initRMANDEV.old
-rwSr-----  1 oracle  amontfx    1536 May 18 2006 orapwRMANDEV
-rw-r-----  1 oracle  amontfx    3584 May 18 2006 spfileRMANDEV.old
-rw-rw----  1 oracle  amontfx    24 May 22 2006 lkRMANDEV
-rw-r-----  1 oracle  amontfx    4608 Jun 30 2006 spfileCRMDEV.ora
-rwSr-----  1 oracle  amontfx    1536 Sep 7 16:18 orapwCRMDEV
-rw-r-----  1 oracle  amontfx    4608 Nov 22 11:01 spfileCRMDEV2.ora
-rw-r-----  1 oracle  dba      4608 Jan 29 17:00 spfileCRMDEV20129.bkp
-rw-r-----  1 oracle  dba      4608 Jan 29 17:00 spfileCRMDEV0129.bkp
-rw-r--r--  1 oracle  dba      1677 Jan 29 17:00 initCRMDEV20129.bkp
-rw-r-----  1 oracle  dba      4608 Jan 30 17:00 spfileCRMDEV20130.bkp
-rw-r-----  1 oracle  dba      4608 Jan 30 17:00 spfileCRMDEV0130.bkp
-rw-r--r--  1 oracle  dba      1677 Jan 30 17:00 initCRMDEV20130.bkp
-rw-r-----  1 oracle  dba      4608 Jan 31 17:00 spfileCRMDEV20131.bkp
-rw-r-----  1 oracle  dba      4608 Jan 31 17:00 spfileCRMDEV0131.bkp
-rw-r--r--  1 oracle  dba      1677 Jan 31 17:00 initCRMDEV20131.bkp
-rw-r-----  1 oracle  dba      4608 Feb 1 17:00 spfileCRMDEV20201.bkp
-rw-r-----  1 oracle  dba      4608 Feb 1 17:00 spfileCRMDEV0201.bkp
-rw-r--r--  1 oracle  dba      1677 Feb 1 17:00 initCRMDEV20201.bkp
-rw-r-----  1 oracle  dba      4608 Feb 2 17:00 spfileCRMDEV20202.bkp
-rw-r-----  1 oracle  dba      4608 Feb 2 17:00 spfileCRMDEV0202.bkp
dba      1677 Feb 11 17:00 initCRMDEV20211.bkp

PL/SQL procedure successfully completed.

SQL>

Followup   February 16, 2007 - 1pm Central time zone:

put some debug in there please - basic stuff - read this thread - been down this "debug it please" path over and over.
4 stars Calculator Command in windows Hangs   February 28, 2007 - 10am Central time zone
Reviewer: A reader from ISB, PK
Tom,

I ran the code you provided and made a call to the calculator application in windows xp.

exec :x := RUN_CMD('C:\windows\system32\calc.exe')

The calc.exe runs but it Hangs. When i kill it at OS level the  function completes successfully.

I don't understand what kind of interaction the calculator is asking. I made a batch file :

do_calc.bat
@echo off
c:\windows\system32\calc.exe

When I double click this batch file it calls the calculator.

Please guide me through this?

Followup   February 28, 2007 - 3pm Central time zone:

the database is running as a service

the service doesn't have a console, it is running in the background

so, when the service that is the database runs "calc.exe", it is running somewhere off in the ether - it cannot see your console.
5 stars   March 2, 2007 - 9am Central time zone
Reviewer: A reader 
Hmmm, I understand that. Thanks for a brief explanation.

But then I have another question.

How to call the calculator from a database procedure?

Thank you for your time.

Followup   March 4, 2007 - 6pm Central time zone:

why would you want to call a GUI from a stored procedure - what would you possibly accomplish that way?
4 stars Java Web service calling C executable on OC4J   March 2, 2007 - 8pm Central time zone
Reviewer: Gayatri from Redwood Shores, CA USA
Tom,

I am looking for a way to expose C executable as a web service using Jdev. So I have created a java class that calls the C executable:

public class JavaInvokeC {
    public JavaInvokeC() {
    }

    public int invoke() throws java.io.IOException, 
                               java.lang.InterruptedException {
        String program = 
            "G:\\public_html\\targetexe.exe 11";
        System.out.println("invoking program: " + program);
        Process p = Runtime.getRuntime().exec(program);
        int exitValue = p.waitFor();
        System.out.println("exit val: " + p.exitValue());
        return exitValue;
    }
}

This code runs fine when I call this method from another class' Main method in Jdev. I am able to convert this java class into a web service and deploy the web service on the standalone OC4J. However the C executable is not being invoked.

I get back a message from the web service as 'Unable to get header stream in saveChanges'.

The method you have described is for executing unix command on a Database server. Is there something similar for OC4J. How can I get OC4J to run the C executable that is invoked by the Java web service?

Any pointers of how I can resolve this problem will help.

Thank you

Gaya3

Followup   March 4, 2007 - 12pm Central time zone:

what is "g:"

it is a network drive or something

can you not debug your java - have it print out useful stuff like "checking for file existence, found file, file is executable, attemtping to execute file.... blah blah blah..."
5 stars java code   March 4, 2007 - 3pm Central time zone
Reviewer: A reader 
The java code is very useful.

5 stars run COMMAND   March 4, 2007 - 3pm Central time zone
Reviewer: sam 
Tom:

Can you use RUN_CMD above to actually run perl or unix shell scripts from PL/SQL and pass parameters from PL/SQL.

FOr example, let us say I have a perl program that creates directories on the fielsystem (mkdir).

Can I have pl/sql read a column value in a table and then do create a directory on the file system /A or /B

If (field='A') then
run_cmd my_perl_program(A);
elsif (filed='B') then
run cmd my_perl_program(B);
END IF;


2. Would the run_CMD work for remote unix server through the web server on the remote machine? Does that perl have to be in the web server directory.

Followup   March 4, 2007 - 7pm Central time zone:

you can use run_cmd to pretty much run whatever you can type on the command line, yes.

if you can type:

$ my_perl_program(A)

then yes.

and run cmd will run things on the DATABASE SERVER only
5 stars run command   March 4, 2007 - 8pm Central time zone
Reviewer: sam 
Tom:

1. What do you mean by database server only? you mean the file system where the database is running?

2. Is there a way to do it on a remote system if you have a userid/password for the remote machine?

3. or by running a CGI program on the remote machine using a URL with utl_http?

Followup   March 5, 2007 - 12pm Central time zone:

1) yes.
2) no, well, that file system would have to be made available to the database server.
3) you would be posting the file, back to square one - right where you started from in the first place.
5 stars PL/SQL script for clean-up dump directories   April 10, 2007 - 1pm Central time zone
Reviewer: Kamran from CA
I wonder is it possible to clean up the bdump and udump directories based on a time parameter !




Followup   April 10, 2007 - 3pm Central time zone:

sure it is, not sure I'd use plsql (you'd need to use a bit of java to read the directory...)

if you don't care about them, just limit the max dump size to zero (apparently you don't)

or write a shell script and let cron (or whatever works like cron on your OS) wipe em out.
5 stars PL/SQL cycle alert log   April 10, 2007 - 1pm Central time zone
Reviewer: kamran from CA
Hi,

Could you give me a trick how to clean-up the bdump and udump directories on a time parameter from PL/SQL script !


Reg.

Kamran

Followup   April 10, 2007 - 3pm Central time zone:

why do you ask TWICE!?
5 stars Appologize   April 10, 2007 - 5pm Central time zone
Reviewer: kamran from CA
I appologize for it .It was my mistake as I thought, my first submt was unsuccessful. But it was there. I'll be careful next time !

5 stars Thanks   April 12, 2007 - 11am Central time zone
Reviewer: Kamran from CA
wow, great, after setting max_dump_size=0, our problem has been solved.

Thanks again !




5 stars utl_file   April 16, 2007 - 1pm Central time zone
Reviewer: Kamran from C
I have a slight change in the requirement.

We don't like to use max_dump_size as on some of our databases we need all trace files
without any size specification. We would to just remove trace files after 7 days on all of
our servers ranging from oracle 8 to oracle 10g. Due to a vast rang of databases , we also
don't like to use java inside pl/sql .

This is some sort of management decision to use pl/sql without java and not to use parameter.

Is it possible to use utl_file package for this purpose ! If yes, kindly let me know how to do this. I'm in a horrible condition :)




Thx.

Kamran

Followup   April 16, 2007 - 1pm Central time zone:

you need java to read the directory and then, as stated, utl_file can fremove a file.

but you need to know the NAME of the file over 7 days and for that you will write java.

so, I'd probably rather just schedule a cron job and be done with it. A simple FIND command would do this in one line of shell script

you could even use dbms_scheduler in 10g to run said shell script if you wanted.
4 stars Regarding JVM Installation   May 9, 2007 - 2am Central time zone
Reviewer: A reader 
Hi Tom,

Our Java team has written Java stored procedures and packaged them in a JAR file.

They use loadjava utility to deploy the jar file in the database.

The deployment would happen from an Application Server and the Java Stored Procedures would be running on Database Server.

They have raised a concern saying that do they need to mention any pre-requisite for using loadjava on Application Server and JSP(JVM installed in database and the version of it).

Database Server Version : 10.2.0.3
Database Client Version : 9.2.0.8

Regards,
Sourabh S Jain

5 stars Need Function To Obtain Output   June 5, 2007 - 1pm Central time zone
Reviewer: JC from El Segundo , CA
Hi Tom


Thanks in advance for the JAVA code.

I have been able to modify your java to use on Windows OS and I was hoping that you could show me some code that calls the java procedure, captures the output into a buffer, and returns that buffer of information in a function call.


Thanks

Followup   June 6, 2007 - 1pm Central time zone:

in your program, just call dbms_output.get_lines (after making sure to have enabled dbms_output.enable)

it is in the dbms_output "buffer", sqlplus just calls get_lines to print to your screen, you can do the same.

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:45027262935845

5 stars Just A Thank You   June 6, 2007 - 2pm Central time zone
Reviewer: Jim from El Segundo, CA
I will look at this info you provided.
Just wanted to say thanks for your patience and guidence
I appreciate your knowledge being shared to folks like me that do not nearly have half the expertise.



5 stars Much simpler way to get TZ variable setting   July 11, 2007 - 2pm Central time zone
Reviewer: Ron from Iowa
I stumbled across the following method to get the TZ variable that the database was started with rather than having to use java to read the UNIX shell variable:

17:11:21 SQL> connect system@cado
Enter password: *******
Connected.
12:59:52 SQL> select dbms_scheduler.GET_SYS_TIME_ZONE_NAME from dual;

GET_SYS_TIME_ZONE_NAME
---------------------------------------------------------------------
UTC

Elapsed: 00:00:00.05

Too cool.

3 stars "sed" not found error when java procedure calls a unix script from oracle database   July 23, 2007 - 2pm Central time zone
Reviewer: Ravinder from Boston,MA USA
we are getting an error "sed" not found when a java procedure calls a shell script from a 
database/plsql

below are the steps to call a shell script from java procedure(java procedure inturn called from 
plsql)
****************************************************
Step1:
create or replace
   FUNCTION run_cmd (cmd IN VARCHAR)
  RETURN NUMBER
  AS LANGUAGE JAVA NAME 'Utils.runScript(java.lang.String) return java.lang.String';
**********************************************************
step 2:
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "Utils" AS
import java.io.*;
import java.lang.*;

public class Utils {
  static public int runScript(String cmd)
  throws IOException, InterruptedException {
    int rv = -1;
    Process proc = Runtime.getRuntime().exec(cmd);
    InputStream err = proc.getErrorStream();
    InputStream outProc = proc.getInputStream();
    int nreadErr, nreadOut;
    byte[] buf = new byte[1024];
    do {
      nreadErr = err.read(buf);
      if (nreadErr > 0) {
    System.err.write(buf,0,nreadErr);
      }
      nreadOut = outProc.read(buf);
      if (nreadOut > 0) {
    System.out.write(buf,0,nreadOut);
      }
    } while (nreadErr>0 && nreadOut>0);
    rv = proc.waitFor();

    return rv;
  }
  static public int raiseError(String uxcode, String message)
  throws IOException, InterruptedException {
    int rv = -1;
    String cmdarray[] = new String[7];
    cmdarray[0] = "/bin/logger";
    cmdarray[1] = "-i";
    cmdarray[2] = "-p";
    cmdarray[3] = "local0.err";
    cmdarray[4] = "-t";
    cmdarray[5] = uxcode;
    cmdarray[6] = message;
    Process proc = Runtime.getRuntime().exec(cmdarray);
    rv = proc.waitFor();

    return rv;
  }
  static public String getProperty(String name) {
    String val = "";
    try {
      val = System.getProperty(name);
    } catch (Exception excp) {
      val = excp.toString();
    }
    return val;
  }
}

************************************************************
we are using 10.2.0 (10g),Solaris 5.10 and oracle application 11.5.10



it is working fine in oracle 9.2.0 and Solaris 5.10

Please let me know what could be the problem for throwing this error.



Followup   July 24, 2007 - 9am Central time zone:

you are making assumptions about your environment

your path is not what you think it is, it is the path of the dedicated server.

use fully qualified paths in your script - to avoid trojans, to be sure you are running what you think you should be running, and to avoid this.
4 stars Possible side effect   September 11, 2007 - 12pm Central time zone
Reviewer: Mahomed Suria from U.K
I am using the following java stored proc to run a unix shell command through the oracle users job 
schedule.

CREATE OR REPLACE and COMPILE JAVA SOURCE
NAMED "MyCommand"
AS
import java.io.*;
import java.lang.*;

public class MyCommand extends Object
{

  public static int RunThis(String args)
  {
    Runtime rt = Runtime.getRuntime();
    int        rc = -1;

    try
    {
       Process p = rt.exec(args);

       int bufSize = 4096;
       BufferedInputStream bis =
        new BufferedInputStream(p.getInputStream(), bufSize);
       int len;
       byte buffer[] = new byte[bufSize];

       // Echo back what the program spit out
       while ((len = bis.read(buffer, 0, bufSize)) != -1)
          System.out.write(buffer, 0, len);

       rc = p.waitFor();
       // do not leave object lying around, good practice to destroy
       p.destroy();
    }
    catch (Exception e)
    {
      e.printStackTrace();
      rc = -1;
    }
    finally
    {
      return rc;
    }
  }
}
/

I have a possible side effect which is that some processes of the form ora_j.... are being left 
behind.

e.g 
oracle9 15177     1  4  Sep  1  ?        18:47 ora_j000_DB9
oracle9 15115     1  0  Sep  1  ?         9:46 ora_j002_DB9
oracle9 15179     1  0  Sep  1  ?        14:38 ora_j001_DB9

When I examine these processes, they have always run or are running the following sql:

select longdbcs from javasnm$ where short = :1

Any help would be appreciated !!




Followup   September 15, 2007 - 3pm Central time zone:

those are just the job queue processes, they will eventually go away, they will be idle (not actually RUNNING that sql, that might have been the last bit they ran) when not executing a job.
3 stars Accessing different server through oracle   October 4, 2007 - 8am Central time zone
Reviewer: Shubham from Mumbai, India
Hi Tom,

I have a oracle instance in a Unix server (say A) and Informatica instance on another Unix server 
(say B).
(earlier both were on same server).

I have datafiles comming on B which is manipulated from Pl/Sql procedure on server A.
What should I do in this case.
Do we have something as sharing in Unix, which can suffice my need.

Thanks


4 stars preserving/setting env's   October 4, 2007 - 1pm Central time zone
Reviewer: Tanya from Beaverton, OR
Hi Tom,

I have this whole setup working, but am running into some environment problems.

I have tested the script that I'm calling from my ApEx app and it works fine at the UNIX level as 
oracle user.  However, when it is called thru Apex, most of my PATH is just GONE!!!  to system 
level commands such as wc and grep.  

I've tried setting my env in my script but that doesn't seem to do any good.

Any ideas?

Thanks,  Tanya.


5 stars perl script   October 8, 2007 - 7am Central time zone
Reviewer: A reader 
Dear Tom,
 I need to run a perl command thru pl-sql.

BEGIN
dbms_java.set_output(1000000);
rc('/nikhilesh/test.sh');
rc('/usr/bin/perl -p -i -e ''s/Sam/Ram/g'' /nikhilesh/test.dat');
rc('/usr/bin/cat /nikhilesh/test.dat');
END;

test.sh contains
#!/bin/ksh
ls /projects/GLOSSIBaseline/Deployments/DataStream/Reports/ravi
perl -p -i -e 's/Sam/Ram/g' test.dat
cat /nikhilesh/test.dat

All permissions are in place. It doesn'r throw any error.
executes ls and cat properly but dosent change ravi.dat as a result of perl command.

    BEGIN
    
dbms_java.grant_permission('NIKHIL','SYS:java.io.FilePermission','/nikhilesh/*','read,write,execute'
);
            dbms_java.grant_permission
            ('NIKHIL',
             'SYS:java.io.FilePermission',
             '/usr/bin/perl',
             'execute');
            dbms_java.grant_permission
            ('NIKHIL',
             'SYS:java.io.FilePermission',
             '/usr/bin/ls',
             'execute');
            dbms_java.grant_permission
            ('NIKHIL',
             'SYS:java.io.FilePermission',
             '/usr/bin/cat',
             'execute');
            dbms_java.grant_permission
            ('NIKHIL',
            'java.lang.RuntimePermission',
            '*',
            'writeFileDescriptor' );
       END;

Could you please help.
Thanks in advance.

Nikhilesh


5 stars Rights Issue   October 9, 2007 - 2pm Central time zone
Reviewer: BC from macomb twp, mi
I am running into invoker vs definer rights issue.
The objective is as follows
"GENERAL" is to house all common utilities. ( We have several users / schemas that use utilities stored in this schema )
"APP" should be able to execute this utility ( Listed below )

GRANTEE         TYPE_NAME                           NAME                                ACTION      
                               SEQ ENABLED
--------------- ----------------------------------- ----------------------------------- 
----------------------------------- ---------- --------
GENERAL         java.lang.RuntimePermission         readFileDescriptor                              
                               464 ENABLED
GENERAL         java.lang.RuntimePermission         writeFileDescriptor                             
                               444 ENABLED
APP             java.io.FilePermission              /usr/bin/script1                    execute     
                               507 ENABLED
APP             java.lang.RuntimePermission         readFileDescriptor                              
                               505 ENABLED
APP             java.lang.RuntimePermission         writeFileDescriptor                             
                               504 ENABLED


When I log in as "APP" and execute the following

declare
   l_num number;
begin
   l_num := system_command.run_command('/usr/bin/script1 /usr2/dev/app/out/file_to_process.txt');
end;
/


I get the below message

java.security.AccessControlException: the Permission (java.io.FilePermission /usr/bin/script1 
execute) has not
been granted to GENERAL. The PL/SQL to grant this is dbms_java.grant_permission( 'GENERAL', 
'SYS:java.io.FilePermission',
'/usr/bin/script1', 'execute' )
        at java.security.AccessControlContext.checkPermission(AccessControlContext.java)
        at java.security.AccessController.checkPermission(AccessController.java)
        at java.lang.SecurityManager.checkPermission(SecurityManager.java)
        at oracle.aurora.rdbms.SecurityManagerImpl.checkPermission(SecurityManagerImpl.java)
        at java.lang.SecurityManager.checkExec(SecurityManager.java)
        at java.lang.Runtime.exec(Runtime.java)
        at java.lang.Runtime.exec(Runtime.java)
        at java.lang.Runtime.exec(Runtime.java)
        at java.lang.Runtime.exec(Runtime.java)
        at java_util.RunCmd(JAVA_UTIL:32)
-1


In the "GENERAL" schema, I created the following,

create or replace and compile java source named java_util authid current_user as
import java.io.*;
import java.sql.*;

public class java_util
{

   public static int RunCmd(String args)
   {
      Runtime rt = Runtime.getRuntime();
      int rc = -1;
      try
      {
         Process p = rt.exec(args);
         int bufSize = 4096;
         BufferedInputStream bis =
         new BufferedInputStream(p.getInputStream(), bufSize);
         int len;
         byte buffer[] = new byte[bufSize];

         // Echo back what the program spit out
         while ((len = bis.read(buffer, 0, bufSize)) != -1)
            System.out.write(buffer, 0, len);
            rc = p.waitFor();
      }
      catch (Exception e)
      {
         e.printStackTrace();
         rc = -1;
      }
      finally
      {
         return rc;
      }
   }
}   

create or replace package system_command authid current_user is
   
   function run_command
   (
      p_command          in          varchar2
   )
   return number;
   
end system_command;
   
create or replace package body system_command is

   function run_command
   (
      p_command          in          varchar2
   )
   return number 
   as
   language java name 'java_util.RunCmd(java.lang.String) return integer';
   
end system_command;


The shell script contains the following
/usr/bin/script1 
================
#!/usr/bin/ksh
GNUPGHOME=/systemadmin/gpg
export GNUPGHOME
/usr/bin/gpg -quite --yes --batch --armor --no-permission-warning -e -r xxx -o yyy $1
Return=$?


When I grant execute on /usr/bin/script1 to "GENERAL" the programs work as expected. I don't want to do that as we have several users / applications that may uses these utilities.

Database Version 10.2
Operating System Linux

Tom, Thank you very much your help is highly appreciated.



5 stars Thanks   October 17, 2007 - 2pm Central time zone
Reviewer: BC from macomb twp, mi
Tom,

I found the answer to this in your followup ( Followup  June 6, 2007 - 12pm US/Eastern) to another post.

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:255615160805


Thank you, you are awesome.

BC

5 stars CloneNotSupportedException   October 26, 2007 - 4am Central time zone
Reviewer: Asis from india
Hi Tom,

I am executing the below procedure as explained above and getting the error:

declare
 x number;
begin
dbms_java.set_output(1000000);
dbms_output.enable(1000000);
 x:=run_cmd('/home/oracle/upload/ls');
 dbms_output.put_line('Returned value='||x);
exception
  when others then dbms_output.put_line('Sql error='||substr(sqlerrm,1,250));
end;
/

java.lang.CloneNotSupportedException
        at java.lang.Object.clone(Native Method)
        at java.lang.Runtime.exec(Runtime.java:543)
        at java.lang.Runtime.exec(Runtime.java:491)
        at java.lang.Runtime.exec(Runtime.java:457)
        at Util.RunThis(Util:11)

Any idea how to resolve this clone not supported exception?


Followup   October 29, 2007 - 10am Central time zone:

you know what, that exception block of yours makes me ill.

I
will
never
understand

I will never ever understand why people do that. Time after time after time.

Makes me sick. Makes me frightened for the future of programming.

I refuse to look at anything that has it anymore. I consider when others, not followed by raise, to be a bug. Maybe that is your issue (it isn't, but I refuse to look any further).

Please - tell us why you do that - when others re-print the error and make the error code GO AWAY so no one knows that an error happened.

Why did you waste the keystrokes - what is the thought process behind catching ALL and ANY exception and hiding it?
3 stars java.lang.CloneNotSupportedException   October 29, 2007 - 2am Central time zone
Reviewer: Asis from india
Hi Tom,

I have been struggling to get this work for weeks now but unable to understand whether my 
10.2.0.1.0 version 10g database does not understand the code or i am doing something wrong.

I would appreciate your input on this please..

Thanks,
Asis


Followup   October 29, 2007 - 12pm Central time zone:

I cannot reproduce, cut and paste this example from your system for us.



ops$tkyte%ORA10GR2> drop user rt_test cascade;

User dropped.

ops$tkyte%ORA10GR2> create user rt_test identified by rt_test;

User created.

ops$tkyte%ORA10GR2> grant create session, create procedure to rt_test;

Grant succeeded.

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> begin
  2    dbms_java.grant_permission
  3    ('RT_TEST',
  4     'java.io.FilePermission',
  5     '/bin/ls',
  6     'execute');
  7
  8    dbms_java.grant_permission
  9    ('RT_TEST',
 10     'java.lang.RuntimePermission',
 11     '*',
 12     'writeFileDescriptor' );
 13  end;
 14  /

PL/SQL procedure successfully completed.

ops$tkyte%ORA10GR2> connect rt_test/rt_test
Connected.
rt_test%ORA10GR2> create or replace and compile
  2  java source named "Util"
  3  as
  4  import java.io.*;
  5  import java.lang.*;
  6
  7  public class Util extends Object
  8  {
  9    public static int RunThis(String args)
 10    {
 11    Runtime rt = Runtime.getRuntime();
 12    int        rc = -1;
 13
 14    try
 15    {
 16       Process p = rt.exec(args);
 17
 18       int bufSize = 4096;
 19       BufferedInputStream bis =
 20        new BufferedInputStream(p.getInputStream(), bufSize);
 21       int len;
 22       byte buffer[] = new byte[bufSize];
 23
 24       // Echo back what the program spit out
 25       while ((len = bis.read(buffer, 0, bufSize)) != -1)
 26          System.out.write(buffer, 0, len);
 27
 28       rc = p.waitFor();
 29    }
 30    catch (Exception e)
 31    {
 32       e.printStackTrace();
 33       rc = -1;
 34    }
 35    finally
 36    {
 37       return rc;
 38    }
 39    }
 40  }
 41  /

Java created.

rt_test%ORA10GR2> create or replace
  2  function RUN_CMD(p_cmd in varchar2) return number
  3  as
  4  language java
  5  name 'Util.RunThis(java.lang.String) return integer';
  6  /

Function created.

rt_test%ORA10GR2> create or replace procedure RC(p_cmd in varchar2)
  2  as
  3    x number;
  4  begin
  5    x := run_cmd(p_cmd);
  6  end;
  7  /

Procedure created.

rt_test%ORA10GR2> variable x number;
rt_test%ORA10GR2> set serveroutput on
rt_test%ORA10GR2> exec dbms_java.set_output(100000);

PL/SQL procedure successfully completed.

rt_test%ORA10GR2> exec :x := RUN_CMD('/bin/ls /tmp');
1_62.dbf
1_63.dbf
1_64.dbf
1_65.dbf

5 stars executing custom shell script from PL/SQL   November 8, 2007 - 12am Central time zone
Reviewer: Asis from india
Hi Tom,

I am trying to execute a custom shell script and not a command. I am giving the 
SYS:java.io.FilePermission to execute the custom shell script which will call sql loader to load 
data into table - but this is showing again the following error:
java.lang.CloneNotSupportedException
        at java.lang.Object.clone(Native Method)
        at java.lang.Runtime.exec(Runtime.java:543)
        at java.lang.Runtime.exec(Runtime.java:491)
        at java.lang.Runtime.exec(Runtime.java:457)
        at Util.RunThis(Util:11)
Returned value=-1
I would appreciate your guidance on this please...
Thanks a lot


5 stars It Worked!   November 8, 2007 - 5am Central time zone
Reviewer: Asis from india
Hi Tom,

It worked. I replaced java.io.FilePermission with SYS:java.io.FilePermission, as i was giving the 
permissions from SYS account.

Thanks a lot.


5 stars cal shell script from pl/sql proc   November 13, 2007 - 2am Central time zone
Reviewer: kanna from india
Thanks Tom for the above java proc to call a script file.......


but is that i have very little knowledge to understand this but i have to get this done as early as 
possible i mean calling a shell script from plsql .....

i have run successfully the java proc UTIL ..
please find below wht i have done

create or replace and compile
    java source named "Util"
    as
    import java.io.*;
    import java.lang.*;
    
    public class Util extends Object
    {
     public static int RunThis(String args)
     {
     Runtime rt = Runtime.getRuntime();
     int        rc = -1;
     try
     {
        Process p = rt.exec(args);
        int bufSize = 4096;
        BufferedInputStream bis =
         new BufferedInputStream(p.getInputStream(), bufSize);
        int len;
       byte buffer[] = new byte[bufSize];
   
        // Echo back what the program spit out
        while ((len = bis.read(buffer, 0, bufSize)) != -1)
           System.out.write(buffer, 0, len);
        rc = p.waitFor();
     }
     catch (Exception e)
     {
        e.printStackTrace();
        rc = -1;
     }
     finally
     {
        return rc;
     }
     }
   }
   -------------------------------

create or replace
  function RUN_CMD(p_cmd in varchar2) return number
  as
  language java
name 'Util.RunThis(java.lang.String) return integer';

------------------------------------

create or replace procedure RC(p_cmd in varchar2)
  as
    x number;
  begin
   x := run_cmd(p_cmd);
 end;
 




begin
   dbms_java.grant_permission
   ('APPS',
  'java.io.FilePermission',
    '/usr/bin/ls',
  'read, write, execute, delete');

   dbms_java.grant_permission
   ('APPS',
  'java.io.FilePermission',
    '/usr/tmp/sh',
  'read, write, execute, delete');


  dbms_java.grant_permission
 ('APPS',
    'java.lang.RuntimePermission',
   '*',
     'writeFileDescriptor' );
  end;

---------------------------

variable x number;
 set serveroutput on
exec dbms_java.set_output(100000);

exec :x := RUN_CMD('/usr/bin/ls /tmp');

we r getting all the files listed in folder /tmp

but we r unable to do this below where we would like to create a log file using this command

exec :x := RUN_CMD('/usr/tmp/sh tst.sh');

can you pls let us know whts going wrong from our side










Followup   November 16, 2007 - 2pm Central time zone:

these are words that scare me to death:

but is that i have very little knowledge to understand this but i have to get
this done as early as possible i mean calling a shell script from plsql .....


translation:

I have no idea what I'm doing.
But this looks like it might do something useful.
I have no idea how it works, or what security implications there might be and I won't take the time to get there.
Please make it do what I mean to do.


your attempt to run a shell script by granting execute on sh to this user opens up the ability to run ANY SHELL SCRIPT AS ORACLE by this user.

that and the "a" and "e" keys are apparently broken on your keyboard.


you'll find you have a permission or environment problem. does /usr/tmp/sh exist. is it executable by the ORACLE process (you should get a cold shudder if the answer is yes hopefully now - now that you understand the rather large hole you've exposed in your system).


I suggest:

if you have 10g, use dbms_scheduler, it can run external processes. And scripts. And if you follow its directions, you stand a chance of securing it a bit too...

4 stars execute Unix script from java stored procedure   December 8, 2007 - 12pm Central time zone
Reviewer: Krishna Chaitanya from US
Hi Tom,

i used the java stored procedure to execute a unix script from oracle.

but it works only halfway. while trying to FTP the file it doesnt work.while this script works when 
executed through unix server.

#!/usr/bin/sh
VALUE=`sqlplus -s safari_owner/welcome@colldmqa <<END
rem -------------------
set linesize 80
set arraysize 1
set verify off
set feedback off
rem -------------------

set serveroutput on

whenever oserror  exit sql.oscode
whenever sqlerror exit sql.sqlcode

execute safari_owner.SAFARI_UPLOAD_FILE_STATUS;
exit sql.sqlcode;
END`
echo $VALUE
if [ -z "$VALUE" ]; then
              echo "No rows returned from database"
              exit 0
            else
e=`head -1 "$VALUE"|awk '{print $1}'`
ft="ftp_xml_file_new.sh $e"
sh $ft
fi



please help ....the java program and oracle function and procedure works well to execute a simple 
script like "echo"
let me know if you require the to check the java procedure and oracle funtion and procedure.


its really urgent for me ..
Thanks
Krishna


Followup   December 10, 2007 - 10am Central time zone:

well, not any clue for you

since I don't have your entire suite of scripts.

I would suggest perhaps adding some DEBUG to your scripts, so you can see what is and what is not getting executed.

that is where I would start.
4 stars trigger executing SP that calls unix script   December 10, 2007 - 8pm Central time zone
Reviewer: Krishna Chaitanya from US
Hi Tom,

it was my mistake and i resolved it.
just wanted to know is there any way to create such a tigger from which we can pass values to the 
procedure that executes Unix script.

Basically your oracle procedure helped me to execute Unix script but i am unable to execute this 
procedure through trigger (AFTER INSERT )  and take the values as reference in Unix script..

please help me to get this problem resolved.

Thanks in advance.
Krishna


Followup   December 11, 2007 - 7am Central time zone:

you just "pass them in"


exec rc('/usr/bin/ps -ef');

just like that.
3 stars   December 11, 2007 - 10am Central time zone
Reviewer: krishna chaitanya from US
Hi Tom,

below is the code of the trigger that i am using to execute the script.but i need the value of the 
in this procedure.
how to pass values(:new.file_name :new.FILE_UPLOAD_KEY :new.UPLOAD_STATUS_CODE) in the procedure 
with the help of trigger.

CREATE OR REPLACE TRIGGER safari_owner.safari_upload_trig
AFTER INSERT
ON safari_owner.SAFARI_UPLOAD_REQUEST
REFERENCING NEW AS NEW
FOR EACH ROW
BEGIN
dbms_output.enable(1000000);
dbms_java.set_output(1000000);
safari_owner.rc('/usr/bin/sh /home/powermart/krishna/scripts/retry :new.file_name 
:new.FILE_UPLOAD_KEY :new.UPLOAD_STATUS_CODE');
END;
/

pleae help..

Thanks
Krishna 


Followup   December 11, 2007 - 11am Central time zone:

concatenate - you build a string....

(careful there, you gave execute on /usr/bin/sh - you can execute ANYTHING, that would not fly on a real production system, quite dangerous)


..../scripts/retry ' || :new.file_name || ' ' || :new.file_upload_key .....


3 stars   December 11, 2007 - 11am Central time zone
Reviewer: krishna chaitanya from US
thanks tom for the great suggesstion.


3 stars   December 11, 2007 - 5pm Central time zone
Reviewer: krishna chaitanya from US
Hi Tom,

i am stuck at one point and need your help very urgently.
Problem: how can i take the output of unix script as a out parameter of the procedure written below 
that executes the unix script

CREATE OR REPLACE procedure SAFARI_OWNER.RC(p_cmd in varchar2)
as
x number;
begin
x := run_cmd(p_cmd);
end;
/

please suggest.

Thanks in advance
Krishna


5 stars One question on this issue   December 12, 2007 - 11pm Central time zone
Reviewer: Reader from India from India
Say I have two databases OraDB1 and OraDB2. I have written a Java class in OraDB2. Can I access 
this class from a Java or PL/SQL procedure in OraDB1. (not through DB LINK)


Followup   December 13, 2007 - 9am Central time zone:

by magic?

I mean - come on - without the dblink how do you think this would work.


In theory, you could load the type-4 thin jdbc driver into the database and open a connection to the remote server using a jdbc java program you load into db1 - but that would be "not an easy or smart thing" to do. It would not be able to participate in the same transaction, you'd have to pass a username and password around, ugh.

A database link is the correct approach here.
4 stars connection of .net with oracle backend   December 14, 2007 - 11pm Central time zone
Reviewer: Krishna Chaitanya from US
Hi Tom,

i really appreciate for the quick response and very useful clues.
again i have a big prob,
basically i have a frontend application from which user generates a file name and this filename 
entry goes to a table.
now since i have trigger on the same table so this trigger calls the proc and finally proc executes 
the unix script and it takes around 2-3 hrs to complete this script functionality.
so i wanted to know if i generate the file name from the frontend then i close the frontend window 
at the same time so will the backgound process will continue its execution or not. because user 
will generate the file name but he should not wait for the whole backend process to complete. i.e 
the frontend process should be independent of the backend ..

if this wont work then please propose a solution so that i can get rid of this issue.

Thanks
Krishna


Followup   December 17, 2007 - 10am Central time zone:

if you want some stored procedure to run in the background, you would use dbms_job or dbms_scheduler.

If you say you have a SCRIPT that runs in the OS for hours, I would not suggest or even consider running it from a stored procedure - in fact running any script is sort of shaky since you cannot really "professionally interact with the script", it is not like an API (application program interface) subroutine call or anything. If you have a script to run for hours, you'll want to find some other way to do it - not from the database.
4 stars use of DBMS_job and dbms_scheduler   December 17, 2007 - 10pm Central time zone
Reviewer: A reader 
Hi Tom,

please explain in brief how can i user dbms_job to run the stored procedure when a row is inserted 
into the table.

my requirement is like we are inserting a row through frontend using VB.net.
now after a row is inserted the procedure has to run and perform the activity .so how can DBMS_JOB 
or DBMS_SCHEDULER would be useful.

thanks
Krishna


Followup   December 18, 2007 - 1pm Central time zone:

1) this is as brief as I can be
create trigger t after insert on t
declare
  l_job number;
begin
  dbms_job.submit( l_job, 'proc;' );
end;
/




5 stars Just what i was looking for   January 8, 2008 - 4pm Central time zone
Reviewer: Dave 
This thread just helped me a ton.

thanks Tom


5 stars Setting sqlplus environment through plsql   February 11, 2008 - 12am Central time zone
Reviewer: Sharon from UAE
Hello Tom,
I have been reading your threads and find them very useful and I get lots of relevant information 
from them. 
I have a question: 
I want to use command SET SQLPROMPT <username> when ever a user is logged in. For e.g.: If SCOTT is 
login to sql plus I want the SQL > to be displayed as 'SCOTT >'. I plan to fire this command in a 
LOGON Trigger. Is there any work around for this? 
I am using Oracle 10g, on windows 2k.
Please help.
Thanks.


Followup   February 11, 2008 - 10pm Central time zone:

think about this please...


sqlprompt - there is some variable in memory somewhere in sqlplus, a program, a program you or I could have written.

You want the database to be able to magically "just write to the client memory, execute some code on the client, silently, magically"

that is called a virus.


You would use a login.sql or glogin.sql file on a shared install - that is a script SQLPLUS runs upon startup.

Would you not be very upset if the database could actually reach out and modify memory arbitrarily in your own developed applications?
3 stars To Sharon from UAE - Setting sqlplus environment through plsql   February 11, 2008 - 11am Central time zone
Reviewer: A reader from London
Hi sharon,

Your question has nothing to do with original post... However.. please check following link :
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:446220075876

Alternatively, user following 
http://asktom.oracle.com/pls/ask/search?p_string=login.sql


3 stars Thanks Tom   February 13, 2008 - 1am Central time zone
Reviewer: Sharon from UAE
Hi,
As you said writing such a script in java was not good, I understand that, and I agree to it. 
As writing script in glogin/login, I had given it a try. In 8i for a reconnect from the same 
sqlplus screen it was not giving the required result, for 10g I got my desired result.
Thanks for your time and help.


4 stars Really Useful Trick !!   March 10, 2008 - 7am Central time zone
Reviewer: Jekyl from INDIA
Excellent Article Tom.

Everything worked firne with me excep the final result, I got this error :-

SQL> set serveroutput on size 1000000;
SQL> exec dbms_java.set_output(1000000);

PL/SQL procedure successfully completed.

SQL> exec rc('/usr/bin/ps -ef');
java.lang.ArrayIndexOutOfBoundsException
at Util.RunThis(Util.java:14)

PL/SQL procedure successfully completed.

What may be the reason ?


Followup   March 10, 2008 - 11am Central time zone:

ctl-f for the word ArrayIndexOutOfBoundsException on this page and see what you see...
4 stars about $path issue - historics ?   April 10, 2008 - 4pm Central time zone
Reviewer: Jens Ludwig from Germany
Good evening,

just a historic question for trying to understand such a path issue i just encountered.

running the same stored procedure on a 9.2 (not set up by me) and a 10g2 (set up by me)it seems to 
behave different regarding unsetting $PATH in the shell.

9.2 doesnt seem to unset the $PATH but i´m not sure if this is due to slightly differen enviroment 
setups or if that unset was introduced with oracle 10.


Followup   April 10, 2008 - 8pm Central time zone:

I don't know what you are referring to here.
5 stars can JAVA stored procedure run commands on client ?   April 11, 2008 - 3pm Central time zone
Reviewer: A reader 
Hi Tom,
Above examples show how to run host commands from database using JAVA stored procedure. The host 
commands run on the server hosting the database. Is it possible to use same approach to run client 
commands ?
Assuming "oscmd" is a java stored program in database residing on server X. If i call "oscmd" 
remotely from a client Y using TNS connection then commands will run on server X. Is there a way to 
run host commands on client Y from java program in database on server X ?  If it is not possible 
with this approach is there any other way ?

thanks


Followup   April 11, 2008 - 4pm Central time zone:

that would be very virus like wouldn't it.

Think about this - you really want a program running on machine X to be able to execute arbitrary code "as some user" (heck, what user?) on some other machine?

No, it will not happen, unless that client machine itself that you want to execute code on HAS A SERVER of some sort, providing a published service that other machines can connect to and run stuff with.
3 stars Unix script not executed   April 24, 2008 - 6am Central time zone
Reviewer: Vikram Rathore from India, Pune
Tom,

I have implemented the code as below:-
begin
      dbms_java.grant_permission
      ('ASR_OWNER',
       'java.io.FilePermission',
       '/d2/users/rathorv2/*',
       'execute');      
      dbms_java.grant_permission
      ('ASR_OWNER',
       'java.io.FilePermission',
       '/u36/app/1SR/v69/*',
       'execute');             
      dbms_java.grant_permission
      ('ASR_OWNER',
       'java.io.FilePermission',
       '/usr/bin/*',
       'execute');
  
      dbms_java.grant_permission
      ('ASR_OWNER',
       'java.lang.RuntimePermission',
       '*',
       'writeFileDescriptor' );
      
      dbms_java.grant_permission
      ( 'ASR_OWNER', 
    'SYS:java.io.FilePermission',
    '<<ALL FILES>>', 
    'execute' );
  end;
  /


create or replace and compile
  java source named "Util"
  as
  import java.io.*;
  import java.lang.*;
  
  public class Util extends Object
  {
  
    public static int RunThis(String args)
    {
    Runtime rt = Runtime.getRuntime();
    int        rc = -1;
  
    try
    {
       System.out.println(args);
       Process p = rt.exec(args);
  
       int bufSize = 4096;
       BufferedInputStream bis =
        new BufferedInputStream(p.getInputStream(), bufSize);
       int len;
       byte buffer[] = new byte[bufSize];
  
       // Echo back what the program spit out
       while ((len = bis.read(buffer, 0, bufSize)) != -1)
          System.out.write(buffer, 0, len);
  
       rc = p.waitFor();
    }
    catch (Exception e)
    {
       e.printStackTrace();
       rc = -1;
    }
    finally
    {
       return rc;
    }
    }
  }
  /

create or replace
function RUN_CMD( p_cmd  in varchar2) return number
as
language java
name 'Util.RunThis(java.lang.String) return integer';


create or replace procedure RC(p_cmd in varchar2)
as
x number;
begin
x := run_cmd(p_cmd);
end;

Till this point it's all exactly the same code as given by you.
Now I have created unix script

t1.sh
#!/bin/sh
/usr/bin/nohup sqlplus asr_owner/XXXXXX @temp.sql > nohup_temp.log &

exit;

temp.sql
d2/users/rathorv2> $cat temp.sql
SET HEAD OFF
SET PAGESIZE 0
SET VERIFY OFF
SET TERMOUT OFF
SET LINE 100
SET WRAP ON
SET FEEDBACK OFF
SET TRIMSPOOL ON

select *
from asr_owner.emp

spool gl_2006_09.csv
/
spool off

exit;

However when I run this it neither generates the log file nor the csv file.
SQL> set serveroutput on size 1000000
SQL> exec dbms_java.set_output(1000000);

PL/SQL procedure successfully completed.

SQL> exec rc('/usr/bin/sh /d2/users/rathorv2/t1.sh');
/usr/bin/sh /d2/users/rathorv2/t1.sh

PL/SQL procedure successfully completed.

d2/users/rathorv2> $ls -altr *.log
ls: *.log not found

d2/users/rathorv2> $ls -altr gl_2006_09.csv
ls: gl_2006_09.csv not found

Can you please help me on this. Am I doing something wrong or am I missing some settings

Followup   April 28, 2008 - 11am Central time zone:

*environment*

what is "sqlplus", think about this.... where is sqlplus... what sqlplus might you be running (or not) if the environment is not set up....

you are running in someone else's environment! not yours.


how about starting with "echo hello > /tmp/something.txt"

just to see it works, then start debugging from there on up.
4 stars Process hangs   May 5, 2008 - 6am Central time zone
Reviewer: Christoph from Graz, Austria
Dear Tom,

above "A Reader" was stating that the run_cmd is hanging in a windows environment when running 
calc.exe. I can understand your doubts about the gui running inside the db service. but when i want 
to run a program without any gui i face the same problems. in my particular case i want to run 
sysinternals pskill tool. when i execute it, it creates a new system process pskill and unless i 
remove this process manually my sql*plus session is blocked. 
Is there anyway to accomplish my needs with the run_cmd approach.

Thanks in advance
Christoph


Followup   May 5, 2008 - 10am Central time zone:

your pskill is probably waiting on some terminal input/output - and there ISN'T any terminal.

This has to do with the way windows works - undoubtedly here - pskill is waiting for you to type something - and you aren't.

By the way, the database runs with a low privileged user, it is doubtful that it'll work - perhaps that is the problem in the first place - pskill is executed, processed your command line arguments and is saying something like "so sorry, we cannot do that, press enter to continue"


I would discourage this approach, it is not likely you want to kill OS processes from a stored procedure executed in the database - I cannot think of anything good coming from this.
3 stars Process hangs   May 5, 2008 - 11am Central time zone
Reviewer: Christoph from Graz, Austria
Dear Tom,

our problem in this case is that our customer demnads the database to be the process monitoring 
system that the application is working transparent over mutliple operating systems. thing is, we 
are using the run_cmd to start and stop and eventually kill a c++ program which is responsible for 
tcp/ip communication with plcs. there are times when we need to get rid of the whole process tree 
(including all threads of the process) if something really bad (on the other side) happens. we know 
that this is not the way to go as it does not solve the problem, but... anyway - do you think we 
have a chance to use the run_cmd in a non blocking way? would it help to write a wrapper? what kind 
of privileges we would need?

thanks in advance
Christoph


Followup   May 5, 2008 - 2pm Central time zone:

sorry, but you won't get there from here - i will reiterate a million times: killing a process from a stored procedure sounds like a horrible idea - you should change that "requirement"

You would best be served by creating a "monitoring bit of software - sort of like Oracle has Enterprise manager - to control your processes"

You will not be very successful on windows unless you install the database to run as "your user" which would be beyond a bad idea.

You need the privileges to kill a process on windows - windows would tell you that.
4 stars executing custom shell script from PL/SQL   May 29, 2008 - 1pm Central time zone
Reviewer: Raj Thangaraj from Raleigh.NC
I am trying to execute custom shell script from PL/SQL.

When I run "exec rc('/tmp/putOraclemessage.sh ./test.msg &');", I see this result "PL/SQL procedure 
successfully completed."

But looks like this is not executed. This script will run a java class.

Please help.


Followup   May 29, 2008 - 1pm Central time zone:

you know, that & is sort of "meaningless"

ctl-f for

"you are running a shell specific command"

on this page to see that discussion.



2 stars executing custom shell script from PL/SQL   June 2, 2008 - 9am Central time zone
Reviewer: Raj Thangaraj from Raleigh, NC USA
I am trying to execute custom shell script from PL/SQL.

These are my permissions. ------------------------------------------------------------------------
begin
       dbms_java.grant_permission
       ('JAVAUSER',
        'SYS:java.io.FilePermission',
        '/bea/gsipjapps/oracleutility/putOraclemessage.sh',
        'execute');
   
       dbms_java.grant_permission
       ('JAVAUSER',
        'SYS:java.lang.RuntimePermission',
        '*',
        'writeFileDescriptor' );
   end;
   /
------------------------------------------------------------------------

------------------------------------------------------------------------
begin
       dbms_java.grant_permission
       ('JAVAUSER',
        'java.io.FilePermission',
        '/bea/gsipjapps/oracleutility/putOraclemessage.sh',
        'execute');
   
       dbms_java.grant_permission
       ('JAVAUSER',
        'java.lang.RuntimeP