This post is also available in:
Ao executar qualquer operação que dependa do Java dentro do Oracle Database, você pode encontrar o seguinte erro:
SQL> select dbms_java.get_jdk_version() from dual;
ERROR at line 1:
ORA-29548: Java system class reported: release of Java system classes in the
database (19.0.0.0.210420 1.8) does not match that of the oracle executable
(19.0.0.0.0 1.8)Esse erro não se limita a dbms_java – ele pode aparecer em qualquer chamada que use a JVM interna da Oracle, incluindo procedimentos armazenados em Java, OJVM, DBMS_SCHEDULER com classes Java e até mesmo exportações do Data Pump em determinados cenários.
Neste artigo, explicarei por que esse erro ocorre, qual é a causa raiz mais comum e como resolvê-lo de forma correta e segura.
Na prática: Na grande maioria dos casos, esse erro aparece após a aplicação de uma atualização de versão (RU) ou atualização de conjunto de patches (PSU) ao Oracle Home. O patch atualiza o executável Oracle, mas as classes Java dentro do dicionário de dados permanecem na versão anterior até que sejam atualizadas manualmente.
Por que ocorre o erro ORA-29548
O Oracle Database tem uma JVM interna (OJVM) que é executada dentro do banco de dados. Essa JVM tem dois componentes que devem permanecer sincronizados:
- Java no Oracle Home – os binários e as classes Java instalados no sistema de arquivos (
$ORACLE_HOME/javavm/) - Java no dicionário de dados – as classes Java carregadas dentro do banco de dados (
SYS.JAVA$CLASS$MD5$TABLE, etc.)
Quando você aplica uma atualização de versão (RU) ao Oracle Home, o componente (1) é atualizado. Mas o componente (2) – dentro do banco de dados – permanece na versão anterior até que você o atualize explicitamente.
O erro ORA-29548 ocorre quando a Oracle detecta essa incompatibilidade de versão entre os dois componentes.
Quando isso acontece?
- Depois de aplicar uma RU/PSU ao Oracle Home sem concluir a pós-correção do Java, você pode usar o Oracle Home.
- Após uma atualização do banco de dados em que a etapa de atualização do OJVM foi ignorada
- Após a reversão de um patch que incluía o componente OJVM, você pode usar o OJVM para fazer a correção.
- Em ambientes RAC em que a correção foi aplicada às residências, mas
datapatchouupdate_javavm_db.sqlnão foram executados em todas as instâncias, você pode ter que fazer a correção em um ambiente RAC.
Diagnóstico
Antes de corrigir, confirme a incompatibilidade de versão.
Verifique a versão do Java no Oracle Home (sistema de arquivos)
$ORACLE_HOME/jdk/bin/java -versionVerificar a versão do Java no banco de dados
-- Connect as SYS
sqlplus / as sysdba
-- Check JAVAVM and CATJAVA components
SELECT comp_name, version, status
FROM dba_registry
WHERE comp_name LIKE '%JAVA%' OR comp_name LIKE '%JAVAVM%';Saída esperada (quando há uma incompatibilidade):
COMP_NAME VERSION STATUS
------------------------------ -------------------- ----------
JServer JAVA Virtual Machine 19.0.0.0.0 VALID
Oracle Java Packages 19.0.0.0.0 VALIDSe o endereço VERSION não corresponder à versão da RU aplicada (por exemplo, deve ser 19.21.0.0.0 após a RU 19.21), o Java está desatualizado.
Verificar se o datapatch já foi executado
$ORACLE_HOME/OPatch/datapatch -verbose <strong>2</strong>><strong>&1</strong> | tail -20Ou via SQL:
SELECT patch_id, action, status, description
FROM dba_registry_sqlpatch
ORDER BY action_time DESC
FETCH FIRST 10 ROWS ONLY;Se o patch do OJVM não aparecer como SUCCESS, ele não foi aplicado ao banco de dados.
Solução 1: executar update_javavm_db.sql (mais comum)
Esse é o método direto e funciona em todas as versões do Oracle.
Etapa 1 – Conecte-se como SYS AS SYSDBA
sqlplus / as sysdbaImportante: o script deve ser executado como
SYS AS SYSDBA. Qualquer outro usuário resultará em erros de permissão.
Etapa 2 – Execute o script de atualização
@?/javavm/install/update_javavm_db.sqlO ? é um atalho do SQL*Plus para $ORACLE_HOME. O caminho completo seria:
@$ORACLE_HOME/javavm/install/update_javavm_db.sqlEtapa 3 – Aguarde a conclusão
Aviso: Esse script pode levar de 5 a 30 minutos ou mais, dependendo do tamanho do banco de dados e do desempenho do armazenamento. Não interrompa a execução.
Durante a execução, o script:
- Atualiza as classes Java no dicionário de dados
- Recompila objetos Java inválidos
- Sincroniza a versão do OJVM com o Oracle Home
Etapa 4 – Validar
-- Should return without error
SELECT dbms_java.get_jdk_version() FROM dual;
-- Check component status
SELECT comp_name, version, status
FROM dba_registry
WHERE comp_name LIKE '%JAVA%';STATUS deve ser VALID e VERSION deve corresponder à RU aplicada.
Solução 2: usar datapatch (Oracle 12c+)
No Oracle 12c e posterior, o datapatch é o método recomendado pela Oracle para aplicar alterações de patch ao dicionário de dados, incluindo o OJVM.
# Run as Oracle Home owner
cd $ORACLE_HOME/OPatch
./datapatch -verbosedatapatch detecta automaticamente quais patches foram aplicados ao Home e quais ainda não foram aplicados ao banco de dados.
Verificar após a execução
SELECT patch_id, action, status, description
FROM dba_registry_sqlpatch
ORDER BY action_time DESC
FETCH FIRST 5 ROWS ONLY;Se o patch do OJVM aparecer com status = SUCCESS, o problema estará resolvido.
Observação: se o site
datapatchfoi executado e o ORA-29548 persistir, o patch do OJVM pode não estar incluído na RU que você aplicou ou houve um erro silencioso. Nesse caso, use a Solução 1 como alternativa.
Considerações sobre o RAC
Em ambientes Oracle RAC, a atualização do Java precisa ser executada em cada instância do cluster.
# Check which instance you're on
sqlplus / as sysdba
SQL> SELECT instance_name FROM v$instance;
# Run the script or datapatch on EACH node
# Node 1
sqlplus / as sysdba
@?/javavm/install/update_javavm_db.sql
# Node 2 (SSH and repeat)
ssh oracle@node2
export ORACLE_SID=DBNAME2
export ORACLE_HOME=/u01/app/oracle/product/19c/dbhome_1
sqlplus / as sysdba
@?/javavm/install/update_javavm_db.sqlRAC com datapatch: A execução do
datapatchem um nó geralmente se propaga para o banco de dados compartilhado. Mas verifique o status em todas as instâncias para ter certeza.
Lista de verificação de diagnóstico rápido
-- 1. Check Java version in the Home
-- (run in shell, not SQL*Plus)
-- $ORACLE_HOME/jdk/bin/java -version
-- 2. Check Java components in the database
SELECT comp_name, version, status
FROM dba_registry
WHERE comp_name LIKE '%JAVA%';
-- 3. Check patches applied to the database
SELECT patch_id, action, status, description
FROM dba_registry_sqlpatch
ORDER BY action_time DESC
FETCH FIRST 10 ROWS ONLY;
-- 4. Test if the error persists
SELECT dbms_java.get_jdk_version() FROM dual;Conclusão
O erro ORA-29548 é causado por uma incompatibilidade de versão entre o Java no Oracle Home e a versão carregada no dicionário de dados. Na grande maioria dos casos, ele aparece após a aplicação de uma atualização de versão que não foi totalmente propagada para o banco de dados.
O diagnóstico correto segue esta ordem:
- Verifique a incompatibilidade – compare a versão do Java na página inicial com a do banco de dados
- Verificar se o datapatch foi executado – verificar
dba_registry_sqlpatch - Aplique a correção –
datapatch(preferencialmente) ouupdate_javavm_db.sql - Validar –
SELECT dbms_java.get_jdk_version() FROM dual - No RAC – verifique se a correção foi aplicada em todas as instâncias
Quando as versões são sincronizadas, o erro desaparece e todas as operações do Java voltam ao normal.
Referências:
