Frederick Tang Weblog

Stories about Oracle concepts I have learnt from work, and the occasional brain-dump…

Archive for the ‘Java’ Category

Installing Oracle10g JAccelerator (NCOMP) on Solaris 10 (SPARC)

with 3 comments

Let’s suppose you find the need to natively compile some Java code on an Oracle10g database, then you would need to have JAccelerator (NCOMP) installed. I have prepared a few installations steps to follow that worked for me. It took me a few days to work this out…

Disclaimer: These steps were tested on Solaris 10 SPARC platform, with a Oracle10g 10.2.0.4 standalone database. Best efforts were made to ensure the steps are correct, but please take extra care when executing them on your platform. Do not run this on your Production environment if you are unsure what it will do.

Let’s start from the beginning…

1. To find out whether you have NCOMP installed, there are two things you can do:

select dbms_java.full_ncomp_enabled from dual
*
ERROR at line 1:
ORA-29558: JAccelerator (NCOMP) not installed. Refer to Install Guide for
instructions.
ORA-06512: at "SYS.DBMS_JAVA", line 236

 

or try executing this on command line, which should show two lines if NCOMP is installed.

$ORACLE_HOME/OPatch/opatch lsinventory -detail |grep JAccelerator
JAccelerator (COMPANION)                                             10.2.0.1.0
JAccelerator (COMPANION) Patch                                       10.2.0.4.0

 

2. Suppose NCOMP is not installed, then you would need to get the Oracle10g Companion CD (downloadable here). Run the installer, and select the “Oracle Database 10g Products” option which will install into your existing Oracle home. Full installation guide is available here. This will install JAccelerator 10.2.0.1.0 along with other 10g Companion products. If you run the opatch command again, you should now see JAccelerator listed.

 

3. Next, we need to patch JAccelerator to the latest patchset – 10.2.0.4. Download the 10.2.0.4 patchset from Metalink and start the installer as usual. Metalink Note 293658.1 explains that the OUI will see the new components installed and only install the 10.2 patches associated to the new products. Re-run catupgrd.sql and utlrp.sql .

10204_1 10204_2

 

4. After completing the patchset installation, re-running the first two checks should show you some good news.

SQL> select dbms_java.full_ncomp_enabled from dual;

FULL_NCOMP_ENABLED
----------------------------------------------------
OK

 

$ORACLE_HOME/OPatch/opatch lsinventory -detail |grep JAccelerator
JAccelerator (COMPANION)                                             10.2.0.1.0
JAccelerator (COMPANION) Patch                                       10.2.0.4.0

 

5. Before one can natively compile anything, we need to follow a few more steps as documented here. Verify a C compiler and linker is installed, and the ncomp properties file knows their full path. Suppose your platform is like mine, then it means you probably need a proper C compiler:

$ which cc
/usr/ucb/cc
$ cc
/usr/ucb/cc:  language optional software package not installed

 

6. Metalink Note: 43208.1 documents a list of Certified Compilers. For Solaris SPARC:

* 10.1.0 Sun ONE Studio 8, C/C++ 5.5
* 10.2.0 Sun ONE Studio 8, C/C++ 5.5
* 11.1.0 Sun ONE Studio 11, C/C++ 5.8
Note: Sun ONE Studio 8 or higher is supported with 9.2, 10.1, 10.2

 

In any case, I downloaded Sun Studio 11 software here. This software installation requires root privilege and installs the C compiler into /opt/SUNWspro by default. Check all system requirements before installation. As an aside, I also tried gcc 3.4.6 but NCOMP didn’t like it very much…

 

7. After the Sun Studio software is installed, update the PATH and LD_LIBRARY_PATH environment variables, e.g.

export PATH=/opt/SUNWspro/bin:$PATH
export LD_LIBRARY_PATH=/opt/SUNWspro/lib:$LD_LIBRARY_PATH

 

8. Inside the $ORACLE_HOME/javavm/jahome directory, you will possibly find two properties files.

$ grep 'CC =' Settings*.properties
Settings.properties:CC = cc
Settings_os.properties:CC = /opt/SunProd/SUNWspro8/bin/cc

 

Update these two lines to the C compiler location, such that if I do another grep:

Settings.properties:CC = /opt/SUNWspro/bin/cc
Settings_os.properties:CC = /opt/SUNWspro/bin/cc

 

9. We are just about done… to enable the database user to perform native compilation, the user needs to be granted certain privileges as documented here, where /app/oracle/10/db is my $ORACLE_HOME:

grant java_deploy to fredt;
grant javasyspriv to fredt;
call dbms_java.grant_permission('FREDT', 'java.io.FilePermission', '/app/oracle/10/db/-', 'read,write');

 

10. We can now ncomp away!

ncomp -u fredt/fredt@MODDB <myJar.jar>

Written by fredericktang

January 21, 2009 at 6:02 am

Posted in 10g, Java, Oracle

Java, Oracle, Bind Variables and Batch Update – Part II

without comments

In my last post, I have setup in Java different insert methods to a database. In this post, I will post what I found in the Oracle trace files / tkprof output and the different response times:

  1. Multiple Inserts using java.sql.Statement
  2. Multiple Inserts using java.sql.PreparedStatement, using Bind Variables
  3. Multiple Inserts using java.sql.Statement, with addBatch() & executeBatch()
  4. Multiple Inserts using java.sql.PreparedStatement, using Bind Variables with addBatch() & executeBatch()

For the impatient readers, the response times when I execute my Java code with each insert method is as follows:

#1 #2 #3 #4
8.012s 9.083s 9.093s 0.15s


Please do not place too much judgments on these timings, they may be affected by the network latency, CPU spikes at the time of testing. However, this study is intended to show the relative amount of work and time spent for each INSERT method.

#1. Multiple Inserts using java.sql.Statement

Oracle trace file / tkprof output:

INSERT INTO insert_test (str)
values
 (:"SYS_B_0")

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse     1000      0.09       0.08          0          0          0           0
Execute   1000      0.31       0.23          2       1006       3065        1000
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total     2000      0.40       0.32          2       1006       3065        1000

Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 23  

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  db file sequential read                         2        0.00          0.00
  SQL*Net message to client                    1002        0.00          0.00
  SQL*Net message from client                  1002        0.04          8.17
********************************************************************************


* The parse count is 1000, and execute count is also 1000 – a 1:1 ratio.
* Some CPU resources were used to parse the statement, and consumed 9ms of CPU time.
* Times waited is 1002 – (my guess) – 1000 for executeUpdate(); 1 for stmt.close(); 1 for commit?
* Oracle waited 8.17s for Java client to issue 1002 calls, one by one.

#2. Multiple Inserts using java.sql.PreparedStatement, using Bind Variables

Oracle trace file / tkprof output:

INSERT INTO insert_test (str)
values
 (:1)

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute   1000      0.16       0.18          3          7       1065        1000
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total     1001      0.16       0.18          3          7       1065        1000

Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 23  

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  db file sequential read                         3        0.00          0.00
  SQL*Net message to client                    1002        0.00          0.00
  SQL*Net message from client                  1002        0.06          8.52
********************************************************************************


* Parse to Execute is a 1:1000 ratio. Almost negligible CPU resource and time spent on parsing.
* Oracle waited 8.52s for Java client to issue 1002 calls, one by one.

#3. Multiple Inserts using java.sql.Statement, with addBatch() & executeBatch()

Oracle trace file / tkprof output:

INSERT INTO insert_test (str)
values
 (:"SYS_B_0")

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse     1000      0.09       0.08          0          0          0           0
Execute   1000      0.31       0.23          2       1006       3065        1000
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total     2000      0.40       0.32          2       1006       3065        1000

Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 23  

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  db file sequential read                         2        0.00          0.00
  SQL*Net message to client                    1002        0.00          0.00
  SQL*Net message from client                  1002        0.04          8.17


* The statistics are similar to Method #1: Multiple Inserts using java.sql.Statement.
* This is because Oracle9i does not support batch updating with java.sql.Statement:

The Oracle implementation of standard update batching does not implement true batching for generic statements and callable statements. Although Oracle JDBC supports the use of standard batching syntax for Statement and CallableStatement objects, you will see performance improvement for only PreparedStatement objects. [source]

#4. Multiple Inserts using java.sql.PreparedStatement, using Bind Variables with addBatch() & executeBatch()

Oracle trace file / tkprof output:

INSERT INTO insert_test (str)
values
 (:1)

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.02       0.04          0         27         89        1000
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      0.02       0.04          0         27         89        1000

Misses in library cache during parse: 0
Optimizer goal: CHOOSE
Parsing user id: 23  

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  SQL*Net more data from client                  12        0.01          0.03
  SQL*Net message to client                       3        0.00          0.00
  SQL*Net message from client                     3        0.00          0.02


* The response time is 0.16secs.
* A (soft) parse of the SQL statement is made, with 1 execute to insert 1000 rows.
* 1 execute saves more time than the 1000 executes in previous methods.
* Communication between the Java client and Oracle is reduced to a minimum, as shown by 3 SQL*Net message from client.
* The 1000 bind values are sent in bulk using SQL*Net more data from client.

Written by fredericktang

September 10, 2008 at 8:20 am

Posted in Java, Oracle

Java, Oracle, Bind Variables and Batch Update – Part I

without comments

This week, I decided to do some simple exercises in Java to test the performance of different Oracle database table insert methods, and observe how much work the database do for each method. Part 1 of this post will demonstrate my Setup, and the Java code I used for each Insert method. Part 2 will show a detailed analysis of the tkprof output, the response times.

  1. Multiple Inserts using java.sql.Statement
  2. Multiple Inserts using java.sql.PreparedStatement, using Bind Variables
  3. Multiple Inserts using java.sql.Statement, with addBatch() & executeBatch()
  4. Multiple Inserts using java.sql.PreparedStatement, using Bind Variables with addBatch() & executeBatch()

Test Environment:

* WinXP laptop; JDK1.3; Oracle9i 9.2.0.8 database with (cursor_sharing=similar); Oracle JDBC Thin Driver.

Please note all the statistics and timing shown in this blog will vary with different environment (e.g. performance of my laptop, JDK version, network speed and database configuration… etc.), do not treat the figures produced here as benchmarks. The Java code provided here are my test codes, and may contain unidentified faults, please use at your own risks.

Test Method:

* Create a simple table in my database,

SQL> create table insert_test (str varchar2(100));

Table created.

* Use Java to instantiate a String array of 1000 random strings (not very pretty I know),

String[] randStrings = new String[1000];
for(i = 0; i < randStrings.length; i++) {
   randStrings[i] = “token” + Math.random();
}

* Trigger a Oracle trace using Java, the trace file generated can be found in $ORACLE_BASE/admin/$ORACLE_SID/udump directory on the database server. Trace files can get hugh very quickly, do not keep a trace running for a long duration. It is best used under the supervision of a DBA.

Statement strace = conn.createStatement();
try {
   strace.executeUpdate(“ALTER SESSION SET EVENTS ‘10046 trace name context forever, level 12′”);
   strace.executeUpdate(“ALTER SESSION SET STATISTICS_LEVEL=all”);
} catch (SQLException t1) {
   t1.printStackTrace();
} finally {
   strace.close();
}

* Use each insert method to insert these strings into the table,

* Measure response times using java.lang.System.currentTimeMillis();

* Analyze Oracle trace files using tkprof.

 

Multiple Inserts using java.sql.Statement

   try {
     long start_ts = System.currentTimeMillis();
     Statement stmt = conn.createStatement();
     for (int i = 0; i < randStrings.length; i++) {
        stmt.executeUpdate(“INSERT INTO insert_test (str) values (‘”+randStrings[i]+”‘)”);
     }
     conn.commit();
     long end_ts = System.currentTimeMillis();
     long sw = end_ts – start_ts;
     System.out.println((double)sw/1000 + “secs”);
  } catch (SQLException e) {
     System.out.println(e.getMessage());
  } finally {
     stmt.close();
  }

Multiple Inserts using java.sql.PreparedStatement, using Bind Variables

  PreparedStatement stmt = conn.prepareStatement(“INSERT INTO insert_test (str) values (?)”);
  try {
     long start_ts = System.currentTimeMillis();
     for (int i = 0; i < randStrings.length; i++) {
        stmt.setString(1, randStrings[i]);
        stmt.executeUpdate();
     }
     conn.commit();
     long end_ts = System.currentTimeMillis();
     long sw = end_ts – start_ts;
     System.out.println((double)sw/1000 + “secs”);
  } catch (SQLException e) {
     System.out.println(e.getMessage());
  } finally {
     stmt.close();
  }

Multiple Inserts using java.sql.Statement, with addBatch() & executeBatch()

    try {
     long start_ts = System.currentTimeMillis();
     Statement stmt = conn.createStatement();
     for (int i = 0; i < randStrings.length; i++) {
        stmt.addBatch(“INSERT INTO insert_test (str) values (‘”+randStrings[i]+”‘)”);
     }
     stmt.executeBatch();
     conn.commit();
     long end_ts = System.currentTimeMillis();
     long sw = end_ts – start_ts;
     System.out.println((double)sw/1000 + “secs”);
  } catch (SQLException e) {
     System.out.println(e.getMessage());
  } finally {
     stmt.close();
  }

Multiple Inserts using java.sql.PreparedStatement, using Bind Variables with addBatch() & executeBatch()

    PreparedStatement stmt = conn.prepareStatement(“INSERT INTO insert_test (str) values (?)”);
  try {
     long start_ts = System.currentTimeMillis();
     for (int i = 0; i < randStrings.length; i++) {
        stmt.setString(1, randStrings[i]);
        stmt.addBatch();

     }
     stmt.executeBatch();
     conn.commit();
     long end_ts = System.currentTimeMillis();
     long sw = end_ts – start_ts;
     System.out.println((double)sw/1000 + “secs”);
  } catch (SQLException e) {
     System.out.println(e.getMessage());
  } finally {
     stmt.close();
  }

Results will be documented in Part 2.

Written by fredericktang

September 10, 2008 at 8:19 am

Posted in Java, Oracle

Java, Oracle and CLOB

with one comment

Today, one of the developers encountered the following error when trying to insert more than 4000 bytes into a CLOB datatype column. The environment is Java 1.4 and Oracle9i (9.2.0.8) database:

ORA-01704: string literal too long

That can happen if the literal (the 4000+ characters String) is embedded into an INSERT statement like a normal String/VARCHAR2. Suppose I create a table like so:

SQL> create table clob_test (id number(10), str clob);

Table created.

This INSERT method won’t work, and will result in the Oracle error, this is because VARCHAR2 has a 4000 bytes limit:

// Create a String of 5000 characters
char[] charArray = new char[5000];
String clobstr = new String(charArray);
     
Statement stmt = conn.createStatement();
try {
   String sql = “INSERT INTO clob_test (str) values (‘”+clobstr+”‘)”;
   stmt.executeUpdate(sql);
} catch (SQLException t1) {
   t1.printStackTrace();
} finally {
   stmt.close();
   conn.commit();
}

Thanks to Holly, she’s worked out a few methods to do this, but they require the use of oracle.sql.CLOB. I will show one of the suggested ways here:

try {
   String sql = “INSERT INTO clob_test (id, str) values (1, empty_clob())”;
   Statement stmt = conn.createStatement();
   stmt.executeUpdate(sql);
   sql = “select str from clob_test where id=1 for update”;
   ResultSet rss=stmt.executeQuery(sql);

   if(rss.next()){
      oracle.sql.CLOB clob= (oracle.sql.CLOB)rss.getClob(“str”);
      clob.putString(1,clobstr);
      sql = “update clob_test set str=? where id=1″;
      PreparedStatement pstmt=conn.prepareStatement(sql);
      pstmt.setClob(1,clob);
      pstmt.executeUpdate();
      pstmt.close();
   }
} catch (SQLException t2) {
   t2.printStackTrace();
} finally {
   stmt.close();
   conn.commit();
}

The Official Oracle9i suggested to use OutputStream, which you can read about it here. It looks a bit more complicated, but a Java developer has to evaluate which of these methods is a better alternative.

There are some good news for Oracle10g databases, which has a much easier way of working with CLOBs. The full Java demo is available here.

Written by fredericktang

July 31, 2008 at 9:31 am

Posted in 10g, 9i, Java, Oracle

Java Class File Version

with 4 comments

I am not posting something new here… but to find the Java Class File Version manually…

1. Use a Hex Editor to view the Java Class File.

View Class file in Hex

2. The first 4 bytes CA FE BA BE is the signature of a Java Class file.

3. The next 2 bytes show the minor version number.

4. The next 2 bytes show the major version number.

5. Convert the hex to decimal number, and find out the JDK version vs. Class File Version. For example: http://www.javaworld.com/javaqa/2003-05/02-qa-0523-version.html?page=3

According to Oracle Metalink Note: 105472.1:

The following is Oracle JDK version compliance:

   Oracle 8.1.5 is compliant with JDK 1.1.6
   Oracle 8.1.6 is compliant with JDK 1.1.8 and 1.2.1
   Oracle 8.1.7 is compliant with JDK 1.2.1
   Oracle 9.0.1 is compliant with JDK 1.2.1
   Oracle 9.2.0 is compliant with JDK 1.3

– Update 24th March 2009
Metalink Note: 401934.1

Oracle 10g supports J2SE 1.4
Oracle 11g supports J2SE 1.5

Written by fredericktang

September 28, 2007 at 8:24 am

Posted in Java

Long road to loadjava…

with 5 comments

This week, one of my projects want to create some Java Stored Procedures in the Oracle9i database. The open source library their code uses is the Apache commons codec. To create the JSPs they wanted, I first have to load the codec library into the database. So the story starts…

1. Initially, I requested the development team to supply me with a Java 1.3 compiled Jar file of the codec library. This is because the Oracle JVM version in an Oracle9i database is 1.3. I was sent a Jar file that was compiled using a -target 1.3 flag, and when I tried to load this into the database:

$loadjava -u ftang/xxxxx -resolve commons-codec-1.3.jar

errors   : class org/apache/commons/codec/BinaryDecoder
    ORA-29534: referenced object org/apache/commons/codec/DecoderException could not be resolved
    ORA-29545: badly formed class:

…. <cut out most of the errors>

The following operations failed
    class org/apache/commons/codec/BinaryDecoder: resolution

…. <cut out most of the errors>

2. I then tried to use -genmissing flag, still no luck.

$loadjava -u ftang/xxxxx -genmissing commons-codec-1.3.jar

I didn’t get any errors in the Shell this time, but every Java Class shows INVALID as status in the database:

SQL> select object_name, object_type, status
  2  from user_objects
  3  where object_type like ‘%JAVA%’;

OBJECT_NAME                    OBJECT_TYPE        STATUS
—————————— —————— ——-
/1195a97a_BCodec               JAVA CLASS         INVALID
/26681f57_BinaryCodec          JAVA CLASS         INVALID
/2d100232_Encoder              JAVA CLASS         INVALID

…. <cut out the rest of the object names>

SQL> alter java class “/b6703010_EncoderException” resolve;

Warning: Java altered with compilation errors.

SQL> show errors
Errors for JAVA CLASS /b6703010_EncoderException:

LINE/COL ERROR
——– ————————————————
0/0      ORA-29545: badly formed class:

3. After a day of Metalink and Internet searching, I couldn’t figure out for the life of me why this is not working. I did read in a forum that suggested ORA-29545 is caused by incompatible Java Class file. In other words, Oracle JVM didn’t like the -target 1.3 compiled Jar file.

To test the truth, I downloaded the source code of the codec and compiled DecoderException.java using JDK 1.3.1_20:

$ java -version
java version “1.3.1_20″
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_20-b03)
Java HotSpot(TM) Client VM (build 1.3.1_20-b03, mixed mode)

$ javac DecoderException.java

I then used Sundararajan’s Version.java to look at the differences:

$ java Version DecoderException.class
class file version is 45.3

$ java Version EncoderException.class
class file version is 47.0

$loadjava -u ftang/xxxxx DecoderException.class
$loadjava -u ftang/xxxxx EncoderException.class

SQL> select object_name, object_type, status
  2  from user_objects
  3  where object_type like ‘%JAVA%’;

OBJECT_NAME                    OBJECT_TYPE        STATUS
—————————— —————— ——-
/618456ed_DecoderException     JAVA CLASS         INVALID
/b6703010_EncoderException     JAVA CLASS         INVALID

SQL> alter java class “/618456ed_DecoderException” resolve;

Java altered.

SQL> alter java class “/b6703010_EncoderException” resolve;

Warning: Java altered with compilation errors.

SQL> show errors
Errors for JAVA CLASS /b6703010_EncoderException:

LINE/COL ERROR
——– ————————————————
0/0      ORA-29545: badly formed class:

SQL> select object_name, object_type, status
  2  from user_objects
  3  where object_type like ‘%JAVA%’;

OBJECT_NAME                    OBJECT_TYPE        STATUS
—————————— —————— ——-
/618456ed_DecoderException     JAVA CLASS         VALID
/b6703010_EncoderException     JAVA CLASS         INVALID

For example, the class file version and the corresponding JDK version is listed here.

So what this is telling at this stage, is that Oracle JVM didn’t like the class file version.

4. I then tried loading the entire source library into the database and see how it likes it. Perhaps if I let Oracle compile it, it might be happier.

$loadjava -u ftang/xxxxx commons-codec-1.3-src.zip

SQL> select object_name, object_type, status
  2  from user_objects
  3  where object_type like ‘%JAVA%’;

OBJECT_NAME                    OBJECT_TYPE        STATUS
—————————— —————— ——-
/1195a97a_BCodec               JAVA CLASS         INVALID
/1195a97a_BCodec               JAVA SOURCE        INVALID
/1de57d57_BCodecTest           JAVA CLASS         INVALID
/1de57d57_BCodecTest           JAVA SOURCE        INVALID
/1ecb3c26_QCodecTest           JAVA CLASS         INVALID
/1ecb3c26_QCodecTest           JAVA SOURCE        INVALID
/1f964432_BinaryCodecTest      JAVA CLASS         INVALID
/1f964432_BinaryCodecTest      JAVA SOURCE        INVALID
/26681f57_BinaryCodec          JAVA CLASS         INVALID
/26681f57_BinaryCodec          JAVA SOURCE        INVALID
/2d100232_Encoder              JAVA CLASS         INVALID
/2d100232_Encoder              JAVA SOURCE        INVALID
/2f584768_StringDecoder        JAVA CLASS         INVALID
/2f584768_StringDecoder        JAVA SOURCE        INVALID

The Java Source and Java Class now come in pairs, but are still INVALID. So I wrote a script to resolve all Java classes:

SQL> spool resolve.sql;

SQL> select ‘alter java class “‘||object_name||’” resolve;’
  2  from user_objects
  3  where object_type like ‘%JAVA%’;

SQL> spool off;

SQL> @resolve

Java altered.

Warning: Java altered with compilation errors.

Warning: Java altered with compilation errors.

Warning: Java altered with compilation errors.

Warning: Java altered with compilation errors.

Java altered.

Java altered.

… <cut out the rest of the output>

I have selected a few errors worth noting to paste below:

SQL> select name, type, text from user_errors;

/1de57d57_BCodecTest           JAVA CLASS
ORA-29535: source requires recompilation

/1de57d57_BCodecTest           JAVA SOURCE
org/apache/commons/codec/net/BCodecTest:22: Class junit.framework.TestCase not found in import.

/1de57d57_BCodecTest           JAVA SOURCE
org/apache/commons/codec/net/BCodecTest:29: Superclass junit.framework.TestCase of class org.apache.commons.codec.net.BCodecTest not found.

/1de57d57_BCodecTest           JAVA SOURCE
 Info: 2 errors

/26681f57_BinaryCodec          JAVA CLASS
ORA-29535: source requires recompilation

/26681f57_BinaryCodec          JAVA SOURCE
org/apache/commons/codec/binary/BinaryCodec:235: Incompatible type for =. Explicit cast needed to convert char to byte.

For example, BCodecTest is some JUnit test code, so there’s no need to make them work properly in the Oracle database. What’s worth noting is the error with BinaryCodec.

BinaryCodec Line 227: byte[] l_ascii = new byte[raw.length << 3];
BinaryCodec Line 235: l_ascii[jj - bits] = ‘0′;

It seems the compiler error is related to this: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4280591

QuotedPrintableCodec, BinaryCodec, URLCodec all have the same error reported by the Oracle Java Compiler. I guess to fix the error, I can cast the char to byte. However, the development team confirmed the classes will not be used, so we decided to not take any further actions.

Most of the Java Class are now valid:

SQL> select object_name, object_type, status
  2  from user_objects
  3  where object_type like ‘%JAVA%’;

OBJECT_NAME                    OBJECT_TYPE        STATUS
—————————— —————— ——-
/1195a97a_BCodec               JAVA CLASS         VALID
/1195a97a_BCodec               JAVA SOURCE        VALID
/1de57d57_BCodecTest           JAVA CLASS         INVALID
/1de57d57_BCodecTest           JAVA SOURCE        INVALID
/1ecb3c26_QCodecTest           JAVA CLASS         INVALID
/1ecb3c26_QCodecTest           JAVA SOURCE        INVALID
/1f964432_BinaryCodecTest      JAVA CLASS         INVALID
/1f964432_BinaryCodecTest      JAVA SOURCE        INVALID
/26681f57_BinaryCodec          JAVA CLASS         INVALID
/26681f57_BinaryCodec          JAVA SOURCE        INVALID
/2d100232_Encoder              JAVA CLASS         VALID
/2d100232_Encoder              JAVA SOURCE        VALID
/2f584768_StringDecoder        JAVA CLASS         VALID
/2f584768_StringDecoder        JAVA SOURCE        VALID

….

I guess this all could still be achieved just the same if we compile the source code into a Jar file, using a 1.3.x compiler.

To view long names of the Java Objects:

SQL> select dbms_java.longname(object_name)
  2  from user_objects where object_type like ‘%JAVA%’;

Hope this helps someone out there :)

Written by fredericktang

September 28, 2007 at 8:15 am

Posted in 9i, Java, Oracle