Archive for September 2007
Java Class File Version
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.
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
Long road to loadjava…
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
SP2-0734: unknown command beginning "…" …
I use Notepad++ for my SQL scripts writing, and one day, I tried to FTP the script to a Unix machine and wanted to run it using SQL*PLus, for argument sake:
SQL> @test.sql
SP2-0734: unknown command beginning “select…” – rest of line ignored.
My script is very simple – one line (no line before the statement, no line after):
select sysdate from dual;
Why won’t it execute??
Turns out it is to do with the Encoding settings of my editor:
When I `more` the file in Unix, it had all this funny characters like ^M all over the file. So I set my editor settings to Unix and ANSI, all returns to normal.
Thought I had one too many coffees…
Resizing db_cache_size
It was interesting to see what happened when I tried to resize the db_cache_size to something greater than sga_max_size, in my test database.
SGA resizing operations are recorded in v$sga_resize_ops:
SQL> select * from v$sga_resize_ops;
COMPONENT OPER_T OPER_M PARAMETER INITIAL_SIZE TARGET_SIZE
————— —— —— ————— ———— ———–
FINAL_SIZE STATUS START_TIM END_TIME
———- —— ——— ———
buffer cache GROW MANUAL db_cache_size 2147483648 8606711808
2147483648 ERROR 20-SEP-07 20-SEP-07
SQL> show parameter sga_max_size;
NAME TYPE VALUE
——————— ———– ——————————
sga_max_size big integer 2635568784
In the alert logs:
CKPT: Begin resize of buffer pool 3 (DEFAULT for block size 8192)
CKPT: Current size = 2048 MB, Target size = 8208 MB
CKPT: Could not allocate memory for buffer pool DEFAULT,
blocksize 8192
