com.mysql.jdbc.UpdatableResultSet.updateBlob gives AbstractMethodError
12 Message(s) by 6 Author(s) originally posted in java databases
| From: pjvleeuwen |
Date: Tuesday, October 02, 2007
|
Hi all,
I'm quite new to all jdbc, but so far working with resultset's over
SQL seemed easy so far, but I'm having some problems writing a blob to
the
database .
What I try to do is two steps:
1. read an
image from the web and
write it to a blob
2. read the blob and
display it as an image
I did the same thing before without trying to write to the blob, but I
want to
store the images in DB because the only stay on the web for a
couple of weeks.
Googling for UpdatableResultset updateBlob AbstractMethodError gets me
lost. Any help is well appreciated.
By the way: the image is 18257 bytes and max_allowed_packet of MySQL
is 1048576
Anyone? thanx
###
stderr output ###
Exception in
thread "main" JAVA.lang.AbstractMethodError:
com.mysql.jdbc.UpdatableResultSet.updateBlob(LJAVA/lang/String;LJAVA/
io/InputStream;)V
at nl.vanleeuwenwilmot.housing.search.woonnet.app.Test.main(Test.JAVA:
52)
######### JAVA
class ###
package nl.vanleeuwenwilmot.housing.search.woonnet.app;
import JAVA.awt.BorderLayout;
import JAVA.awt.Image;
import JAVA.io.IOException;
import JAVA.io.InputStream;
import JAVA.net.
URL ;
import JAVA.sql.Connection;
import JAVA.sql.DriverManager;
import JAVA.sql.ResultSet;
import JAVA.sql.SQLException;
import JAVA.sql.Statement;
import JAVAx.imageio.ImageIO;
import JAVAx.swing.ImageIcon;
import JAVAx.swing.JFrame;
import JAVAx.swing.JLabel;
public class Test {
/**
* @xxxxxxxxxxx args
* @xxxxxxxxxxx IOException
* @xxxxxxxxxxx SQLException
*/
public static void main(String[] args) throws IOException,
SQLException {
Connection
con = null;
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
con = DriverManager.getConnection("jdbc:mysql:///woonnet",
"root",
"<A2Cc|4w");
} catch (InstantiationException e) {
e.printStackTrace();
System.exit(1);
} catch (IllegalAccessException e) {
e.printStackTrace();
System.exit(1);
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.exit(1);
}
Statement updatestmt =
con.createStatement(ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_UPDATABLE);
ResultSet resultset = updatestmt
.executeQuery("SELECT * FROM `image` WHERE `house_id`
= 1");
resultset.first();
// fine till here
resultset.updateBlob("image", new URL( // <====
line 52
"
http://www.woonnet-haaglanden.nl/library/fotos/
18/12845.jpg")
.openStream());
resultset.updateRow();
resultset.close();
updatestmt.close();
Statement readstmt = null;
readstmt =
con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
resultset = readstmt.executeQuery("SELECT * FROM `image` " //
+ "WHERE `house_id` = 1;");
resultset.first();
InputStream theimage =
resultset.getBlob("image").getBinaryStream();
Image image = ImageIO.read(theimage);
// Use a label to display the image
JFrame
frame = new JFrame();
JLabel label = new JLabel(new ImageIcon(image));
frame.getContentPane().add(label, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
}
######
| From: =?ISO-8859-1?Q?Arne_Vajh=F8j?= |
Date: Tuesday, October 02, 2007
|
wrote in message:
Googling for UpdatableResultset updateBlob AbstractMethodError gets me
lost. Any help is well appreciated.
### stderr output ###
Exception in thread "main" JAVA.lang.AbstractMethodError:
com.mysql.jdbc.UpdatableResultSet.updateBlob(LJAVA/lang/String;LJAVA/
io/InputStream;)V
at nl.vanleeuwenwilmot.housing.search.woonnet.app.Test.main(Test.JAVA:
52)
######
What
version of the MySQL
JDBC driver are you using ?
I suspect an old version that doesn't have this
method .
Arne
| From: Dyreatnews |
Date: Tuesday, October 02, 2007
|
"pjvleeuwen@xxxxxxxxxxx"
<pjvleeuwen@xxxxxxxxxxx> writes:
Hi all,
I'm quite new to all jdbc, but so far working with resultset's over
SQL seemed easy so far, but I'm having some problems writing a blob to
the database.
What I try to do is two steps:
1. read an image from the web and write it to a blob
2. read the blob and display it as an image
I did the same thing before without trying to write to the blob, but I
want to store the images in DB because the only stay on the web for a
couple of weeks.
Googling for UpdatableResultset updateBlob AbstractMethodError gets me
lost. Any help is well appreciated.
Why do you've to use an updatable result set to store the blob? Why
can not you use an ordnary update statment?
I do not know if MySQL supports updatable result sets with blobs, (it
probably does) but why make things more complicated than necessary...?
--
dt
| From: pjvleeuwen |
Date: Tuesday, October 02, 2007
|
Sorry for the late response, just back from diner.
Arne
What version of the MySQL JDBC driver are you using ?
<dependency>
<groupId>mysql
</groupId>
<artifactId>mysql-connector-java
</artifactId>
<version>5.0.3
</version>
</dependency>
And MySQL
monitor informed me that I have 5.0.26-community-nt...
Dt
Why do you've to use an updatable result set to store the blob? Why
can not you use an ordnary update statment?
Since I would not know the answer to that question I also tried the
following
PreparedStatement pstmt = con
.prepareStatement("INSERT INTO `image` (`house_id`,
`image`) "
+ "VALUES(1, ?)");
pstmt.setBlob(1, new URL( //
<===============line 51
"http://www.woonnet-haaglanden.nl/library/fotos/
18/12845.jpg")
.openStream());
pstmt.executeUpdate();
Exception in thread "main" JAVA.lang.AbstractMethodError:
com.mysql.jdbc.ServerPreparedStatement.setBlob(ILJAVA/io/
InputStream;)V
at nl.vanleeuwenwilmot.housing.search.woonnet.app.Test.main(Test.JAVA:
51)
And if I try setObject like the following I get no error at 51, but a
null-pointer exception after reading it.
public static void main(String[] args) throws IOException,
SQLException {
Connection con = null;
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
con = DriverManager.getConnection("jdbc:mysql:///woonnet",
"root",
"<A2Cc|4w");
} catch (InstantiationException e) {
e.printStackTrace();
System.exit(1);
} catch (IllegalAccessException e) {
e.printStackTrace();
System.exit(1);
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.exit(1);
}
PreparedStatement pstmt = con
.prepareStatement("INSERT INTO `image` (`house_id`,
`image`) "
+ "VALUES(1, ?)");
pstmt.setObject(1, new URL(
"http://www.woonnet-haaglanden.nl/library/fotos/
18/12845.jpg")
.openStream());
pstmt.executeUpdate();
Statement readstmt = null;
readstmt =
con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet resultset = readstmt.executeQuery("SELECT * FROM
`image` " //
+ "WHERE `house_id` = 1;");
resultset.first();
InputStream theimage =
resultset.getBlob("image").getBinaryStream();
Image image = ImageIO.read(theimage);
// Use a label to display the image
JFrame frame = new JFrame();
JLabel label = new JLabel(new ImageIcon(image)); // <=== line
69
frame.getContentPane().add(label, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
Exception in thread "main" JAVA.lang.NullPointerException
at JAVAx.swing.ImageIcon.<init>(ImageIcon.JAVA:161)
at nl.vanleeuwenwilmot.housing.search.woonnet.app.Test.main(Test.JAVA:
69)Further more I tried reading the inputstream to a
string (and play
ignorant on charset headaches), but I could not get that to work...
(furthermore, it does not seem the right way to go).
*Any* suggestions are warmly welcome. I stay tuned..
(oh and off topic suggestions on coding like dt.'s are also welcome,
there's just a lot that I do not know...)
| From: David Harper |
Date: Tuesday, October 02, 2007
|
wrote in message:
[SNIP]
### stderr output ###
Exception in thread "main" JAVA.lang.AbstractMethodError:
com.mysql.jdbc.UpdatableResultSet.updateBlob(LJAVA/lang/String;LJAVA/
io/InputStream;)V
at nl.vanleeuwenwilmot.housing.search.woonnet.app.Test.main(Test.JAVA:
52)
######
[SNIP]
The
Java API (
application program ming
int erface)documentation for JAVA.lang.AbstractMethodError explains:
public class AbstractMethodError
extends IncompatibleClassChangeError
Thrown when an application tries to call an abstract method. Normally,
this error is caught by the
compiler ; this error can only occur at
run
time if the definition of some class has incompatibly changed since
the currently executing method was last compiled.
This can happen if you've two versions of the Connector/J JAR
file ,
and you are using the newer one when compiling your
code but an older
version when running it. Check your compile-time and run-time
classpaths to ensure that they both
reference the newer version of the
JAR file.
David Harper
Cambridge, England
| From: pjvleeuwen |
Date: Tuesday, October 02, 2007
|
David
Thrown when an application tries to call an abstract method. Normally,
this error is caught by the compiler; this error can only occur at run
version when running it. Check your compile-time and run-time
classpaths to ensure that they both reference the newer version of the
JAR file.
Thanks, but I only *have* one version. I guess the MySQL Connection\J
guys felt that the next "*Normally* this error..." was optional. :)
$ ls -R .m2/repository/mysql/
.m2/repository/mysql/:
mysql-connector-JAVA
.m2/repository/mysql/mysql-connector-JAVA:
5.0.3
.m2/repository/mysql/mysql-connector-JAVA/5.0.3:
mysql-connector-JAVA-5.0.3.
jar mysql-connector-JAVA-5.0.3.jar.sha1
mysql-connector-JAVA-5.0.3.pom mysql-connector-JAVA-5.0.3.pom.sha1
| From: Lew |
Date: Tuesday, October 02, 2007
|
wrote in message:
ResultSet.TYPE_FORWARD_ONLY,
...
resultset.first();
<
http://JAVA.sun.com/JAVAse/6/docs/api/JAVA/sql/ResultSet.html#first()>
Returns:
true if the cursor is on a valid row; false if there are no rows in the result set
You do not check the return code. This might not matter here, but you should
be aware of it.
Throws:
SQLException - if ... this method is called on a ... result set type ... TYPE_FORWARD_ONLY
Which is what you typed your ResultSet.
PreparedStatement pstmt = con
.prepareStatement("INSERT INTO `image` (`house_id`,
`image`) "
+ "VALUES(1, ?)");
pstmt.setBlob(1, new URL( // <===============line 51
"http://www.woonnet-haaglanden.nl/library/fotos/18/12845.jpg" )
.openStream());
pstmt.executeUpdate();
Exception in thread "main" JAVA.lang.AbstractMethodError:
com.mysql.jdbc.ServerPreparedStatement.setBlob(ILJAVA/io/
InputStream;)V
at nl.vanleeuwenwilmot.housing.search.woonnet.app.Test.main(Test.JAVA:
51)
This is pretty much the same error you got with the ResultSet.
And if I try setObject like the following I get no error at 51, but a
null-pointer exception after reading it.
public static void main(String[] args) throws IOException,
SQLException {
Connection con = null;
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
You do not need the newInstance(). You could also do the forName() call in a
static initializer.
...
PreparedStatement pstmt = con
.prepareStatement("INSERT INTO `image` (`house_id`,
`image`) "
+ "VALUES(1, ?)");
pstmt.setObject(1, new URL(
"http://www.woonnet-haaglanden.nl/library/fotos/18/12845.jpg")
.openStream());
pstmt.executeUpdate();
Statement readstmt = null;
readstmt =
con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet resultset = readstmt.executeQuery("SELECT * FROM
`image` " //
+ "WHERE `house_id` = 1;");
resultset.first();
This time it's with a ResultSet.TYPE_SCROLL_INSENSITIVE, but you still should
consider using next() instead, and you must check the return code!
InputStream theimage =
resultset.getBlob("image").getBinaryStream();
Image image = ImageIO.read(theimage);
// Use a label to display the image
JFrame frame = new JFrame();
JLabel label = new JLabel(new ImageIcon(image)); // <=== line
69
frame.getContentPane().add(label, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
Exception in thread "main" JAVA.lang.NullPointerException
at JAVAx.swing.ImageIcon.<init>(ImageIcon.JAVA:161)
at nl.vanleeuwenwilmot.housing.search.woonnet.app.Test.main(Test.JAVA:
69)
Further more I tried reading the inputstream
That's "InputStream".
to a string (and playignorant on charset headaches), but I could not get that to work...
(furthermore, it does not seem the right way to go).
It is not, but byte[]'d be all right.
The AbstractMethodError only occurs if the implementing class for the abstract
call isn't available or incompatible at run time. Something is not finding
the MySQL-specific implementation of these methods. I'd review how you've
the MySQL JAR located in your classpath.
It's a weird one, because a classpath issue shows up at compile time, or worst
case, at runtime when the Class.forName() fails. How you could get to the
MySQL Driver class and not have access to its implementation classes is a mystery.
There's a clue, however, at the MySQL web site:
<http://dev.mysql.com/doc/refman/5.0/en/connector-j-installing-classpath.html>
where the tell you to put the JAR
mysql-connector-JAVA-[version]-bin.jar
in your classpath, but you have got
mysql-connector-JAVA-5.0.3.jar
I
download ed the latest Connector/J (version 5.0.7) and there was only the
*-bin.jar version, not the version without the "-bin".
--
Lew
| From: David Harper |
Date: Wednesday, October 03, 2007
|
wrote in message:
David
Thrown when an application tries to call an abstract method. Normally,
this error is caught by the compiler; this error can only occur at run
version when running it. Check your compile-time and run-time
classpaths to ensure that they both reference the newer version of the
JAR file.
Thanks, but I only *have* one version. I guess the MySQL Connection\J
guys felt that the next "*Normally* this error..." was optional. :)
I suspect that I was not thinking clearly last night. Sorry. Here's a
more likely explanation.
Your code never refers directly to the concrete implementation classes
in the Connector/J JAR file (such as com.mysql.jdbc.Driver) but only to
the classes (actually, mostly interfaces, like JAVA.sql.Driver) in
JAVA.sql.* and JAVAx.sql.*
Therefore, your compiler will have no reason to check any of the classes
in the Connector/J JAR file, and the abstract method problem isn't
detected at compile time. Remember that JAVA.sql.ResultSet, like
JAVA.sql.Driver, is an interface, not a class.
You only
hit the abstract method problem when you actually run your
code, and the JAVA
virtual machine needs to
load the concrete classes
such as com.mysql.jdbc.Driver, which implements the JAVA.sql.Driver
interface.
When your program reaches the call to ResultSet.updateBlob at line 52,
the
JVM attempts to call the method updateBlob on a concrete
com.mysql.jdbc.UpdatableResultSet object. That method is apparently
abstract, and you get the mysterious AbstractMethodError.
I hope this makes better sense :-)
David Harper
Cambridge, England
| From: pjvleeuwen |
Date: Wednesday, October 03, 2007
|
David
When your program reaches the call to ResultSet.updateBlob at line 52,
the JVM attempts to call the method updateBlob on a concrete
com.mysql.jdbc.UpdatableResultSet object. That method is apparently
abstract, and you get the mysterious AbstractMethodError.
So MySQL Connector/J does not implement any code for handling blobs
here. Makes the most sence to me. Forget about the nice blob interface
then.
Lew
> to a string (and playignorant on charset headaches), but I could not get that to work...
> (furthermore, it does not seem the right way to go).
It is not, but byte[]'d be all right.
You are very right there. I liked the Blob's because they work with
streams, but the following code below works! With byte[].I will just wrap it in an URL2Bytes utility class and all is done.
Thanks for all your tips! Ciao
public static void main(String[] args)
throws MalformedURLException,
IOException, SQLException {
// download photo to byte[]
URL fileurl = new URL(
"
http://www.woonnet-haaglanden.nl/"
+ "library/fotos/18/12845.jpg");
int length = fileurl.openConnection()
.getContentLength();
byte[] bytebuf = new byte[length];
InputStream is = fileurl.openStream();
byte[] b = new byte[1];
for (int I = 0; is.read(b) > -1; i++) {
bytebuf[i] = b[0];
}
// write to DB
Connection con = null;
try {
Class
.forName(
"com.mysql.jdbc.Driver")
.newInstance();
con = DriverManager.getConnection(
"jdbc:mysql:///woonnet",
"root", "<A2Cc|4w");
} catch (InstantiationException e) {
e.printStackTrace();
System.exit(1);
} catch (IllegalAccessException e) {
e.printStackTrace();
System.exit(1);
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.exit(1);
}
PreparedStatement pstmt = con
.prepareStatement("INSERT INTO `image` "
+ "(`house_id`, `image`) "
+ "VALUES(4, ?)");
pstmt.setBytes(1, bytebuf);
pstmt.executeUpdate();
// read from DB
Statement readstmt = con
.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet resultset = readstmt
.executeQuery("SELECT * FROM `image` " //
+ "WHERE `house_id` = 4;");
resultset.first();
byte[] readbytes = resultset
.getBytes("image");
Image image = ImageIO
.read(new ByteArrayInputStream(
readbytes));
// Use a label to display the image
JFrame frame = new JFrame();
JLabel label = new JLabel(new ImageIcon(
image));
frame.getContentPane().add(label,
BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
| From: Lew |
Date: Wednesday, October 03, 2007
|
wrote in message:
public static void main(String[] args)
throws MalformedURLException,
IOException, SQLException {
...
// write to DB
Connection con = null;
try {
Class
.forName(
"com.mysql.jdbc.Driver")
.newInstance();
Why are you creating a throwaway
instance here?
--
Lew
| From: Lew |
Date: Wednesday, October 03, 2007
|
wrote in message:
PreparedStatement pstmt = con
.prepareStatement("INSERT INTO `image` "
+ "(`house_id`, `image`) "
+ "VALUES(4, ?)");
Remember, prepareStatement() "[t]hrows ... SQLException ... if a database
access error occurs or this method is called on a closed connection."
pstmt.executeUpdate();
This method call returns a value that you shouldn't ignore, nor should you
ignore the possible SQLException.
// read from DB
Statement readstmt = con
.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
"Throws ... SQLException ... if a database access error occurs or this method
is called on a closed connection"
ResultSet resultset = readstmt
.executeQuery("SELECT * FROM `image` " //
+ "WHERE `house_id` = 4;");
possible SQLException
resultset.first();
Why not call next(), and why, oh, why do you disregard the returned value?
--
Lew
| From: =?UTF-8?B?QXJuZSBWYWpow7hq?= |
Date: Thursday, October 04, 2007
|
wrote in message:
wrote in message:
public static void main(String[] args)
throws MalformedURLException,
IOException, SQLException {
...
// write to DB
Connection con = null;
try {
Class
.forName(
"com.mysql.jdbc.Driver")
.newInstance();
Why are you creating a throwaway instance here?
That is a common practice when loading the MySQL JDBC
driver.
My guess is that some very old version of the driver
register ed itself with DriverManager in the constructor,
so that it was necessary.
It isn't necessary today and hasn't been for many years,
but you'll see that code all the time.
The MySQL docs even use it even though they blame JAVA:
<quote>
Example 3.1. Registering the Driver With the DriverManager
The following section of JAVA code shows how you might register MySQL
Connector/J from the main() method of your application.
import JAVA.sql.Connection;
import JAVA.sql.DriverManager;
import JAVA.sql.SQLException;
// Notice, don't import com.mysql.jdbc.*
// or you'll have problems!
public class LoadDriver {
public static void main(String[] args) {
try {
// The newInstance() call is a work around for some
//
broken JAVA implementations
Class.forName("com.mysql.jdbc.Driver").newInstance();
} catch (Exception ex) {
//
handle the error
}
</quote>
Arne
Next Message: [Aaron J Tarter] Re: [comp.lang.JAVA.databases] Derby eclipse install