1 package body rmjvm is
2
3 procedure exec (x varchar2) as
4 begin
5 initjvmaux.exec(x);
6 end;
7
8 procedure drp (x varchar2) as
9 begin
10 initjvmaux.drp(x);
11 end;
12
13 procedure run(remove_all boolean) as
14 begin
15 -- DESCRIPTION
16 -- This removes java related objects from the data dictionary.
17 -- If remove_all is true, it removes all java objects and java
18 -- related tables and packages, including user objects.
19 -- If remove all is false, it removes only the java objects, such
20 -- as system classes, that are considered to be a fixed part of a
21 -- given Oracle release. It does not remove user objects.
22 --
23 -- NOTES
24 -- This procedure is destructive. After it runs, System classes
25 -- must be reloaded either by initjvm or in a subsequent
26 -- upgraded/downgrade phase before Java is again usable.
27 --
28 -- This procedure requires a significant amount of rollback
29 -- to execute.
30 --
31
32 dbms_output.enable(10000000); -- biggest size we can get
33
34 initjvmaux.rollbacksetup;
35
36 commit;
37 initjvmaux.rollbackset;
38
39 declare
40 c number;
41 begin
42 select count(*) into c from java$rmjvm$aux;
43 if c = 0 then
44 commit;
45 initjvmaux.rollbackset;
46 if remove_all then
47 exec('insert into java$rmjvm$aux (select obj# from obj$ where ' ||
48 'type#=28 or type#=29 or type#=30 or namespace=32)');
49 else
50 exec('insert into java$rmjvm$aux (select joxftobn from x$joxfc ' ||
51 'where bitand(joxftflags,96)!=0)');
52 commit;
53 initjvmaux.rollbackset;
54 exec('insert into java$rmjvm$aux (select joxftobn from x$joxfr ' ||
55 'where bitand(joxftflags,96)!=0)');
56 commit;
57 initjvmaux.rollbackset;
58 exec('insert into java$rmjvm$aux (select obj# from obj$ ' ||
59 'where namespace=32)');
60 end if;
61 end if;
62 end;
63
64 commit;
65 initjvmaux.rollbackset;
66
67 dbms_output.put_line('drop or disable triggers with java implementations');
68
69 drp('drop trigger JIS$ROLE_TRIGGER$');
70
71 drp('delete from duc$ where owner=''SYS'' and pack=''JIS$INTERCEPTOR$'' ' ||
72 'and proc=''USER_DROPPED''');
73 drp('delete from aurora$startup$classes$ where ' ||
74 'classname=''oracle.aurora.mts.http.admin.RegisterService''');
75 drp('delete from aurora$dyn$reg');
76 drp('alter trigger CDC_ALTER_CTABLE_BEFORE disable');
77 drp('alter trigger CDC_CREATE_CTABLE_BEFORE disable');
78 drp('alter trigger CDC_CREATE_CTABLE_AFTER disable');
79 drp('alter trigger CDC_DROP_CTABLE_BEFORE disable');
80 drp('delete from JAVA$CLASS$MD5$TABLE');
81 commit;
82
83 initjvmaux.rollbackset;
84
85 dbms_output.put_line('drop synonyms with java targets');
86
87 DECLARE
88 cursor C1 is select name from java$rmjvm$aux2;
89
90 DDL_CURSOR integer;
91 syn_name varchar2(30);
92 iterations number;
93 previous_iterations number;
94 loop_count number;
95 my_err number;
96 cmd varchar2(1000);
97 loss_count number := 0;
98 BEGIN
99 previous_iterations := 10000000;
100
101 DDL_CURSOR := dbms_sql.open_cursor;
102
103 loop
104
105 exec('delete from java$rmjvm$aux2');
106 if remove_all then
107 exec('insert into java$rmjvm$aux2 (select unique o1.name from ' ||
108 'obj$ o1,obj$ o2 where o1.type#=5 and o1.owner#=1 and o1.name=o2.name and o2.type#=29)');
109 else
110 exec('insert into java$rmjvm$aux2 (select unique o1.name ' ||
111 'from obj$ o1,obj$ o2, java$rmjvm$aux j ' ||
112 'where o1.type#=5 and o1.owner#=1 and o1.name=o2.name and o2.obj#=j.obj#)');
113 end if;
114
115 -- To make sure we eventually stop, pick a max number of iterations
116 select count(*) into iterations from java$rmjvm$aux2;
117
118 exit when iterations=0 or iterations >= previous_iterations;
119 previous_iterations := iterations;
120 loop_count := 0;
121
122 OPEN C1;
123
124 LOOP
125
126 BEGIN
127 FETCH C1 INTO syn_name;
128 EXIT WHEN C1%NOTFOUND OR loop_count > iterations;
129 EXCEPTION
130 WHEN OTHERS THEN
131 my_err := SQLCODE;
132 IF my_err = -1555 THEN -- snapshot too old, re-execute fetch query
133 exit;
134 ELSE
135 RAISE;
136 END IF;
137 END;
138
139 BEGIN
140 -- Issue the Alter Statement (Parse implicitly executes DDLs)
141 cmd := 'DROP PUBLIC SYNONYM '||
142 sys.dbms_assert.enquote_name(syn_name, false);
143 dbms_sql.parse(DDL_CURSOR, cmd, dbms_sql.native);
144
145 EXCEPTION
146 WHEN OTHERS THEN
147 my_err := SQLCODE;
148 dbms_output.put_line('### Failure ('||my_err||') executing '||cmd);
149 loss_count := loss_count+1;
150 if loss_count > 100 then raise; end if;
151 END;
152
153 <<continue>>
154 loop_count := loop_count + 1;
155
156 END LOOP;
157 CLOSE C1;
158
159 end loop;
160 dbms_sql.close_cursor(DDL_CURSOR);
161
162 END;
163 commit;
164
165 dbms_output.put_line('flush shared_pool');
166 execute immediate 'alter system flush shared_pool';
167 execute immediate 'alter system flush shared_pool';
168 execute immediate 'alter system flush shared_pool';
169
170 declare
171 total_to_delete number;
172 deletions_per_iteration number := 1000;
173 begin
174
175 initjvmaux.rollbackset;
176
177 dbms_output.put_line('delete from dependency$');
178
179 if remove_all then
180 select count(*) into total_to_delete from dependency$
181 where p_obj# in (select obj# from java$rmjvm$aux);
182 else
183 select count(*) into total_to_delete from dependency$
184 where p_obj# in (select obj# from obj$ where (type#=29 or type#=56));
185 end if;
186 commit;
187
188 loop
189 dbms_output.put_line(total_to_delete ||' remaining at ' || to_char(sysdate,'mm-dd hh:mi:ss'));
190 initjvmaux.rollbackset;
191 if remove_all then
192 delete from dependency$ where p_obj# in
193 (select obj# from java$rmjvm$aux)
194 and rownum <= deletions_per_iteration;
195 else
196 delete from dependency$ where p_obj# in
197 (select obj# from obj$ where (type#=29 or type#=56))
198 and rownum <= deletions_per_iteration;
199 end if;
200 commit;
201 exit when total_to_delete <= deletions_per_iteration;
202 total_to_delete := total_to_delete - deletions_per_iteration;
203 end loop;
204
205 initjvmaux.rollbackset;
206
207 dbms_output.put_line('delete from error$');
208
209 if remove_all then
210 select count(*) into total_to_delete from error$
211 where obj# in (select obj# from java$rmjvm$aux);
212 else
213 select count(*) into total_to_delete from error$
214 where obj# in (select obj# from obj$
215 where type#=28 or type#=29 or type#=30 or type#=56);
216 end if;
217 commit;
218 loop
219 dbms_output.put_line(total_to_delete ||' remaining at ' || to_char(sysdate,'mm-dd hh:mi:ss'));
220 initjvmaux.rollbackset;
221 if remove_all then
222 delete from error$ where obj# in
223 (select obj# from java$rmjvm$aux)
224 and rownum <= deletions_per_iteration;
225 else
226 delete from error$ where obj# in
227 (select obj# from obj$ where type#=28 or type#=29 or type#=30 or type#=56)
228 and rownum <= deletions_per_iteration;
229 end if;
230 commit;
231 exit when total_to_delete <= deletions_per_iteration;
232 total_to_delete := total_to_delete - deletions_per_iteration;
233 end loop;
234
235 initjvmaux.rollbackset;
236
237 dbms_output.put_line('delete from objauth$');
238
239 select count(*) into total_to_delete from objauth$
240 where obj# in (select obj# from java$rmjvm$aux);
241 commit;
242 loop
243 dbms_output.put_line(total_to_delete ||' remaining at ' || to_char(sysdate,'mm-dd hh:mi:ss'));
244 initjvmaux.rollbackset;
245 delete from objauth$ where obj# in (select obj# from java$rmjvm$aux)
246 and rownum <= deletions_per_iteration;
247 commit;
248 exit when total_to_delete <= deletions_per_iteration;
249 total_to_delete := total_to_delete - deletions_per_iteration;
250 end loop;
251
252 initjvmaux.rollbackset;
253
254 dbms_output.put_line('delete from javaobj$');
255
256 select count(*) into total_to_delete from javaobj$
257 where obj# in (select obj# from java$rmjvm$aux);
258 commit;
259 loop
260 dbms_output.put_line(total_to_delete ||' remaining at ' || to_char(sysdate,'mm-dd hh:mi:ss'));
261 initjvmaux.rollbackset;
262 delete from javaobj$ where obj# in (select obj# from java$rmjvm$aux)
263 and rownum <= deletions_per_iteration;
264 commit;
265 exit when total_to_delete <= deletions_per_iteration;
266 total_to_delete := total_to_delete - deletions_per_iteration;
267 end loop;
268
269 initjvmaux.rollbackset;
270
271 dbms_output.put_line('delete from access$');
272
273 select count(*) into total_to_delete from access$
274 where d_obj# in (select obj# from java$rmjvm$aux);
275 commit;
276 loop
277 dbms_output.put_line(total_to_delete ||' remaining at ' || to_char(sysdate,'mm-dd hh:mi:ss'));
278 initjvmaux.rollbackset;
279 delete from access$ where d_obj# in (select obj# from java$rmjvm$aux)
280 and rownum <= deletions_per_iteration;
281 commit;
282 exit when total_to_delete <= deletions_per_iteration;
283 total_to_delete := total_to_delete - deletions_per_iteration;
284 end loop;
285
286 if remove_all then
287 initjvmaux.rollbackset;
288
289 dbms_output.put_line('delete from javasnm$');
290 delete from javasnm$;
291 commit;
292 end if;
293
294 initjvmaux.rollbackset;
295
296 dbms_output.put_line('delete from idl_ub1$');
297
298 select count(*) into total_to_delete
299 from idl_ub1$ where obj# in (select obj# from java$rmjvm$aux);
300 commit;
301 loop
302 dbms_output.put_line(total_to_delete ||' remaining at ' || to_char(sysdate,'mm-dd hh:mi:ss'));
303 initjvmaux.rollbackset;
304 delete from idl_ub1$ where obj# in (select obj# from java$rmjvm$aux)
305 and rownum <= deletions_per_iteration;
306 commit;
307 exit when total_to_delete <= deletions_per_iteration;
308 total_to_delete := total_to_delete - deletions_per_iteration;
309 end loop;
310
311 dbms_output.put_line('delete from idl_ub2$');
312
313 execute immediate
314 'select count(*) from idl_ub2$ ' ||
315 'where obj# in (select obj# from java$rmjvm$aux)' into total_to_delete;
316 commit;
317 loop
318 dbms_output.put_line(total_to_delete ||' remaining at ' || to_char(sysdate,'mm-dd hh:mi:ss'));
319 initjvmaux.rollbackset;
320 execute immediate
321 'delete from idl_ub2$ where obj# in (select obj# from java$rmjvm$aux) ' ||
322 'and rownum <= :deletions_per_iteration' using deletions_per_iteration;
323 commit;
324 exit when total_to_delete <= deletions_per_iteration;
325 total_to_delete := total_to_delete - deletions_per_iteration;
326 end loop;
327
328 dbms_output.put_line('delete from idl_char$');
329
330 select count(*) into total_to_delete
331 from idl_char$ where obj# in (select obj# from java$rmjvm$aux);
332 commit;
333 loop
334 dbms_output.put_line(total_to_delete ||' remaining at ' || to_char(sysdate,'mm-dd hh:mi:ss'));
335 initjvmaux.rollbackset;
336 delete from idl_char$ where obj# in (select obj# from java$rmjvm$aux)
337 and rownum <= deletions_per_iteration;
338 commit;
339 exit when total_to_delete <= deletions_per_iteration;
340 total_to_delete := total_to_delete - deletions_per_iteration;
341 end loop;
342
343 dbms_output.put_line('delete from idl_sb4$');
344
345 execute immediate
346 'select count(*) from idl_sb4$ ' ||
347 'where obj# in (select obj# from java$rmjvm$aux)' into total_to_delete;
348 commit;
349 loop
350 dbms_output.put_line(total_to_delete ||' remaining at ' || to_char(sysdate,'mm-dd hh:mi:ss'));
351 initjvmaux.rollbackset;
352 execute immediate
353 'delete from idl_sb4$ where obj# in (select obj# from java$rmjvm$aux) ' ||
354 'and rownum <= :deletions_per_iteration' using deletions_per_iteration;
355 commit;
356 exit when total_to_delete <= deletions_per_iteration;
357 total_to_delete := total_to_delete - deletions_per_iteration;
358 end loop;
359
360 dbms_output.put_line('delete from obj$');
361 --
362 -- only delete from obj$ if all the java information was deleted
363 -- from the other tables correctly. Once we run this delete
364 -- there is no going back to remove the information from
365 -- syn$, objauth$, javaobj$, access$ and dependency$ using this script.
366 --
367 DECLARE
368 c1 number;
369 c2 number;
370 c3 number;
371 c4 number;
372 c5 number;
373 c6 number;
374 BEGIN
375 if remove_all then
376 select count(*) into c1 from syn$ where obj# in
377 (select o1.obj# from obj$ o1,obj$ o2
378 where o1.name=o2.name and
379 o1.type#=5 and o1.owner#=1 and o2.type#=29);
380 select count(*) into c2 from dependency$ where p_obj# in
381 (select obj# from java$rmjvm$aux);
382 select count(*) into c4 from javasnm$;
383 else
384 select count(*) into c1 from syn$ where obj# in
385 (select o1.obj# from obj$ o1,obj$ o2,java$rmjvm$aux j
386 where o1.name=o2.name and o1.type#=5 and o1.owner#=1
387 and o2.obj#=j.obj#);
388 select count(*) into c2 from dependency$ where p_obj# in
389 (select obj# from obj$ where
390 type#=28 or type#=29 or type#=30 or type#=56);
391 c4 := 0;
392 end if;
393
394 select count(*) into c3 from objauth$ where obj# in
395 (select obj# from java$rmjvm$aux);
396 select count(*) into c6 from javaobj$ where obj# in
397 (select obj# from java$rmjvm$aux);
398 select count(*) into c5 from access$ where d_obj# in
399 (select obj# from java$rmjvm$aux);
400
401 update java$jvm$status set rmjvmtime = (select startup_time from v$instance);
402
403 IF c1 = 0 AND c2 = 0 AND c3 = 0 AND c4 = 0 AND c5 = 0 and c6 = 0 THEN
404 select count(*) into total_to_delete
405 from obj$ where obj# in (select obj# from java$rmjvm$aux);
406 commit;
407 loop
408 initjvmaux.rollbackset;
409 delete from obj$ where obj# in (select obj# from java$rmjvm$aux)
410 and rownum <= deletions_per_iteration;
411 commit;
412 exit when total_to_delete <= deletions_per_iteration;
413 total_to_delete := total_to_delete - deletions_per_iteration;
414 end loop;
415
416 initjvmaux.rollbackset;
417 if not remove_all then
418 update obj$ set status=5 where type#=28 or type#=29;
419 end if;
420
421 commit;
422 initjvmaux.rollbackset;
423 delete from java$rmjvm$aux;
424
425 commit;
426 initjvmaux.rollbackset;
427
428 insert into java$rmjvm$aux
429 (select obj# from obj$ where type#=10 and owner#=1);
430 delete from java$rmjvm$aux
431 where obj# in (select p_obj# from dependency$);
432 delete from obj$ where obj# in (select obj# from java$rmjvm$aux);
433 commit;
434 delete from java$rmjvm$aux;
435 commit;
436
437 dbms_output.put_line('All java objects removed');
438 ELSE
439 dbms_output.put_line('c1: '||c1||' c2: '||c2||' c3: '||c3||
440 ' c4: '||c4||' c5: '||c5||' c6: '||c6);
441 dbms_output.put_line('Java objects not completely removed. ' ||
442 'Rerun rmjvm.run');
443 END IF;
444 END;
445
446 end;
447
448 commit;
449
450 initjvmaux.rollbackcleanup;
451
452 dbms_output.put_line('flush shared_pool');
453 execute immediate 'alter system flush shared_pool';
454 execute immediate 'alter system flush shared_pool';
455 execute immediate 'alter system flush shared_pool';
456 end;
457
458 function hextochar(x varchar2) return varchar2 as
459 y varchar2(200) := '';
460 d number;
461 begin
462 for i in 1..length(x)/2 loop
463 d := to_number(substr(x,i*2-1,2),'XX');
464 if d = 0 then return y;end if;
465 y := y || chr(d);
466 end loop;
467 return y;
468 end;
469
470 procedure check_for_rmjvm as
471 foo exception;
472 pragma exception_init(foo,-28);
473 ct number;
474 begin
475 -- check whether registry says startup is pending
476 if initjvmaux.startup_pending_p then raise foo; end if;
477 -- check whether there are any KGL handles for non fixed objects which
478 -- do not appear in obj$. This can indicate that rmjvm has run in the
479 -- current instance
480 -- Ignore SYS temp tables created during optimizer statstics
481 -- collection.
482 select count(*) into ct from x$kglob,obj$ where
483 kglnacon=sys_context('USERENV', 'CON_NAME') and
484 kglnaobj=name(+) and name is null and kglobtyp in (28, 29, 30, 56);
485 if ct != 0 then raise foo; end if;
486 end;
487
488 procedure strip as
489 begin
490 -- DESCRIPTION
491 -- This strips bytecode optimizations from non-system java classes,
492 -- and sets the status of these classes to invalid (unresolved).
493 -- It is intended for use only prior to downgrade to 8.1.5, and is
494 -- present only because 8.1.5 resolution code incorrectly fails to
495 -- do such stripping, allowing 8.1.6 optimization codes that cannot
496 -- be correctly interpreted by 8.1.5 to remain in place.
497 --
498
499 dbms_output.enable(10000000); -- biggest size we can get
500 initjvmaux.rollbacksetup;
501 commit;
502 initjvmaux.rollbackset;
503
504 delete from java$rmjvm$aux;
505
506 exec('insert into java$rmjvm$aux (select joxftobn from x$joxfc ' ||
507 'where bitand(joxftflags,96)=0)');
508
509 commit;
510 initjvmaux.rollbackset;
511
512 exec('create or replace java source named java$rmjvm$src as import java.lang.Object;');
513
514 commit;
515 initjvmaux.rollbackset;
516
517 dbms_output.put_line('strip 8.1.6 bytecode optimizations');
518
519 DECLARE
520 done boolean;
521 already_done number := 0;
522 cursor C1(above number) is select
523 'ALTER JAVA CLASS "' || u.name || '"."' || o.name || '" RESOLVE',
524 o.obj# from
525 obj$ o, user$ u, java$rmjvm$aux j where
526 o.obj#=j.obj# and u.user# = o.owner# and j.obj# > above
527 order by j.obj#;
528
529 DDL_CURSOR integer;
530 ddl_statement varchar2(200);
531 my_err number;
532 BEGIN
533
534 DDL_CURSOR := dbms_sql.open_cursor;
535
536 loop
537 done := true;
538 OPEN C1(already_done);
539
540 LOOP
541
542 BEGIN
543 FETCH C1 INTO ddl_statement, already_done;
544 EXIT WHEN C1%NOTFOUND;
545 EXCEPTION
546 WHEN OTHERS THEN
547 my_err := SQLCODE;
548 IF my_err = -1555 THEN -- snapshot too old, re-execute fetch query
549 -- CLOSE C1;
550 done := false;
551 exit;
552 ELSE
553 RAISE;
554 END IF;
555 END;
556
557 BEGIN
558 -- Issue the Alter Statement (Parse implicitly executes DDLs)
559 dbms_sql.parse(DDL_CURSOR, sys.dbms_assert.noop(ddl_statement),
560 dbms_sql.native);
561 EXCEPTION
562 WHEN OTHERS THEN
563 null; -- ignore, and proceed.
564 END;
565
566 END LOOP;
567 CLOSE C1;
568 exit when done;
569
570 end loop;
571 dbms_sql.close_cursor(DDL_CURSOR);
572
573 END;
574 commit;
575
576 initjvmaux.rollbackset;
577
578 exec('drop java source java$rmjvm$src');
579 delete from java$rmjvm$aux;
580
581 commit;
582
583 initjvmaux.rollbackcleanup;
584
585 end;
586
587 end;