It all started with a Java Source compilation error. The problematic code was a Java Source, which was tried to be compiled inside the Oracle Database..
The code was written to make a web service call remotely using the Oracle Database using Java. The creation script was starting as follows;
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "BLABLA"
AS import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Reader;
import java.nio.charset.Charset;
import java.sql.Clob;
import java.sql.SQLException;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
And it was continuing, without any syntax errors. It was actually compiled in an 11.2.0.4 Oracle database without any problems, but when it have come compiling it in an 11.2.0.3 Oracle Database , the customer had throubles, which made me writing this post ..
09:54:01 AS import java.io.BufferedReader;
09:54:01 ...
09:54:02 ORA-24344: compilation error
09:56:01 Start Compiling 1 object(s) ...
09:56:01 Executing ALTER JAVA SOURCE blabla COMPILE ...
09:56:02 [0:0] blabla:10: cannot find symbol
09:56:02 [0:0] symbol : class MessageFactory
09:56:02 [0:0] location: package javax.xml.soap
09:56:02 [0:0] import javax.xml.soap.MessageFactory;
09:56:02 [0:0] blabla:11: cannot find symbol
09:56:02 [0:0] symbol : class MimeHeaders
09:56:02 [0:0] location: package javax.xml.soap
09:56:02 [0:0] import javax.xml.soap.MimeHeaders;
09:56:02 [0:0] blabla:12: cannot find symbol
09:56:02 [0:0] symbol : class SOAPConnection
09:56:02 [0:0] location: package javax.xml.soap
Select comp_name, status, version
from dba_registry ;
select *
from dba_objects
where object_type like '%JAVA%'
and owner = 'SYS'
and object_name like '%soap%'
On the other hand; there was a document in Oracle Support for making these kind of web services operations using PL/SQL rahter than Java.
Altough, this document seemed unrelated , it had an excellent reference to a jar file..
By using the following sequence of commands loading of soap package could be done;
cd $ORACLE_HOME/sqlj/lib (replacing $ORACLE_HOME with the proper directory structure)
loadjava -u username/password -r -v -f -s -grant public -genmissing dbwsclientws.jar dbwsclientdb11.jar
The customer loaded those jars; and as expected it seemed loading these jars would bring the soap java package in to the database , and these actions actually did bring the soap java package :)
So far so good. No effort for manual load was needed, but this time another compilation errors were encountered..
14:31:13 Executing ALTER JAVA SOURCE blabla COMPILE ...
14:31:13 [0:0] blabla:21: cannot find symbol
14:31:13 [0:0] symbol : method getBytes(java.nio.charset.Charset)
14:31:13 [0:0] location: class java.lang.String
14:31:13 [0:0] SOAPMessage message = factory.createMessage(new MimeHeaders(), new ByteArrayInputStream(xml.getBytes(Charset.forName("UTF-8"))));
14:31:13 [0:0] ^
14:31:13 [0:0] blabla:31: cannot find symbol
14:31:13 [0:0] symbol : method isEmpty()
14:31:13 [0:0] location: class java.lang.String
14:31:13 [0:0] if(outputParameterText.isEmpty() == false){
14:31:13 [0:0] ^
14:31:13 [0:0] 2 errors
14:31:13 Compilation complete - 11 error(s) found
14:31:13 End Compiling 1 object(s)
This time, the compiler was complaing about the the java.nio.charset.Charset.. It seemed it had no method named forName..
select *
from dba_objects
where object_type like '%JAVA%'
and owner = 'SYS'
and object_name like '%java/nio%'
Executing the same java stored procedure on Oracle 10.1, 10.2, 11.1, 11.2 and 12.1 databases will show following results for JVM version:
Oracle 10.1 runs java.vm.version=1.4.1
Oracle 10.2 runs java.vm.version=1.4.2
Oracle 11.1 runs java.vm.version=1.5.0_01
Oracle 11.2 runs java.vm.version=1.6.0_43
Oracle 12.1 runs java.vm.version=1.6.0_43 or higher
The code was written to make a web service call remotely using the Oracle Database using Java. The creation script was starting as follows;
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "BLABLA"
AS import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Reader;
import java.nio.charset.Charset;
import java.sql.Clob;
import java.sql.SQLException;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
public class WebServiceCall {
private static SOAPMessage getSoapMessageFromString(String xml) throws SOAPException, IOException {
MessageFactory factory = MessageFactory.newInstance();
SOAPMessage message = factory.createMessage(new MimeHeaders(), new ByteArrayInputStream(xml.getBytes(Charset.forName("UTF-8"))));
return message;
}
import javax.xml.soap.SOAPMessage;
public class WebServiceCall {
private static SOAPMessage getSoapMessageFromString(String xml) throws SOAPException, IOException {
MessageFactory factory = MessageFactory.newInstance();
SOAPMessage message = factory.createMessage(new MimeHeaders(), new ByteArrayInputStream(xml.getBytes(Charset.forName("UTF-8"))));
return message;
}
......
As you may expect, the Java Souce could not be compiled on 11.2.0.3..
The key errors were as follows;
09:54:01 ...
09:54:02 ORA-24344: compilation error
09:56:01 Start Compiling 1 object(s) ...
09:56:01 Executing ALTER JAVA SOURCE blabla COMPILE ...
09:56:02 [0:0] blabla:10: cannot find symbol
09:56:02 [0:0] symbol : class MessageFactory
09:56:02 [0:0] location: package javax.xml.soap
09:56:02 [0:0] import javax.xml.soap.MessageFactory;
09:56:02 [0:0] blabla:11: cannot find symbol
09:56:02 [0:0] symbol : class MimeHeaders
09:56:02 [0:0] location: package javax.xml.soap
09:56:02 [0:0] import javax.xml.soap.MimeHeaders;
09:56:02 [0:0] blabla:12: cannot find symbol
09:56:02 [0:0] symbol : class SOAPConnection
09:56:02 [0:0] location: package javax.xml.soap
..
...
.....
So, this could mean that the Entprise Java packages(like soap) in 11.2.0.4 were coming by default.
And a lot more ....
Okay, the cause of these errors were the JDK embedded / inside the Oracle Database.. It was clear that some packages could not be found , especially javax.xml.soap..
The developers were thinking that at least Oracle 11.2.0.4 was needed to compile such a Java Source, as it was clear that 11.2.0.3 didnt have the necessary java packages.. That's why an 11.2.0.4 upgrade was requested immediately..
On the other hand; the customer's Dba didnt approve this request because it was only about a single Java object.
At this point , I step in, made the following analysis and solved the problem without a need to upgrade the entire database.
At this point , I step in, made the following analysis and solved the problem without a need to upgrade the entire database.
It was a productive day, which made me do practices in Java.
First of all, there is no document or a whitepaper saying that 11.2.0.4 is needed for compiling these kind of Java Souce objects..
The only statement I could find in Oracle, was "Release 11.2.0.4 provides an enterprise class platform, Oracle JVM, for developing and deploying server-based Java applications."
That seemed to be true, because the Java source was compiling without any errors in 11.2.0.4.
However; we had 11.2.0.3 , so we needed to find a solution in place.
However; we had 11.2.0.3 , so we needed to find a solution in place.
First, checked the component status in the reqisty using the following query;
I was interested to see the Java Virtual Machine Status and Jasva Database Java Packages status.
from dba_registry ;
COMP_NAME | STATUS | VERSION |
OWB | VALID | 11.2.0.3.0 |
Oracle Application Express | VALID | 3.2.1.00.12 |
Oracle Enterprise Manager | VALID | 11.2.0.3.0 |
OLAP Catalog | VALID | 11.2.0.3.0 |
Spatial | VALID | 11.2.0.3.0 |
Oracle Multimedia | VALID | 11.2.0.3.0 |
Oracle XML Database | VALID | 11.2.0.3.0 |
Oracle Text | VALID | 11.2.0.3.0 |
Oracle Expression Filter | VALID | 11.2.0.3.0 |
Oracle Rules Manager | VALID | 11.2.0.3.0 |
Oracle Workspace Manager | VALID | 11.2.0.3.0 |
Oracle Database Catalog Views | VALID | 11.2.0.3.0 |
Oracle Database Packages and Types | VALID | 11.2.0.3.0 |
JServer JAVA Virtual Machine | VALID | 11.2.0.3.0 |
Oracle XDK | VALID | 11.2.0.3.0 |
Oracle Database Java Packages | VALID | 11.2.0.3.0 |
OLAP Analytic Workspace | VALID | 11.2.0.3.0 |
Oracle OLAP API | VALID | 11.2.0.3.0 |
Oracle Real Application Clusters | VALID | 11.2.0.3.0 |
Everything seemed okay..
Then I checked to see the soap package .. I was interested to see its presence..
from dba_objects
where object_type like '%JAVA%'
and owner = 'SYS'
and object_name like '%soap%'
Okay, the problem was that as expected.. The soap package was missing.. That is, it was not coming in 11.2.0.3 by default.. So it seemed; we had to install/load these kind of missing packages manually using jars...
Okay good, but there were no references for this kind of operations , especially for soap..
Maybe that was the reason that made the Developers think 11.2.0.4 as one an only solution.
Maybe that was the reason that made the Developers think 11.2.0.4 as one an only solution.
Only the following documents were making sense, but they weren't point shots, and unfortuneatly they were for older releases.
How to Load Soap.jar into Oracle Database (Doc ID 344799.1)
They were not answering the question likes which soap package to use; where to download what are the dependencies and etc..
Using UTL_DBWS to Make a Database 11g Callout to a Document Style Web Service (Doc ID 841183.1)
In te 4th Step of this documents; it was saying that : Load the necessary core web services callout jar files into the database. This step is to load the core Java components and is a completely separate action from loading the PL/SQL package as described in the previous steps. This means that the considerations for completing this step are entirely different from the loading of the PL/SQL components.
The load that was mentioned here was by using the dbwsclientws.jar and dbwsclientdb11.jar files.
The load that was mentioned here was by using the dbwsclientws.jar and dbwsclientdb11.jar files.
These jar files were located in te UTL_DBWS utiliy , which can be downloaded from Oracle Support. Download the LATEST copy of the UTL_DBWS utility zip file from the Oracle Technology Network (OTN). This file, for an 11G database, is named dbws-callout-utility-10131.zip and can be obtained from here.
By using the following sequence of commands loading of soap package could be done;
loadjava -u username/password -r -v -f -s -grant public -genmissing dbwsclientws.jar dbwsclientdb11.jar
The customer loaded those jars; and as expected it seemed loading these jars would bring the soap java package in to the database , and these actions actually did bring the soap java package :)
So far so good. No effort for manual load was needed, but this time another compilation errors were encountered..
14:31:13 [0:0] blabla:21: cannot find symbol
14:31:13 [0:0] symbol : method getBytes(java.nio.charset.Charset)
14:31:13 [0:0] location: class java.lang.String
14:31:13 [0:0] SOAPMessage message = factory.createMessage(new MimeHeaders(), new ByteArrayInputStream(xml.getBytes(Charset.forName("UTF-8"))));
14:31:13 [0:0] ^
14:31:13 [0:0] blabla:31: cannot find symbol
14:31:13 [0:0] symbol : method isEmpty()
14:31:13 [0:0] location: class java.lang.String
14:31:13 [0:0] if(outputParameterText.isEmpty() == false){
14:31:13 [0:0] ^
14:31:13 [0:0] 2 errors
14:31:13 Compilation complete - 11 error(s) found
14:31:13 End Compiling 1 object(s)
Checked the java package using the following;
select *
from dba_objects
where object_type like '%JAVA%'
and owner = 'SYS'
and object_name like '%java/nio%'
It was there.. Oracle Database 11.2.0.3 had java.nio.charset, so what was the problem?
The problem should be the method "forName" .. I guessed that it was missing because I knew that this method comes with JDK 1.6.. So the jdk in this release may be below 1.6..
According to Oracle Support JDKs or lets say JVMs in Oracle Database were as follows;
Oracle 10.1 runs java.vm.version=1.4.1
Oracle 10.2 runs java.vm.version=1.4.2
Oracle 11.1 runs java.vm.version=1.5.0_01
Oracle 11.2 runs java.vm.version=1.6.0_43
Oracle 12.1 runs java.vm.version=1.6.0_43 or higher
But , I had doubts about this info, as it might be referring to Oracle Database 11.2.0.4 when saying Oracle 11.2 runs java.vm.version=1.6.0_43
Then I checked the JDK version of Oracle Database using the following support doc..
The result was as I expected;
This was the needed action to compile this Java Source with a 1.5 JDK, and this action solved the remaining compilation problems.. It saved the day :)
In this incident; I realized that again..I realized that being a Senior/Principle Oracle Dba/Apps Dba consultant, requires we to have a good developer perspective, too..
How To Determine The JDK Version Used by the Oracle JVM in the Database (Doc ID 131872.1)
The JDK in 11.2.0.4 Oracle Database was 1.6, but the JDK in 11.2.0.3 Oracle Database was 1.5...
So this error was normal ..
The idea to upgrade JDK, which resided in Oracle Database 1.5 to 1.6 seemed utopic, and it was also not supported.
Thus, I had to find another solution in place.
In this manner; I suggested to change a line in the problematic java source script as follows;
I recommended to use UTF8 directly.. Sourcing a script would do the job..
java.lang
Class String
getBytespublic byte[] getBytes( String charsetName) throws UnsupportedEncodingException
Encodes this String into a sequence of bytes using the named charset, storing the result into a new byte array.
The behavior of this method when this string cannot be encoded in the given charset is unspecified. The CharsetEncoder class should be used when more control over the encoding process is required.
Parameters:charsetName - the name of a supported charsetReturns:The resultant byte arrayThrows:UnsupportedEncodingException - If the named charset is not supportedSince:JDK1.1
Modify this line;I recommended to use UTF8 directly.. Sourcing a script would do the job..
java.lang
Class String
getBytespublic byte[] getBytes( String charsetName) throws UnsupportedEncodingException
Encodes this String into a sequence of bytes using the named charset, storing the result into a new byte array.
The behavior of this method when this string cannot be encoded in the given charset is unspecified. The CharsetEncoder class should be used when more control over the encoding process is required.
Parameters:charsetName - the name of a supported charsetReturns:The resultant byte arrayThrows:UnsupportedEncodingException - If the named charset is not supportedSince:JDK1.1
....................ByteArrayInputStream(xml. getBytesCharset.forName("UTF- 8")));
To be like the following;
.....................................ByteArrayInputStream(xml. getBytes("UTF8")));
This was the needed action to compile this Java Source with a 1.5 JDK, and this action solved the remaining compilation problems.. It saved the day :)
No need to say that; using Oracle Support efficiently is a must for being successful.
One last thing about the dependency in Oracle Database; upgrading the Jdk seems unsupported.
Alternatively, you can use OS tier to develop your Java code if it satisfies your needs.. You can have several Jdks in Os tier and you can upgrade them if needed..
One other alternative is to use PLSQL for web service operations, like mentioned in the following doc:
Using UTL_DBWS to Make a Database 11g Callout to a Document Style Web Service (Doc ID 841183.1) .. UTL_DBWS will make you use java indirectly :)
Okay that 's all for now.. Hope you 'll find this useful.
One last thing about the dependency in Oracle Database; upgrading the Jdk seems unsupported.
Alternatively, you can use OS tier to develop your Java code if it satisfies your needs.. You can have several Jdks in Os tier and you can upgrade them if needed..
One other alternative is to use PLSQL for web service operations, like mentioned in the following doc:
Using UTL_DBWS to Make a Database 11g Callout to a Document Style Web Service (Doc ID 841183.1) .. UTL_DBWS will make you use java indirectly :)
Okay that 's all for now.. Hope you 'll find this useful.
No comments :
Post a Comment
If you will ask a question, please don't comment here..
For your questions, please create an issue into my forum.
Forum Link: http://ermanarslan.blogspot.com.tr/p/forum.html
Register and create an issue in the related category.
I will support you from there.