如何将依赖包/Uber Jar加载为单个Java数据库对象
解决Oracle加载Java类时依赖导致大量数据库对象的问题
方案1:拆分依赖与业务类,单独加载共享依赖
不要使用包含所有依赖的Fat Jar,而是将依赖和业务代码分开处理:
- 先加载依赖Jar并标记为共享资源,让多个业务类可以复用,避免重复生成对象:
参数CALL dbms_java.loadjava('-r -v -f -s /home/usr/javastuff/ojdbc.jar');-s表示将Jar作为共享模式加载,依赖类会被全局复用,不会为每个业务类重复创建对象。 - 再加载仅包含自己业务代码的Jar(不含依赖):
业务类会自动引用已加载的共享依赖,大幅减少数据库中生成的对象数量。CALL dbms_java.loadjava('-r -v -f /home/usr/javastuff/Application.jar');
方案2:用PL/SQL包封装Java方法,简化管理
将Java方法发布为PL/SQL函数/过程,再封装到PL/SQL包中,对外只需要维护PL/SQL包,无需直接处理大量Java对象:
- 先加载不含依赖的业务类Jar(确保依赖已提前加载到数据库)。
- 发布Java方法为PL/SQL函数:
CREATE OR REPLACE FUNCTION BLOB_LENGTH(myBlob IN BLOB) RETURN NUMBER AS LANGUAGE JAVA NAME 'Application.BlobLength(oracle.sql.BLOB) return java.lang.Long'; - 封装到PL/SQL包:
后续管理只需维护PL/SQL包,Java对象作为底层实现无需直接操作。CREATE OR REPLACE PACKAGE BLOB_UTILS AS FUNCTION GET_BLOB_LENGTH(myBlob IN BLOB) RETURN NUMBER; END BLOB_UTILS; / CREATE OR REPLACE PACKAGE BODY BLOB_UTILS AS FUNCTION GET_BLOB_LENGTH(myBlob IN BLOB) RETURN NUMBER IS BEGIN RETURN BLOB_LENGTH(myBlob); END; END BLOB_UTILS; /
方案3:精简Jar包,只保留必要类
先排查哪些依赖类是Oracle数据库已内置的(比如java.sql包下的类、部分oracle.sql类通常是数据库自带的),只打包业务类本身:
- 例如你的
Application类仅依赖oracle.sql.BLOB和java.sql.SQLException,这些类Oracle数据库大概率已经提供,无需打包到Jar中。 - 直接加载仅包含
Application.class的精简Jar,生成的数据库对象只会是业务类相关的少数几个,不会引入大量依赖对象。 - 如果调用时出现类找不到的错误,再针对性加载缺失的单个类,而非整个依赖Jar。
方案4:将依赖Jar作为Java资源上传
把依赖Jar作为数据库的Java资源整体存储,避免拆分为大量单个类对象:
- 上传依赖Jar为资源:
CALL dbms_java.loadjava('-r -v -f -res /home/usr/javastuff/ojdbc.jar'); - 设置资源路径,让业务类可以找到依赖:
CALL dbms_java.set_resource_path('/home/usr/javastuff/ojdbc.jar', 'APPEND'); - 加载业务类Jar:
依赖以Jar资源形式存在,不会拆分成大量独立对象,同时业务类可以正常引用依赖。CALL dbms_java.loadjava('-r -v -f /home/usr/javastuff/Application.jar');
内容的提问来源于stack exchange,提问作者Branimir
相关产品推荐
相关产品推荐

