Thanks to Axel Delin for asking this very reasonable question on the blog. Do you need the Mitigation Patch in CDB$ROOT and all PDBS? Background for this question is that Axel can’t remove JVM but doesn’t use it. A typical case we cover in our slides and presentations as well. And in this case, the Mitigation Patch will become your friend. Please note: If you DON’T have JAVAVM in your database, you won’t need to pay attention and instead could stop reading now.

Photo by Mick Truyts on Unsplash
Mitigation Patch
You can read more about the Mitigation Patch, and its pros and cons here:
In short, you will find the Mitigation Patch in all your environments since 11.2.0.4. Once you execute the dbmsjdev.sql script, you can disable the Java subsystem with a call. Only real downside: Whenever you patch or upgrade, you need to enable it beforehand. Plus, you shouldn’t forget to disable it after upgrade or patching again.
Mitigation Patch and Multitenant?
For non-CDB databases, everything is easy.
@?/rdbms/admin/dbmsjdev.sql
And then you disable JVM with:
exec dbms_java_dev.disable
But how about Multitenant?
At first, you can decide WHERE you’d like to disable the Java subsystem. This is pretty handy as you could disable JVM in PDB1, PDB2 and PDB4 but have it still enabled in PDB3.
But there are a lot of questions coming to my mind right now.
- How do you make the dbms_java_dev.disable call available in all containers?
- When you provision a new PDB, will it have JVM on or off?
- Can you have JVM enabled in a PDB when you disabled it in the CDB$ROOT?
- Can you disable JVM in all containers with one single command?
Maybe I didn’t search clever enough but I couldn’t find answers in MOS or in the documentation to my questions. No idea why I need to raise these questions as our team does not own OJVM … but let’s play a bit with the database and see what happens.
Setup
I will use a 19.10.0 CDB with 3 PDBs:
SQL> show pdbs CON_ID CON_NAME OPEN MODE RESTRICTED ---------- ------------------------------ ---------- ---------- 2 PDB$SEED READ ONLY NO 3 PDB1 READ WRITE NO 4 PDB2 READ WRITE NO 5 PDB3 READ WRITE NO
And in all of them I’ll have the JVM component enabled:
SQL> select CON_ID, COMP_ID, STATUS from CDB_REGISTRY where COMP_ID='JAVAVM' order by CON_ID; CON_ID COMP_ID STATUS ---------- ---------- -------- 1 JAVAVM VALID 2 JAVAVM VALID 3 JAVAVM VALID 4 JAVAVM VALID 5 JAVAVM VALID
One important thing to mention: When I write “Mitigation Patch is activated”, I mean that the dbmsjdev.sql script has been run. Then the functionatily to disable the JAVAMVM is available. When I write “JAVAVM is disabled”, then nobody can use the JAVAVM, and you are safe.
Can you enable the Mitigation Patch in CDB$ROOT only?
In CDB$ROOT only:
@?/rdbms/admin/dbmsjdev.sql exec dbms_java_dev.disable
Unfortunately DBA_REGISTRY does not give any indication of the fact that JAVAVM has been disabled now.
Luckily I had this issue before – and blogged about it a while ago: OJVM and the Mitigation Patch – Things to know in 2020. This is the key:
SQL> select status from dba_triggers where trigger_name='DBMS_JAVA_DEV_TRG'; STATUS -------- DISABLED
What does this mean?
It means, the Mitigation Patch is active, but JAVAVM is still ENABLED.
The three potential results of the query select status from dba_triggers where trigger_name=’DBMS_JAVA_DEV_TRG’; mean:
- Query returns “no rows selected”: You haven’t run dbmsjdev.sql in this container
- Query returns DISABLED: You ran dbmsjdev.sql but the JAVAVM is still ENABLED
- Query returns ENABLED: You ran dbmsjdev.sql and the JAVAVM is DISABLED
Looks weird? Yes, it does … and don’t shoot the messenger as I haven’t implemented it this way.
What you want is the last bullet point: The query returns ENABLED, and nobody can use JAVAVM.
Let me bring this now into a useful query for my Multitenant environments:
column STATUS format A60 SELECT t.con_id, CASE t.status WHEN 'ENABLED' THEN 'Mitigation patch active, JAVAVM is disabled' WHEN 'DISABLED' THEN 'Mitigation patch active, but JAVAVM is still enabled' END AS status from CDB_TRIGGERS t, CDB_REGISTRY r where t.TRIGGER_NAME='DBMS_JAVA_DEV_TRG' AND r.comp_id='JAVAVM' AND t.con_id=r.con_id order by CON_ID; CON_ID STATUS ------ ------------------------------------------------------------ 1 Mitigation patch active, but JAVAVM is still enabled 3 Mitigation patch active, JAVAVM is disabled 2 rows selected.
I have activated the Mitigation Patch in CDB$ROOT (CON_ID=1) and PDB1 (CON_ID=3). In the root container JAVAMVM can still be used. In PDB1 is has been disabled and can’t be used.
You have the choice where you activate the Mitigation Patch – and where you really disable JAVAVM. I’d recommend in case you have the intention to disable JAVAVM to activate the Mitigation Patch in all containers includeing the PDB$SEED – and then disabling JAVAVM at will or in all containers.
Activate the Mitigation Patch in all containers
I create a simple script called miti_activate.sql:
-- Script Name: miti_activate.sql -- @?/rdbms/admin/dbmsjdev.sql
And then I execute it in all containers:
$ORACLE_HOME/perl/bin/perl $ORACLE_HOME/rdbms/admin/catcon.pl -n 1 -l /home/oracle -b miti_active -d /home/oracle miti_activate.sql
Let me check with my above query:
CON_ID STATUS ---------- ------------------------------------------------------------ 1 Mitigation patch active, JAVAVM is enabled 2 Mitigation patch active, JAVAVM is enabled 3 Mitigation patch active, JAVAVM is enabled 4 Mitigation patch active, JAVAVM is enabled 5 Mitigation patch active, JAVAVM is enabled
Be aware: I ran the dbmsjdev.sql again – but JAVAVM was DISABLED in PDB1 (CON_ID=3) before. Now it is ENABLED – ouch! Hence, please double-check.
Let me now DISABLE JAVAVM in all containers. Sounds simple, doesn’t it?
*** At this point I’ve had to adjust my blog post – thanks to YEKI for the hint with PDB$SEED!! ***
I ran into this error:
BEGIN dbms_java_dev.disable; END; * ERROR at line 1: ORA-20032: Disable failed. Parameter _oracle_script found set ORA-06512: at "SYS.DBMS_JAVA_DEV", line 18 ORA-06512: at "SYS.DBMS_JAVA_DEV", line 12 ORA-06512: at "SYS.DBMS_JAVA_DEV", line 34 ORA-06512: at line 1
when I set _ORACLE_SCRIPT=TRUE to alter my PDB$SEED as well.
This means, you can’t use catcon.pl but rather need to connect to all container and disable it manually.
But I learned (thanks Yeki!) that you won’t need to set _ORACLE_SCRIPT to treat PDB$SEED.
SQL> alter session set container=PDB$SEED; Session altered. SQL> shutdown Pluggable Database closed. SQL> startup Pluggable Database opened. SQL> show pdbs CON_ID CON_NAME OPEN MODE RESTRICTED ---------- ------------------------------ ---------- ---------- 2 PDB$SEED READ WRITE NO SQL> start ?/rdbms/admin/dbmsjdev.sql SQL> exec dbms_java_dev.disable; PL/SQL procedure successfully completed. SQL> shutdown Pluggable Database closed. SQL> startup open read only; Pluggable Database opened. SQL> show pdbs CON_ID CON_NAME OPEN MODE RESTRICTED ---------- ------------------------------ ---------- ---------- 2 PDB$SEED READ ONLY NO
And then I check all my PDBs:
CON_ID STATUS ---------- ------------------------------------------------------------ 1 Mitigation patch active, JAVAVM is disabled 2 Mitigation patch active, JAVAVM is disabled 3 Mitigation patch active, JAVAVM is disabled 4 Mitigation patch active, JAVAVM is disabled 5 Mitigation patch active, JAVAVM is disabled
Provisiong a new PDB
Let me now provision a new PDB and see what happens:
SQL> create pluggable database PDB4 admin user adm identified by adm file_name_convert=('pdbseed','pdb4'); Pluggable database created. SQL> alter pluggable database PDB4 open; Pluggable database altered. SQL> start check_mitigation_patch.sql CON_ID STATUS ---------- ------------------------------------------------------------ 1 Mitigation patch active, JAVAVM is disabled 2 Mitigation patch active, JAVAVM is disabled 3 Mitigation patch active, JAVAVM is disabled 4 Mitigation patch active, JAVAVM is disabled 5 Mitigation patch active, JAVAVM is disabled 6 Mitigation patch active, JAVAVM is disabled
Perfect. New PDBs will be provisioned with the Mitigation Patch being active, and JAVAVM being disabled.
Conclusion
When you don’t use JAVAVM and you’d like to disable it, you need two steps. At first, you need to activate the Mitigation Patch. It is included in all bundle patches since 2018 as far as I’m aware. And then you need to DISABLE the JAVAVM with a call to DBMS_JAVA_DEV.
You can do this independently for each container, regardless whether you have disabled JAVAVM in the CDB$ROOT or not.
But there is one single flaw when you do this after provisioning a lot of PDB already:
You can’t use catcon.pl for this task but instead need either to connect to each of the PDBs manually, or write your own script who does that.
The crucial part is having JAVAVM being disabled in PDB$SEED. Once you completed this, all future PDBs you’ll provision have JAVAVM disabled then by default.
Further Links and Information
- Install and remove components in Multitenant always with catcon.pl
- OJVM and the Mitigation Patch – Things to know in 2020
- Be aware when you use _ORACLE_SCRIPT
–Mike
Hello Mike,
am i right, that this article must not interest me when i don’t install JVM in the database?
The article sounds, that the JVM Subsystem is also active when not installed and so i should/could disable it. I’m a little confused.
Thanks Marcus
Hi Marcus,
correct – let me add a “disclaimer” message upfront š
If you don’t have JAVAVM, you don’t have to take care.
Cheers and thanks for the hint,
Mike
Hi Mike,
very valuable info, thank you. I want to disable JVM next time.
One question:
We use Oracle Multimedia (Locator). Oracle Multimedia prequisite the Oracle JVM installed, hence I’m not sure if I disable Oracle JVM will Oracle Multimedia keeps valid and is it supported then?
Thank you Peter
Hi Peter,
I’m not 100% sure – but I guess that especially the Locator will still work.
MOS Note: 1929745.1 (Oracle Recommended Patches — “Oracle JavaVM Component Database PSU and Update” (OJVM PSU and OJVM Update) Patches
https://support.oracle.com/epmos/faces/DocumentDisplay?id=1929745.1
describes the effects of having the mitigation patch active and javavm disabled under:
“Effects of Activating the Mitigation Patch”
I don’t think that Locator calls will fail – but I’m not an expert for these options.
Hope this helps – cheers,
Mike
Hi Mike,
I think you don’t need to set _ORACLE_SCRIPT in order to open the PDB$SEED read write, or you can just set _ORACLE_SCRIPT to false just before calling dbms_java_dev.
Beer’s on me – THANK YOU!
I was in the intention that you need _ORACLE_SCRIPT to open the PDB$SEED read/write – but you are absolutely right.
I change the blog post now!
Thanks!!!
Mike
Welcome š
Your blog is always helpful to me.
Thanks Yeki!
Cheers,
Mike
Hello Mike,
I want to disable run exec dbms_java_dev.enable; in all the pdbs+root, i tried to use catcon.pl, but it fails with
BEGIN dbms_java_dev.disable; END;
*
ERROR at line 1:
ORA-20032: Disable failed. Parameter _oracle_script found set
ORA-06512: at “SYS.DBMS_JAVA_DEV”, line 18
ORA-06512: at “SYS.DBMS_JAVA_DEV”, line 12
ORA-06512: at “SYS.DBMS_JAVA_DEV”, line 34
ORA-06512: at line 1
I have tried with alter session set “_oracle_script”=false, but no good.
Any suggestion on how i can run this on all the pdbs.
(Manually hopping on to all pdbs ain’t an option, as i have many..and want to automate it.)
Regards,
John
Hi John,
as I wrote in my blog post:
“This means, you can’t use catcon.pl but rather need to connect to all container and disable it manually.”
You simply can’t use catcon.pl as it automatically uses _oracle_script – you need to do it as I proposed in my blog post.
Cheers,
Mike