krwWard
2005-11-23 19:13:34 UTC
I am having a problem with Connection Pooling and Blobs. I have created a
connection pool that uses an OCI connection with oracle. So my definition of
the pool sets the Driver to be "oracle.jdbc.driver.OracleDriver" and the URL to
be "jdbc:Oracle:oci:@MYDB". Using an OCI connection allows me to both read and
write Blobs to Oracle without too much trouble. Using the OCI connection I can
write using the setBytes method and use the getBlob method to read. Everything
works fine when using code executed from my Web application - (servlets).
However, I have some external services I am running that use jndi to connect to
the database through the connection pool. This works great except when it
comes to reading Blobs in a ResultSet. When I try to read the Blob, I am
returned a null. Here is a snippet of my code.
Blob blobData =rset.getBlob("Acceptance_Response_Data");
If (blobData != null)
{
InputStream blobStream=blobData.getBinaryStream();
if (blobStream != null)
{
System.out.println("blobData.class=" + blobData.getClass().getName());
int sizeOfArray = 256;
byte array[] = new byte[sizeOfArray];
int bytesread=0;
ByteArrayOutputStream baos=new ByteArrayOutputStream();
bytesread=blobStream.read(array,0,sizeOfArray);
while(bytesread!=-1)
{
baos.write(array,0,bytesread);
bytesread=blobStream.read(array,0,sizeOfArray);
}
data = baos.toByteArray();
}
}
This code works if I execute this from a servlet. If I execute it from the
command line, it does not. I don't get past the first check to see if the blob
is null. All other inserts, updates, and selects work fine from the command
line.
Here is my connection code
if (environment == null)
{
System.out.println("connectionPool=" + connectionPool);
System.out.println("contextFactory=" + contextFactory);
environment = new Hashtable();
if ((contextFactory != null) && (contextFactory.trim().length() != 0))
environment.put("java.naming.factory.initial", contextFactory);
if ((contextServerURL != null) && (contextServerURL.trim().length() != 0))
environment.put("java.naming.provider.url", contextServerURL);
if ((contextFactoryURLPkgs != null) &&
(contextFactoryURLPkgs.trim().length() != 0))
environment.put("java.naming.factory.url.pkgs", contextFactoryURLPkgs);
}
final InitialContext ctxt = new InitialContext(environment);
final DataSource source = (DataSource)ctxt.lookup(connectionPool);
System.out.println("DataSource class=" + source.getClass().getName());
return (source.getConnection());
Here is the result of the print statements if I run it from the command line
connectionPool=tybera.signer.signerPool
contextFactory=jrun.naming.JRunContextFactory
DataSource class=$Proxy1
conn.class=$Proxy5
stmt.class=$Proxy6
rset.class=$Proxy7
blobData is null
getAcceptanceResponseData returns null due to data==null
No acceptance response data found for submissionid=10
Here is the result of the print statements if I run it from the servlet
connectionPool=tybera.signer.signerPool
contextFactory=jrun.naming.JRunContextFactory
DataSource class=jrun.sql.JRunDataSource
conn.class=jrun.sql.JRunConnectionHandle
stmt.class=jrun.sql.JRunStatement
rset.class=oracle.jdbc.driver.OracleResultSetImpl
blobData.class=oracle.sql.BLOB
data.length, getter 1738
<?xml version="1.0" encoding="UTF-8"?>
<Response><filing version="1.0"><response idref="1
As you can see, I get Proxy classes for the Datasource, Connection, ResultSet,
and Blob classes when I run from the command line, but not when I execute it
from the servlet. I believe JRunContextFactory is returning me a DataSource
that is local if I run from the servlet and is remote if I am not, and it is
the remote implementation that is having difficulties with Blob.
Any thoughts? At this point I am at a bit of a loss. The external service is
polling the database regularly which is why we want to make use of the
connection pooling. I can make a connection to the database without making use
of JRun's connection pooling, but we are hoping that connection pooling will
allow us to minimize the repeated connections we are currently getting.
connection pool that uses an OCI connection with oracle. So my definition of
the pool sets the Driver to be "oracle.jdbc.driver.OracleDriver" and the URL to
be "jdbc:Oracle:oci:@MYDB". Using an OCI connection allows me to both read and
write Blobs to Oracle without too much trouble. Using the OCI connection I can
write using the setBytes method and use the getBlob method to read. Everything
works fine when using code executed from my Web application - (servlets).
However, I have some external services I am running that use jndi to connect to
the database through the connection pool. This works great except when it
comes to reading Blobs in a ResultSet. When I try to read the Blob, I am
returned a null. Here is a snippet of my code.
Blob blobData =rset.getBlob("Acceptance_Response_Data");
If (blobData != null)
{
InputStream blobStream=blobData.getBinaryStream();
if (blobStream != null)
{
System.out.println("blobData.class=" + blobData.getClass().getName());
int sizeOfArray = 256;
byte array[] = new byte[sizeOfArray];
int bytesread=0;
ByteArrayOutputStream baos=new ByteArrayOutputStream();
bytesread=blobStream.read(array,0,sizeOfArray);
while(bytesread!=-1)
{
baos.write(array,0,bytesread);
bytesread=blobStream.read(array,0,sizeOfArray);
}
data = baos.toByteArray();
}
}
This code works if I execute this from a servlet. If I execute it from the
command line, it does not. I don't get past the first check to see if the blob
is null. All other inserts, updates, and selects work fine from the command
line.
Here is my connection code
if (environment == null)
{
System.out.println("connectionPool=" + connectionPool);
System.out.println("contextFactory=" + contextFactory);
environment = new Hashtable();
if ((contextFactory != null) && (contextFactory.trim().length() != 0))
environment.put("java.naming.factory.initial", contextFactory);
if ((contextServerURL != null) && (contextServerURL.trim().length() != 0))
environment.put("java.naming.provider.url", contextServerURL);
if ((contextFactoryURLPkgs != null) &&
(contextFactoryURLPkgs.trim().length() != 0))
environment.put("java.naming.factory.url.pkgs", contextFactoryURLPkgs);
}
final InitialContext ctxt = new InitialContext(environment);
final DataSource source = (DataSource)ctxt.lookup(connectionPool);
System.out.println("DataSource class=" + source.getClass().getName());
return (source.getConnection());
Here is the result of the print statements if I run it from the command line
connectionPool=tybera.signer.signerPool
contextFactory=jrun.naming.JRunContextFactory
DataSource class=$Proxy1
conn.class=$Proxy5
stmt.class=$Proxy6
rset.class=$Proxy7
blobData is null
getAcceptanceResponseData returns null due to data==null
No acceptance response data found for submissionid=10
Here is the result of the print statements if I run it from the servlet
connectionPool=tybera.signer.signerPool
contextFactory=jrun.naming.JRunContextFactory
DataSource class=jrun.sql.JRunDataSource
conn.class=jrun.sql.JRunConnectionHandle
stmt.class=jrun.sql.JRunStatement
rset.class=oracle.jdbc.driver.OracleResultSetImpl
blobData.class=oracle.sql.BLOB
data.length, getter 1738
<?xml version="1.0" encoding="UTF-8"?>
<Response><filing version="1.0"><response idref="1
As you can see, I get Proxy classes for the Datasource, Connection, ResultSet,
and Blob classes when I run from the command line, but not when I execute it
from the servlet. I believe JRunContextFactory is returning me a DataSource
that is local if I run from the servlet and is remote if I am not, and it is
the remote implementation that is having difficulties with Blob.
Any thoughts? At this point I am at a bit of a loss. The external service is
polling the database regularly which is why we want to make use of the
connection pooling. I can make a connection to the database without making use
of JRun's connection pooling, but we are hoping that connection pooling will
allow us to minimize the repeated connections we are currently getting.