Friday, April 23, 2010

Retrieve Java source from its binary class

Java can be stored in an Oracle database without the source and only the binary data.  Retrieving the source from a java class may not be as straight forward as you may think but it is possible with these few steps outlined below.

As you can see below the java class has no source.

 


Create table with BLOB column
truncate table lob_class;
select * from lob_class;
commit;
drop table lob_class;
CREATE TABLE lob_class
   (  lob_id      NUMBER(3),
      java_clip   BLOB DEFAULT empty_blob(),
      java_clob   CLOB DEFAULT NULL);


Copy binary source to BLOB column
set serveroutput on
declare
blob1 BLOB;
  temp_blob   BLOB;
  temp_clob   CLOB;
  dest_offset NUMBER  := 1;
  src_offset  NUMBER  := 1;
  amount      INTEGER := dbms_lob.lobmaxsize;
  blob_csid   NUMBER  := dbms_lob.default_csid;
  lang_ctx    INTEGER := dbms_lob.default_lang_ctx;
  warning     INTEGER;
begin
dbms_lob.createtemporary(blob1,true, dbms_lob.session);
dbms_java.export_class('com/budco/csc/feed/DataLoader',blob1);
insert into lob_class (lob_id, java_clip) values (1,blob1);
dbms_lob.freetemporary(blob1);
end;
/
 

Copy binary BLOB column to OS file
Decompile source file with open source java decompiler
DECLARE
   clob_locator BLOB;
   charbuf      VARCHAR2(20);
   read_offset  INTEGER;
   read_amount  INTEGER;
  
vblob BLOB;
vstart NUMBER := 1;
bytelen NUMBER := 32000;
len NUMBER;
my_vr RAW(32000);
x NUMBER;

l_output utl_file.file_type;
  
BEGIN
l_output := utl_file.fopen('DPUMP_EXP_DIR',

                           'blob_csc.class','wb', 32760);
vstart := 1;
bytelen := 32000;

SELECT dbms_lob.getlength(java_clip)
INTO len
FROM lob_class
WHERE lob_id = 1;

x := len;

SELECT java_clip
INTO vblob
FROM lob_class
WHERE lob_id = 1;

-- single write if small enough
IF len < 32760 THEN
utl_file.put_raw(l_output,vblob);
utl_file.fflush(l_output);
ELSE -- write in pieces
vstart := 1;
WHILE vstart < len and bytelen > 0
LOOP
   dbms_lob.read(vblob,bytelen,vstart,my_vr);
   utl_file.put_raw(l_output,my_vr);
   utl_file.fflush(l_output);
   vstart := vstart + bytelen;
   x := x - bytelen;
   IF x < 32000 THEN
      bytelen := x;
   END IF;
utl_file.fclose(l_output);
end loop;
END IF;
END;
/

1 comment:

/* begin todea */ /* end todea */