ORA-29540 DirectStreamReader does not exist
User faces issue with UDF objects, ORA-29540.
ORA-29540: class com/pega/pegarules/data/udf/directstreamreader/DirectStreamReader does not exist
Steps to Reproduce
The root cause of this problem is defect/misconfiguration in the operating environment. User was facing the reported behaviour since UDF was installed.
By running the below query, User has confirmed the root cause.
Select Dbms_Java.Longname(Object_Name) From User_Objects Where Status='VALID' AND object_type LIKE 'JAVA%';
The above query results in the class, ‘com/pega/pegarules/data/udf/directstreamreader/DirectStreamReader’ being listed.
This issue is resolved through the following steps:
Steps to install UDF manually on PRPC 7.1 Split schema are as follows:
Step 1: Take a backup of your existing DB
Use EXPDP command (in oracle) to take a full database backup.
Pre-requisite check if re-creating UDF
1. Drop all UDFs
2. Generate a drop script using (run as SYSTEM user):
3. Select 'drop JAVA class PRPCDATA."' || object_name || '";' from dba_objects where owner = 'PRPCDATA' and object_type = 'JAVA CLASS';
Drop Functions (optional)
If GUI installer or GenerateDDL script has run previously from this location, you need to drop the functions, else the install script ends with FAILED message. This however still creates the Java classes, it only fails on creating functions, because they already exist.
This is only needed if following directory is present and has relevant SQL statements: <PEGA_INSTALLSET>/schema/generated/oracledate/install/
Drop all the UDFs related functions. To get the Drop script, run these 2 queries (as SYSTEM user on DB):
select 'drop function PRPCDATA."' || object_name || '";' from dba_objects where owner = 'PRPCDATA' and object_type = 'FUNCTION';
select 'drop function PRPCRULES."' || object_name || '";' from dba_objects where owner = 'PRPCRULES' and object_type = 'FUNCTION';
The above queries result in Drop statements such as:
drop JAVA class PRPCDATA."/fcf52cd4_DirectStreamEnvironm";
drop JAVA class PRPCDATA."/fad24711_DirectStreamReaderDB";
drop JAVA class PRPCDATA."/e9802c50_DirectStream";
drop JAVA class PRPCDATA."/af2ac841_InflaterV7";
drop JAVA class PRPCDATA."/ac7654fa_DirectStreamReaderPo";
drop JAVA class PRPCDATA."/9dbd2fb4_BadReferenceExceptio";
drop JAVA class PRPCDATA."/9b1d56c2_BasicEnvironmentAdap";
drop JAVA class PRPCDATA."/8f93fd2d_DirectStreamReaderBa";
drop JAVA class PRPCDATA."/8259c7b6_FixedCacheMap";
drop JAVA class PRPCDATA."/7c1e1a3d_PropertyReferenceUti";
drop JAVA class PRPCDATA."/75ff6599_CachedDirectStream";
drop JAVA class PRPCDATA."/644d6c0f_UnsupportedFeatureEx";
drop JAVA class PRPCDATA."/43e33eef_BadStreamDataExcepti";
drop JAVA class PRPCDATA."/32d1f03d_DirectStreamReader";
drop JAVA class PRPCDATA."/2b12b644_DirectStreamReaderDB";
drop JAVA class PRPCDATA."/20e5462f_ByteArrayUtil";
drop function PRPCDATA."PR_READ_INT_FROM_STREAM";
drop function PRPCDATA."PR_READ_FROM_STREAM";
drop function PRPCDATA."PR_READ_DECIMAL_FROM_STREAM";
drop function PRPCRULES."PR_READ_INT_FROM_STREAM";
drop function PRPCRULES."PR_READ_FROM_STREAM";
drop function PRPCRULES."PR_READ_DECIMAL_FROM_STREAM";
Step 2: Cross check whether java is enabled on your database.
To verify, run the following sql as SYSDBA.
select comp_name, version, status from dba_registry where upper(comp_name) like '%JAVA%';
A record for JVM must be returned. For example: on 11gR2, 'JServer JAVA Virtual Machine'.
Step 3: Create Procedure DB privilege
The database user used during installation must have the "create procedure" permission explicitly granted.
To verify that you have proper DB privilege, run the following sql as SYSDBA.
Select * from dba_sys_privs where grantee='<PRPCADMIN>' and privilege='CREATE ANY PROCEDURE';
Replace <PRPCADMIN> with the real PRPC ADMIN schema owner.
A record should be returned, with the schema owner and the 'CREATE ANY PROCEDURE' privilege listed.
If not, grant Create ANY Procedure DB privilege to PRPC DB schema owner.
Step 4: Map your DB properties
In the scripts folder in your PRPC media, configure the setupDatabase.properties file to map it to the PRPC schema where you install UDF.
Step 5: Modify setupDatabase.xml file
Once the permissions are setup correctly, to run the setupUDF piece the easiest thing to do is to add a new target to setupDatabase.xml which initializes, configures and generates UDF.
In setupDatabase.xml add below snippet:
<target name="installUDF" depends="Initialization, Configuration, Apply UDFs">
<echo message="PegaRULES Process Commander UDF load complete."/>
Step 6: Edit install.sh to install only UDF
Edit line of install.sh to call this new target or set ant_home and java_home and make the call from the command line.
"`dirname "$0"`/bin/ant" $ANT_PROPS -f ./setupDatabase.xml install -noclasspath 2>&1 | tee $logfile
"`dirname "$0"`/bin/ant" $ANT_PROPS -f ./setupDatabase.xml installUDF -noclasspath 2>&1 | tee $logfile
Step 7: Execute install.sh
This should be executed from the INSTALLSET/scripts folder.
The build should complete successfully.
Check all dropped objects were created. If not, you need to run GenerateDDL script if the functions are missing (see pre-req check above)
Step 8: Execute the below SQL for testing:
SELECT PRPCDATA.pr_read_from_stream('pzInsKey', pzInsKey, pzPVStream) as "StringValue", PRPCDATA.pr_read_int_from_stream('pzRuleSetVersionMajor', pzInsKey, pzPVStream) as "IntegerValue", PRPCDATA.pr_read_decimal_from_stream('pzRuleSetVersionMinor', pzInsKey, pzPVStream) as "DecimalValue" from prpcrules.pr4_rule where pxInsID like 'CANNOT%';
Sample output (7.1.5):
RULE-MESSAGE CANNOTBEBLANK #20131021T154455.159 GMT 7 10
RULE-MESSAGE CANNOTBEBLANK #20130919T015230.511 GMT 7 10
RULE-MESSAGE CANNOTBEBLANK #20131021T154757.011 GMT 7 10
RULE-MESSAGE CANNOTBENONALPHANUM #20130919T015230.561 GMT 7 10
RULE-MESSAGE CANNOTIDENTIFYTHREAD #20130918T235100.459 GMT 7 10
RULE-MESSAGE CANNOTSORT #20130918T235100.524 GMT 7 10
This will make a call to a function, which makes use of the Java Objects: We are not interested in the result of this; it is simply to call the objects. Please note, if this SQL is run in same session where the objects were previously dropped, you will need to run it twice.
Step 9: Execute below to check invalid java objects
SELECT dbms_java.longname(object_name) FROM all_objects WHERE status!='VALID' AND object_type LIKE 'JAVA%';
At this moment most of the JAVA objects should be valid. Run as SYSTEM.
If some objects are invalid, that is fine as long as query in Step 8 succeeds.