You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-user@db.apache.org by Mikael <mi...@telia.com> on 2007/09/21 16:51:08 UTC
PreparedStatement problem with big BLOBS
Hi !
I have a pretty weird problem, I use a Derby 10.3.1.4 with the ClientDriver and I run the code below:
// Data is a byte[] vector
ByteArrayInputStream is = new ByteArrayInputStream( data);
String sql = "UPDATE MyTable SET FContents=? WHERE FName='" + name + "'";
PreparedStatement ps = conn.prepareStatement( sql);
ps.setBinaryStream( 1, is, data.length);
if( ps.executeUpdate() == 0)
{
// it throws an exception here if the data array us larger then around 32750 bytes!!!
}
Connection is "jdbc:derby://localhost/mydb;create=true;"
java.sql.SQLException: A network protocol error was encountered and the connection has been terminated: A PROTOCOL Data Stream Syntax Error was detected. Reason: 0x0. Plaintext connection attempt to an SSL enabled server?
at org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(Unknown Source)
at org.apache.derby.client.am.SqlException.getSQLException(Unknown Source)
at org.apache.derby.client.am.PreparedStatement.executeUpdate(Unknown Source)
The table is defined as:
CREATE TABLE MyTable (FName varchar(300) NOT NULL,FContents BLOB(16M) NOT NULL)
I do not understand why it only works with small BLOB contents, as soon as I pass 32750 bytes or so the above happens,
when data is 32750 or smaller it works just fine.
Re: PreparedStatement problem with big BLOBS
Posted by Mikael <mi...@telia.com>.
That is correct, no SSL involved at all.
----- Original Message -----
From: "Bernt M. Johnsen" <Be...@Sun.COM>
To: "Derby Discussion" <de...@db.apache.org>
Sent: Monday, September 24, 2007 3:45 PM
Subject: Re: PreparedStatement problem with big BLOBS
Re: PreparedStatement problem with big BLOBS
Posted by "Bernt M. Johnsen" <Be...@Sun.COM>.
>>>>>>>>>>>> Kathey Marsden wrote (2007-09-21 09:14:50):
> Mikael wrote:
> >Hi !
> >
> >I have a pretty weird problem, I use a Derby 10.3.1.4 with the
> >ClientDriver and I run the code below:
> >
> > // Data is a byte[] vector
> > ByteArrayInputStream is = new ByteArrayInputStream( data);
> > String sql = "UPDATE MyTable SET FContents=? WHERE FName='" + name
> >+ "'";
> > PreparedStatement ps = conn.prepareStatement( sql);
> > ps.setBinaryStream( 1, is, data.length);
> >
> > if( ps.executeUpdate() == 0)
> > {
> > // it throws an exception here if the data array us larger
> >then around 32750 bytes!!!
> > }
> >
> >Connection is "jdbc:derby://localhost/mydb;create=true;"
> >
> >java.sql.SQLException: A network protocol error was encountered and
> >the connection has been terminated: A PROTOCOL Data Stream Syntax
> >Error was detected. Reason: 0x0. Plaintext connection attempt to an
> >SSL enabled server?
> > at
> >org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(Unknown
> >Source)
> > at
> >org.apache.derby.client.am.SqlException.getSQLException(Unknown Source)
> > at
> >org.apache.derby.client.am.PreparedStatement.executeUpdate(Unknown Source)
> >The table is defined as:
> > CREATE TABLE MyTable (FName varchar(300) NOT NULL,FContents
> >BLOB(16M) NOT NULL)
> >
> >I do not understand why it only works with small BLOB contents, as
> >soon as I pass 32750 bytes or so the above happens,
> >when data is 32750 or smaller it works just fine.
> >
> Hello Mikal. The error seems related to an SSL enabled server, but it
> would seem that you would get that error at connection time, not when
> inserting into the table. I tried the following program just starting
> network server normally java org.apache.derby.drda.NetworkServerControl
> start and it seemed to run ok. Can you tell me how to modify this
> program or the way I started the server to reproduce your error?
The client error message "A network protocol error was encountered and
the connection has been terminated: A PROTOCOL Data Stream Syntax
Error was detected. Reason: 0x0. Plaintext connection attempt to an
SSL enabled server?" will be thrown in 3 possible cases
1) A buggy DRDA data stream was sent from the server
2) A plaintext client tries to connect to an SSL enabled server
3) A plaintext client tries to connect to any other server which does
not talk DRDA.
So that's why the question mark is there. I assume Mikael hits case
#1 and no SSL is involved.
--
Bernt Marius Johnsen, Database Technology Group,
Staff Engineer, Derby/Java DB
Sun Microsystems, Trondheim, Norway
Re: PreparedStatement problem with big BLOBS
Posted by Kathey Marsden <km...@sbcglobal.net>.
Mikael wrote:
> Hi !
>
> I have a pretty weird problem, I use a Derby 10.3.1.4 with the
> ClientDriver and I run the code below:
>
> // Data is a byte[] vector
> ByteArrayInputStream is = new ByteArrayInputStream( data);
> String sql = "UPDATE MyTable SET FContents=? WHERE FName='" + name
> + "'";
> PreparedStatement ps = conn.prepareStatement( sql);
> ps.setBinaryStream( 1, is, data.length);
>
> if( ps.executeUpdate() == 0)
> {
> // it throws an exception here if the data array us larger
> then around 32750 bytes!!!
> }
>
> Connection is "jdbc:derby://localhost/mydb;create=true;"
>
> java.sql.SQLException: A network protocol error was encountered and
> the connection has been terminated: A PROTOCOL Data Stream Syntax
> Error was detected. Reason: 0x0. Plaintext connection attempt to an
> SSL enabled server?
> at
> org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(Unknown
> Source)
> at
> org.apache.derby.client.am.SqlException.getSQLException(Unknown Source)
> at
> org.apache.derby.client.am.PreparedStatement.executeUpdate(Unknown Source)
> The table is defined as:
> CREATE TABLE MyTable (FName varchar(300) NOT NULL,FContents
> BLOB(16M) NOT NULL)
>
> I do not understand why it only works with small BLOB contents, as
> soon as I pass 32750 bytes or so the above happens,
> when data is 32750 or smaller it works just fine.
>
Hello Mikal. The error seems related to an SSL enabled server, but it
would seem that you would get that error at connection time, not when
inserting into the table. I tried the following program just starting
network server normally java org.apache.derby.drda.NetworkServerControl
start and it seemed to run ok. Can you tell me how to modify this
program or the way I started the server to reproduce your error?
Thanks
Kathey
import java.sql.*;
import java.io.*;
public class TestBlob {
public static void main(String args[]) throws Exception {
Class.forName("org.apache.derby.jdbc.ClientDriver").newInstance();
Connection conn =
DriverManager.getConnection("jdbc:derby://localhost:1527/wombat;create=true");
Statement s = conn.createStatement();
try {
s.executeUpdate("drop table MyTable");
} catch (SQLException se) {}
s.executeUpdate("create table MyTable (Contents BLOB(2G))");
s.executeUpdate("insert into MyTable VALUES NULL");
byte[] data = new byte[40000];
for (int i = 0; i < 40000; i++)
data[i] = 'a';
ByteArrayInputStream is = new ByteArrayInputStream( data);
String sql = "UPDATE MyTable SET Contents=?";
PreparedStatement ps = conn.prepareStatement( sql);
ps.setBinaryStream( 1, is, data.length);
ps.executeUpdate();
ps.close();
conn.close();
}
}
Re: PreparedStatement problem with big BLOBS
Posted by Kathey Marsden <km...@sbcglobal.net>.
Kathey Marsden wrote:
> I was able to reproduce the exception with your reproduction.
Looks like this regressed with revision 438478 of DERBY-1559
http://svn.apache.org/viewvc?view=rev&revision=438478
Re: PreparedStatement problem with big BLOBS
Posted by Kathey Marsden <km...@sbcglobal.net>.
Mikael wrote:
> Here is a modified version of the SimpleApp that comes with Derby, if
> you run it without any argument (embedded mode) it works just fine,
> but if you add the argument "derbyclient" to run it in client mode it
> throws the exception,
Thanks Mikael,
I was able to reproduce the exception with your reproduction. It also
reproduced with 10.2, but with a generic protocol message. The program
was successful with 10.1 so this is a regression in 10.2.
Could you file an issue and mark it as a regression.
http://db.apache.org/derby/DerbyBugGuidelines.html
Thanks for finding this problem.
Kathey
Re: PreparedStatement problem with big BLOBS
Posted by Mikael <mi...@telia.com>.
Here is a modified version of the SimpleApp that comes with Derby,
if you run it without any argument (embedded mode) it works just
fine, but if you add the argument "derbyclient" to run it in client mode
it throws the exception, the modified code is marked with comments
and look's like this:
byte[] data = new byte[ 38000];
ByteArrayInputStream is = new ByteArrayInputStream( data);
String sql = "UPDATE testing SET contents=? WHERE num=1";
PreparedStatement ps = conn.prepareStatement( sql);
ps.setBinaryStream( 1, is, data.length);
int x = ps.executeUpdate(); // Throws exception here
----- Original Message -----
From: "Bryan Pendleton" <bp...@amberpoint.com>
To: "Derby Discussion" <de...@db.apache.org>
Sent: Friday, September 21, 2007 6:05 PM
Subject: Re: PreparedStatement problem with big BLOBS
>> I do not understand why it only works with small BLOB contents, as soon
>> as I pass 32750 bytes or so the above happens,
>> when data is 32750 or smaller it works just fine.
>
> This sounds like a bug to me. The DRDA client/server protocol
> tends to divide data at 32K boundaries, so it's possible that
> there is a bug in that implementation that you have encountered.
>
> Can you provide a test program that reproduces this problem?
>
> thanks,
>
> bryan
>
>
Re: PreparedStatement problem with big BLOBS
Posted by Bryan Pendleton <bp...@amberpoint.com>.
> I do not understand why it only works with small BLOB contents, as soon
> as I pass 32750 bytes or so the above happens,
> when data is 32750 or smaller it works just fine.
This sounds like a bug to me. The DRDA client/server protocol
tends to divide data at 32K boundaries, so it's possible that
there is a bug in that implementation that you have encountered.
Can you provide a test program that reproduces this problem?
thanks,
bryan
Re: PreparedStatement problem with big BLOBS
Posted by Kathey Marsden <km...@sbcglobal.net>.
Kathey Marsden wrote:
> Mikael wrote:
>
>>
>> ps.setBinaryStream( 1, is, data.length);
> [snip rest of the program]
>
> A workaround seems to be to use ps.setBinaryStream without the length
> parameter.
> ps.setBinaryStream( 1, is);
>
Sorry, I was wrong about the workaround. Please ignore my last mail.
Kathey
Re: PreparedStatement problem with big BLOBS
Posted by Kathey Marsden <km...@sbcglobal.net>.
Mikael wrote:
>
> ps.setBinaryStream( 1, is, data.length);
[snip rest of the program]
A workaround seems to be to use ps.setBinaryStream without the length
parameter.
ps.setBinaryStream( 1, is);
Here is the old error output at revision 438478 before SSL was added
which was more helpful: (I don't know if maybe we have an issue with the
message we are getting with protocol errors in 10.3)
[C:/kmarsden/repro/bigblob] java TestBlob
Exception in thread "main" java.sql.SQLException: Network protocol
error: end of stream prematurely reached, parameter #
1. Remaining data has been padded with 0x0.
at
org.apache.derby.client.am.SQLExceptionFactory.getSQLException(SQLExceptionFactory.java:46)
at
org.apache.derby.client.am.SqlException.getSQLException(SqlException.java:345)
at
org.apache.derby.client.am.PreparedStatement.executeUpdate(PreparedStatement.java:389)
at TestBlob.main(TestBlob.java:28)
Caused by: org.apache.derby.client.am.SqlException: Network protocol
error: end of stream prematurely reached, parameter
#1. Remaining data has been padded with 0x0.
at
org.apache.derby.client.net.Request.writePlainScalarStream(Request.java:467)
at
org.apache.derby.client.net.Request.writeScalarStream(Request.java:242)
at
org.apache.derby.client.net.NetStatementRequest.buildEXTDTA(NetStatementRequest.java:855)
at
org.apache.derby.client.net.NetStatementRequest.writeExecute(NetStatementRequest.java:145)
at
org.apache.derby.client.net.NetPreparedStatement.writeExecute_(NetPreparedStatement.java:172)
at
org.apache.derby.client.am.PreparedStatement.writeExecute(PreparedStatement.java:1557)
at
org.apache.derby.client.am.PreparedStatement.flowExecute(PreparedStatement.java:1803)
at
org.apache.derby.client.am.PreparedStatement.executeUpdateX(PreparedStatement.java:394)
at
org.apache.derby.client.am.PreparedStatement.executeUpdate(PreparedStatement.java:380)
... 1 more
This sounds kind of similar to DERBY-2017, but in this case the length
is actually correct so I think this is a separate issue.
Kathey