1 package body initjvmaux is
2
3 deallocate_rollback_name varchar2(30);
4 sec_rollback_segment_name varchar2(32);
5
6 current_step varchar2(40);
7 standalone_action boolean := false;
8 do_debug_output boolean := false;
9
10 alt_tablespace_limit number := 0;
11
12 procedure require_sys as
13 begin
14 if login_user != 'SYS' then
15 declare
16 foo exception;
17 pragma exception_init(foo,-1031);
18 begin
19 raise foo;
20 end;
21 end if;
22 end;
23
24 procedure exec (x varchar2) as
25 begin
26 dbms_output.put_line(substr(x, 1, 250));
27 require_sys;
28 execute immediate x;
29 end;
30
31 procedure drp (x varchar2) as
32 begin
33 exec(x);
34 exception
35 when others then
36 if sqlcode not in (-4080, -1418, -1919, -942, -1432, -4043, -1918, -2289,
37 -6550, -1598, -1534, -1434) then raise; end if;
38 end;
39
40 procedure rollbacksetup as
41 x number;
42 rollback_segment_name varchar2(30);
43 BEGIN
44 deallocate_rollback_name := null;
45 sec_rollback_segment_name := null;
46
47 -- no rollback actions when undo_management is AUTO
48 begin
49 select num into x from v$parameter
50 where name='undo_management' and value='AUTO';
51 return;
52 exception when no_data_found then null;
53 end;
54
55 -- or in pdbs
56 declare
57 pdbname varchar2(128) := sys_context('USERENV', 'CON_NAME');
58 begin
59 if pdbname is not null and pdbname != 'CDB$ROOT' then return; end if;
60 end;
61
62 begin
63 select segment_name into rollback_segment_name from dba_rollback_segs
64 where tablespace_name='SYSTEM' and next_extent*max_extents>100000000 and
65 status='ONLINE' and initial_extent>1000000 and rownum < 2;
66 debug_output('found good enough rollback segment ' ||
67 rollback_segment_name);
68 exception when no_data_found then
69 debug_output('didnt find good enough rollback segment');
70 x := 1;
71 rollback_segment_name := 'MONSTER';
72 loop
73 begin
74 select segment_name into deallocate_rollback_name
75 from dba_rollback_segs where segment_name = rollback_segment_name;
76 debug_output('skipped rollback segment ' || rollback_segment_name);
77 exception when no_data_found then
78 deallocate_rollback_name := rollback_segment_name;
79 sec_rollback_segment_name :=
80 sys.dbms_assert.simple_sql_name(rollback_segment_name);
81 begin
82 exec('create rollback segment ' || sec_rollback_segment_name ||
83 ' storage (initial 2 m next 2 m maxextents unlimited)');
84 exec('alter rollback segment ' ||
85 sec_rollback_segment_name || ' online');
86 debug_output('created rollback segment ' || rollback_segment_name);
87 exception when others then
88 if sqlcode not in (-65091) then raise; end if;
89 sec_rollback_segment_name := null;
90 deallocate_rollback_name := null;
91 return;
92 end;
93 exit;
94 end;
95 rollback_segment_name := 'MONSTER' || x;
96 x := x + 1;
97 end loop;
98 end;
99
100 sec_rollback_segment_name :=
101 sys.dbms_assert.simple_sql_name(rollback_segment_name);
102 END;
103
104 procedure rollbackset as
105 begin
106 if sec_rollback_segment_name is not null then
107 execute immediate 'set transaction use rollback segment ' ||
108 sec_rollback_segment_name;
109 end if;
110 end;
111
112 procedure rollbackcleanup as
113 counter number := 0;
114 begin
115 if deallocate_rollback_name is not null then
116 loop
117 declare
118 sec_name varchar2(32); -- 30+2
119 begin
120 sec_name := sys.dbms_assert.simple_sql_name(deallocate_rollback_name);
121 drp('alter rollback segment ' || sec_name || ' offline');
122 begin
123 drp('drop rollback segment ' || sec_name);
124 exit;
125 exception when others then
126 if sqlcode not in (-1545) then raise; end if;
127 end;
128 counter := counter + 1;
129 dbms_output.put_line('retrying because of ORA-01545');
130 dbms_lock.sleep(2);
131 exit when counter > 150;
132 exception when others then
133 if sqlcode in (-20000) then
134 dbms_output.disable;
135 dbms_output.enable;
136 else
137 raise;
138 end if;
139 end;
140 end loop;
141 end if;
142 end;
143
144 procedure setloading as
145 begin
146 dbms_registry.loading('JAVAVM',
147 'JServer JAVA Virtual Machine',
148 'initjvmaux.validate_javavm');
149 end;
150
151 procedure setloaded as
152 begin
153 dbms_registry.loaded('JAVAVM');
154 validate_javavm;
155 end;
156
157 procedure validate_javavm as
158 begin
159 execute immediate
160 'declare junk varchar2(10) := dbms_java.longname(''foo''); begin null; end;';
161 dbms_registry.valid('JAVAVM');
162 exception when others then
163 dbms_registry.invalid('JAVAVM');
164 end;
165
166 function registrystatus return varchar2 as
167 result varchar2(30) := dbms_registry.status('JAVAVM');
168 begin
169 if result = 'VALID' then result := 'LOADED'; end if;
170 return result;
171 end;
172
173 function startup_pending_p return boolean as
174 result boolean := false;
175 rmjvmtime date;
176 begin
177 begin
178 select rmjvmtime into rmjvmtime from java$jvm$status
179 where rmjvmtime = (select startup_time from v$instance);
180 result := true;
181 exception when no_data_found then null;
182 end;
183 return result;
184 end;
185
186 procedure check_sizes_for_cjs(required_shared_pool number := 24000000,
187 required_shared_pool_if_10049
188 number := 70000000,
189 required_java_pool number := 12000000,
190 required_tablespace number := 70000000) as
191 foo exception;
192 pragma exception_init(foo, -29554);
193 free number;
194 shared_pool_limit number := required_shared_pool;
195 tablespace_limit number := required_tablespace;
196 step_name varchar2(40) := 'CHECK_SIZES';
197 sga_target_value number := 0;
198 begin
199 if alt_tablespace_limit != 0 then
200 tablespace_limit := alt_tablespace_limit;
201 end if;
202 if startstep(step_name) then
203 exec('alter system flush shared_pool');
204 begin
205 select 0 into free from v$parameter2
206 where name='event' and value like '%10049 trace%'
207 and not exists (select * from v$parameter2
208 where name='event'
209 and value='10049 trace name all off');
210 shared_pool_limit := required_shared_pool_if_10049;
211 exception when no_data_found then null;
212 end;
213 begin
214 select current_size into sga_target_value
215 from v$memory_dynamic_components
216 where component='SGA Target';
217 exception when no_data_found then null;
218 end;
219 if sga_target_value = 0 then
220 begin
221 select sum(bytes) into free from v$sgastat where pool='java pool';
222 exception when no_data_found then free := 0;
223 end;
224 if free < required_java_pool then
225 abort_message('Aborting because available java pool, ' || free ||
226 ', is less than ' || required_java_pool || ' .');
227 raise foo;
228 end if;
229 declare
230 msg1 varchar2(200);
231 begin
232 select bytes into free from v$sgastat
233 where name='free memory' and
234 pool='shared pool' and
235 bytes < shared_pool_limit;
236 msg1 := 'Aborting because available shared pool, ' || free ||
237 ', is less than ' || shared_pool_limit || ' .';
238 if shared_pool_limit = required_shared_pool_if_10049 then
239 abort_message(msg1,
240 'Required value is large because event 10049 is set.');
241 else
242 abort_message(msg1);
243 end if;
244 raise foo;
245 exception when no_data_found then null;
246 end;
247 else
248 if sga_target_value <
249 required_java_pool + shared_pool_limit + 1000000 then
250 abort_message('Aborting because sga_target value, ' ||
251 sga_target_value ||
252 ', is not sufficiently larger than the sum of '||
253 ' the required java_pool size, ' || required_java_pool ||
254 ', and the required shared_pool size, ' ||
255 shared_pool_limit || ' .');
256 raise foo;
257 end if;
258 end if;
259 if sys_context('USERENV', 'CON_ID') < 2 then
260 select sum(length) into free from idl_ub1$,x$joxft
261 where obj#=joxftobn and bitand(joxftflags,96)!=0;
262 tablespace_limit := tablespace_limit - free;
263 select sum(length) into free from idl_ub1$ u,obj$ o
264 where o.obj#=u.obj# and o.type#=56 and name like 'Locale%';
265 tablespace_limit := tablespace_limit - free;
266 select sum(bytes) into free from dba_free_space
267 where tablespace_name='SYSTEM';
268 if free < tablespace_limit then
269 abort_message('Aborting because available SYSTEM tablespace, ' ||
270 free ||
271 ', is less than ' || tablespace_limit || ' .');
272 raise foo;
273 end if;
274 end if;
275 end if;
276 endstep;
277 delete from java$jvm$steps$done where step = step_name;
278 commit;
279 end;
280
281 procedure create_if_not_present(command varchar2) as
282 begin
283 exec(command);
284 exception when others then
285 if sqlcode not in (-955, -1921) then raise; end if;
286 end;
287
288 procedure alter_if_not_present(command varchar2) as
289 begin
290 exec(command);
291 exception when others then
292 if sqlcode not in (-2260) then raise; end if;
293 end;
294
295 procedure abort_message(msg1 varchar2, msg2 varchar2 default null) as
296 begin
297 dbms_output.put_line('.');
298 dbms_output.put_line('###');
299 dbms_output.put_line('### ' || msg1);
300 if msg2 is not null then dbms_output.put_line('### ' || msg2);end if;
301 dbms_output.put_line('###');
302 dbms_output.put_line('.');
303 end;
304
305 function jvmuscript(patchset varchar2) return varchar2 as
306 result varchar2(30) := 'jvmempty.sql';
307 stat varchar2(30);
308 registry_version varchar2(30);
309 begin
310 begin
311 select status, version into stat, registry_version from dba_registry
312 where comp_id='JAVAVM';
313 if stat = 'UPGRADING' or patchset = 'TRUE' then
314 result := 'jvmu' || substr(translate(registry_version,'x.','x'), 1, 3) || '.sql';
315 end if;
316 exception when no_data_found then null;
317 end;
318 return result;
319 end;
320
321 function jvmversion return varchar2 as
322 begin
323 return dbms_registry.version('JAVAVM');
324 end;
325
326 function current_release_version return varchar2 as
327 v varchar2(20);
328 begin
329 SELECT version INTO v from v$instance;
330 return v;
331 end;
332
333 procedure drop_sys_class(name varchar2) as
334 begin
335 drp('drop java class ' || sys.dbms_assert.enquote_name(name, false));
336 drp('drop public synonym ' || sys.dbms_assert.enquote_name(name, false));
337 end;
338
339 procedure drop_sys_resource(name varchar2) as
340 begin
341 drp('drop java resource ' || sys.dbms_assert.enquote_name(name, false));
342 end;
343
344 function compare_releases(first varchar2, second varchar2) return varchar2 as
345 posx number:=0;
346 indx number;
347 posy number:=0;
348 indy number;
349 xt varchar2(100);
350 yt varchar2(100);
351 res varchar2(30):='SAME';
352 begin
353 if first is null then return 'FIRST IS NULL'; end if;
354 loop
355 indx := instr(first, '.', posx + 1);
356 indy := instr(second, '.', posy + 1);
357 if indx = 0 then indx := 10000; end if;
358 if indy = 0 then indy := 10000; end if;
359 xt := substr(first, posx + 1, indx - posx - 1);
360 yt := substr(second, posx + 1, indy - posy - 1);
361 if xt <> yt then
362 if least(10000, xt, yt) = least(10000, xt) then
363 res := 'FIRST IS OLDER';
364 else
365 res := 'FIRST IS NEWER';
366 end if;
367 exit;
368 end if;
369 if indx = 10000 then
370 if indy < 10000 then res := 'FIRST IS OLDER'; end if;
371 exit;
372 end if;
373 if indy = 10000 then
374 res := 'FIRST IS NEWER';
375 exit;
376 end if;
377 posx := indx;
378 posy := indy;
379 end loop;
380 return res;
381 end;
382
383 -- actions: LOAD initjvm.sql
384 -- UNLOAD rmjvm.sql
385 -- UPGRADE udjvmrm from jvmdbmig
386 -- DOWNGRADE* jvmexxx
387 -- STANDALONE initsec
388
389 -- If input action is compatible with the current action status, as
390 -- given by the values in the single row in table java$jvm$status,
391 -- then change java$jvm$status to reflect that the input action is
392 -- now (or again) in progress. If the input action is incompatible,
393 -- set the punting column in java$jvm$status so that until a subsequent
394 -- endaction or startaction call resets things, startstep will always
395 -- indicate that a given step should be skipped.
396 procedure startaction_outarg(newaction IN OUT varchar2) as
397 lastaction varchar2(40);
398 inprogress varchar2(1);
399 inaction varchar(40) := newaction;
400 begin
401 begin
402 select action,inprogress into lastaction,inprogress from java$jvm$status;
403 exception when no_data_found then
404 lastaction := 'NONE';
405 inprogress := 'N';
406 insert into java$jvm$status values('NONE','N',null,null,'TRUE');
407 end;
408 standalone_action := false;
409 if inprogress = 'Y' then
410 if not (newaction = lastaction or
411 (newaction = 'UNLOAD' and lastaction = 'LOAD') or
412 (substr(newaction,1,13) = 'DOWNGRADE_TO_' and
413 substr(lastaction,1,13) = 'DOWNGRADE_TO_')) then
414 newaction := 'PUNT';
415 end if;
416 elsif newaction = 'LOAD' then
417 if lastaction != 'UNLOAD' and lastaction != 'NONE' then
418 newaction := 'PUNT';
419 end if;
420 elsif newaction = 'UPGRADE' then
421 if (not (lastaction = 'LOAD' or lastaction = 'NONE')) or
422 jvmversion = current_release_version
423 then
424 newaction := 'PUNT';
425 end if;
426 elsif newaction = 'DOWNGRADERELOAD' then
427 if substr(lastaction,1,9) != 'DOWNGRADE' then
428 newaction := 'PUNT';
429 end if;
430 elsif substr(newaction,1,9) = 'DOWNGRADE' then
431 if lastaction != 'LOAD' then
432 newaction := 'PUNT';
433 end if;
434 elsif newaction = 'PATCHSET' then
435 if lastaction != 'LOAD' then
436 newaction := 'PUNT';
437 end if;
438 elsif newaction = 'STANDALONE' then
439 if lastaction != 'LOAD' then
440 newaction := 'PUNT';
441 end if;
442 elsif newaction != 'UNLOAD' then
443 newaction := 'PUNT';
444 end if;
445
446 if newaction = 'PUNT' then
447 debug_output('startaction(' || inaction || ') PUNTED');
448 update java$jvm$status set punting = 'TRUE';
449 elsif newaction = 'STANDALONE' then
450 standalone_action := true;
451 update java$jvm$status set punting = 'FALSE';
452 else
453 debug_output('startaction(' || inaction || ') STARTED');
454 update java$jvm$status set
455 action = newaction,
456 inprogress = 'Y',
457 execid = currentexecid,
458 punting = 'FALSE';
459 end if;
460
461 commit;
462
463 end;
464
465 procedure startaction(newaction IN varchar2) as
466 newaction_outarg varchar2(40) := newaction;
467 begin
468 startaction_outarg(newaction_outarg);
469 end;
470
471 procedure endaction_outarg(action OUT varchar2) as
472 begin
473 if standalone_action then
474 update java$jvm$status set punting = 'FALSE';
475 standalone_action := false;
476 action := 'STANDALONE';
477 else
478 begin
479 select action into action from java$jvm$status where
480 punting = 'FALSE' and
481 execid = currentexecid;
482 delete from java$jvm$steps$done;
483 update java$jvm$status set inprogress = 'N', execid = null;
484 debug_output('endaction(' || action || ') DONE');
485 exception when no_data_found then
486 debug_output('endaction while PUNTING');
487 update java$jvm$status set punting = 'FALSE';
488 action := 'PUNT';
489 end;
490 end if;
491
492 commit;
493
494 end;
495
496 procedure endaction as
497 outarg varchar2(40);
498 begin
499 endaction_outarg(outarg);
500 end;
501
502 procedure endaction_asload as
503 outarg varchar2(40);
504 begin
505 endaction_outarg(outarg);
506 if (outarg != 'PUNT') then
507 update java$jvm$status set action = 'LOAD';
508 commit;
509 end if;
510 end;
511
512 function startstep(newstep varchar2) return boolean as
513 punting varchar2(5);
514 execid varchar2(40);
515 oldstep varchar2(40);
516 try boolean := false;
517 begin
518 current_step := null;
519 begin
520 select execid, punting into execid, punting from java$jvm$status;
521 if punting = 'FALSE' then
522 debug_output('NOT YET PUNTING AT ' || newstep);
523 if standalone_action then
524 try := true;
525 update java$jvm$status set punting = 'TRUE';
526 elsif execid = currentexecid then
527 begin
528 select step into oldstep from java$jvm$steps$done where step = newstep;
529 exception when no_data_found then
530 try := true;
531 current_step := newstep;
532 update java$jvm$status set punting = 'TRUE';
533 end;
534 else
535 debug_output('startstep(' || newstep || ') PUNTED');
536 update java$jvm$status set punting = 'TRUE';
537 end if;
538 end if;
539 exception when no_data_found then
540 insert into java$jvm$status values('NONE','N',null,null,'TRUE');
541 end;
542
543 commit;
544
545 if try then
546 debug_output('TRIED ' || newstep);
547 else
548 debug_output('SKIPPED ' || newstep);
549 end if;
550
551 return try;
552
553 end;
554
555 procedure endstep as
556 begin
557 if current_step is not null then
558 debug_output('COMPLETED ' || current_step);
559 insert into java$jvm$steps$done values(current_step);
560 current_step := null;
561 end if;
562 update java$jvm$status set punting = 'FALSE';
563 commit;
564 end;
565
566 function currentexecid return varchar2 as
567 execid varchar2(40);
568 begin
569 select sid||'-'||serial# into execid from v$session
570 where sid = (select unique(sid) from v$mystat);
571 return execid;
572 end;
573
574 procedure set_debug_output_on as begin do_debug_output := true; end;
575 procedure set_debug_output_off as begin do_debug_output := false; end;
576
577 procedure debug_output(line varchar2) as
578 begin
579 if do_debug_output then dbms_output.put_line(line);end if;
580 end;
581
582 procedure set_alt_tablespace_limit(l number) as
583 begin
584 alt_tablespace_limit := l;
585 end;
586
587 -- drop sros during up/downgrade
588 procedure drop_sros as
589 begin
590 update obj$ set status=5 where obj#=(select obj# from obj$,javasnm$
591 where owner#=0 and type#=29 and short(+)=name and
592 nvl(longdbcs,name)='oracle/aurora/rdbms/Compiler');
593 commit;
594 declare
595 cursor C1 is select
596 u.name, o.name
597 from obj$ o,user$ u where o.type#=56 and u.user#=o.owner#;
598 ddl_statement varchar2(200);
599 uname varchar2(30);
600 oname varchar2(30);
601 iterations number;
602 previous_iterations number;
603 loop_count number;
604 my_err number;
605 begin
606 previous_iterations := 10000000;
607 loop
608 -- To make sure we eventually stop, pick a max number of iterations
609 select count(*) into iterations from obj$ where type#=56;
610 exit when iterations=0 or iterations >= previous_iterations;
611 previous_iterations := iterations;
612 loop_count := 0;
613 open C1;
614 loop
615 begin
616 fetch C1 into uname,oname;
617 -- zsqi LRG 4937433 (Enquote_Name in place of manually added quotes)
618 ddl_statement := 'DROP JAVA DATA ' ||
619 sys.dbms_assert.enquote_name(uname,FALSE) || '.' ||
620 sys.dbms_assert.enquote_name(oname,FALSE);
621 exit when C1%NOTFOUND or loop_count > iterations;
622 exception when others then
623 my_err := sqlcode;
624 if my_err = -1555 then -- snapshot too old, re-execute fetch query
625 exit;
626 else
627 raise;
628 end if;
629 end;
630 initjvmaux.exec(ddl_statement);
631 loop_count := loop_count + 1;
632 end loop;
633 close C1;
634 end loop;
635 end;
636 commit;
637 drp('delete from java$policy$shared$table');
638 update obj$ set status=1 where obj#=(select obj# from obj$,javasnm$
639 where owner#=0 and type#=29 and short(+)=name and
640 nvl(longdbcs,name)='oracle/aurora/rdbms/Compiler');
641 commit;
642 end;
643
644 procedure create_property_defs_table as
645 begin
646 require_sys;
647 exec('create table ' ||
648 'SYS.java$jvm$system$property$defs(user_name varchar2(128), ' ||
649 'property_name varchar2(4000), ' ||
650 'property_value varchar2(4000))');
651 exec('create or replace view java_system_property_settings as ' ||
652 'select * from sys.java$jvm$system$property$defs ' ||
653 'where user_name=SYS_CONTEXT(''userenv'',''SESSION_USER'') ' ||
654 'with check option');
655 exec('grant update,select,delete,insert on ' ||
656 'SYS.java_system_property_settings to public');
657 exec('create or replace public synonym java_system_property_settings for ' ||
658 'SYS.java_system_property_settings');
659 exec('begin dbms_java.reset_property_defs_table_flag; end;');
660 end;
661
662 end;