
May 30, 2001 - 3pm Central time zone
Reviewer: Nagarajan from USA
very useful material. Thanks for the same
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.

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.
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

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.

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?
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" :)

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).
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.

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.

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
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
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
"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.
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.
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...
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
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.
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>

March 4, 2002 - 6am Central time zone
Reviewer: A reader from italy
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.
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.
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.
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.
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)
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
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)
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.
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
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.
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?
.......

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.
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/
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.
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.
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?
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.
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???
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.
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.
excellent
April 25, 2003 - 10am Central time zone
Reviewer: A reader
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.

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
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.
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.
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.
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
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!
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?
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.
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"
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.
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.
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...) ???
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."
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.
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.
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...
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?
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"

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?
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.
"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"
"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.
"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
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.
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)
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?
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)
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>
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.
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
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.
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
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
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

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

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!
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

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!

January 9, 2004 - 12pm Central time zone
Reviewer: A reader
The Beauty of Windows shutdown and restart, everything works fine.
:-))))))
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.
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

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.
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"

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.
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.

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'

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.

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.

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

February 19, 2004 - 3pm Central time zone
Reviewer: Ben from Quebec
ok
Thanks for all your help, Tom.
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?
3x for help!!!
March 21, 2004 - 10pm Central time zone
Reviewer: dibo from China
so good.
haho.
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 &
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.
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.
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');
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 }
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.
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.
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.
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.
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;
/
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...
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
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?
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?)
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?
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
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.
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
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.
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);
}
}
/
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.
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.
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.
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.
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.
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)
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.
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.

October 25, 2004 - 11am Central time zone
Reviewer: raman from TN,USA
Thankyou verymuch ...
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.

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?
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!
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.

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

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?
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".

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?

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.

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 ...

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?
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.

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.
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?
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.
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?
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!!!!!)
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)
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.
ok.. thanks for the input
February 14, 2005 - 9am Central time zone
Reviewer: Justin from PA
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"

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)
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)
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
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...
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 whats 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.
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")
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?
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
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.
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?
Permission Error - Ok
April 7, 2005 - 6pm Central time zone
Reviewer: Andy from Mexico
forgets the previous question, already arrange it...
thanks
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.
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.
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.
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....)
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.
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?
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.
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.
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.
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.
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.
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.
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 #.
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
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.
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.
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.
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!
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.
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
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"
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?
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

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
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.
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.
Loved it as always
September 6, 2005 - 5pm Central time zone
Reviewer: Dmitriy N. from CA USA
I found exactly what I needed
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.

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.

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.
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.
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.
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.

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....)

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?

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

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
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
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!
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)
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.
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
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
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.
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;
}
}
}
/
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.

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.

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.

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.
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 :(
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
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?
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.
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
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
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)
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)
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.
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.
Scheiss Gallier
August 23, 2006 - 10am Central time zone
Reviewer: Stefanie
It was the asterix in the second last line ... *aaargh* ... ;o)
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.
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
Thank you
August 30, 2006 - 3am Central time zone
Reviewer: A reader
Thank you very much
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...
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 :)
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;
/
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
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
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.
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)
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.
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
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.
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.
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.
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.
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 ~]$
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.
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
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.
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.
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.
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.
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??
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
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.
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.

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.
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.

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?
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..."
java code
March 4, 2007 - 3pm Central time zone
Reviewer: A reader
The java code is very useful.
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
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.
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.
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!?
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 !
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 !
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.
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
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
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.
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.
"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.
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.
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
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.
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
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.
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
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?
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
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
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.
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...
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.
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.

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 .....

December 11, 2007 - 11am Central time zone
Reviewer: krishna chaitanya from US
thanks tom for the great suggesstion.

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
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.
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.
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;
/
Just what i was looking for
January 8, 2008 - 4pm Central time zone
Reviewer: Dave
This thread just helped me a ton.
thanks Tom
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?
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
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.
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...
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.
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.
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.
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.
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.
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.
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 |