2

I just upgraded mysql jdbc connection JAR (from mysql-connector-java-5.0.5.jar to mysql-connector-java-8.0.19.jar) and the project started showing error for import statements:

import com.mysql.jdbc.PreparedStatement;

java: cannot find symbol
  symbol:   class PreparedStatement
  location: class package.ClassName 

Where to find the location or package for PreparedStatement in new jar file or is it replaced with any other class in new JAR?

enter image description here

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Krunal
  • 77,632
  • 48
  • 245
  • 261
  • Do you mean [`java.sql.PreparedStatement`](https://docs.oracle.com/javase/8/docs/api/java/sql/PreparedStatement.html)? – khelwood Aug 04 '20 at 10:55
  • @khelwood - Could you please help to understand? Do you mean `import com.mysql.jdbc.*` is now repalced with `import java.sql.*` with new JAR files? (I'm not a professional Java developer, so not much aware about this package changes.) – Krunal Aug 04 '20 at 10:58
  • 1
    No, I mean the only `PreparedStatement` type in Java I've ever had to use is `java.sql.PreparedStatement`, and maybe that was the type you were looking for. – khelwood Aug 04 '20 at 10:59
  • 1
    Actully I've `import com.mysql.jdbc.PreparedStatement;` in my project, which was working fine until I upgraded JDBC connection jar file to `mysql-connector-java-8.0.21.jar`. What can be it's resolution – Krunal Aug 04 '20 at 11:01
  • 2
    It was perhaps a mistake to `import com.mysql.jdbc.PreparedStatement` - when working with JDBC, you usually only code against the `java.sql` interfaces. – Gyro Gearless Aug 04 '20 at 11:06
  • @GyroGearless - Thank you for clarification.. The project source code I've is around 7-8 years old, which we are upgrading. – Krunal Aug 04 '20 at 11:13

2 Answers2

4

com.mysql.jdbc.PreparedStatement is an internal class to the MySQL 5.x JDBC driver. Your code should not import it. It should be using the standard java.sql.PreparedStatement class instead.

The package names have changed in the MySQL 8.x JDBC drivers, and that is what caused your code to start giving compilation errors.

Solution:

  1. Fix your code so that it doesn't import any MySQL implementation classes1. Use the java.sql.* and javax.sql.* class instead.

  2. Change your project dependencies so that the MySQL driver JAR is not a compile-time dependency. Doing that will cause any accidental source code dependencies on JDBC drivers to be flagged as compilation errors. It will also stop your IDE from making incorrect suggestions for import statements. (My guess is that that is how the bogus import got into your codebase.)

  3. If your code is (still) using Class.forName to load the JDBC driver, change it to use java.sql.DriverManager instead; see javadoc. That way you won't be burned by another change in the MySQL driver class name.


1 - Your Java code should not need to depend on MySQL-specific APIs. As far as I know, the MySQL implementation classes mirror the standard JDBC APIs, so you gain nothing by using them directly. This is not true for all vendors.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • In general you are right, but sometimes using the implementation specific classes or interfaces may be necessary to access features not specified in JDBC (vendor-specific extensions). – Mark Rotteveel Aug 04 '20 at 11:42
  • I don't think that is true for MySQL. I recall that (ahem) some old Oracle JDBC drivers required you to do that kind of thing. Maybe Postgres too. – Stephen C Aug 04 '20 at 11:48
  • MySQL doesn't have many of them, but for example you might want to cast or unwrap to `com.mysql.cj.jdbc.JdbcStatement` to access the `setLocalInfileInputStream` method. And the `JdbcConnection` interface contains some methods that are - I think - primarily for internal use, but may be helpful in some cases. – Mark Rotteveel Aug 04 '20 at 11:55
3

Try to replace it with:

import java.sql.PreparedStatement;

Using com.mysql.jdbc.PreparedStatement is specific to mysql, and should not be imported directly.

So unless you need MySQL specific features, it's always better to use the interface java.sql.PreparedStatement that is database independent. See also this.

Marc
  • 2,738
  • 1
  • 17
  • 21
  • So do you mean import com.mysql.jdbc.* is now replaced with import java.sql.* with new JAR file mysql-connector-java-8.0.21.jar? – Krunal Aug 04 '20 at 11:03
  • 1
    @Krunal It has always been better to import the `java.sql.*` interfaces instead of the MySQL implementation classes, you're now just confronted with this previous mistake to import the wrong class because MySQL moved and renamed a lot of the implementation classes in MySQL Connector/J. – Mark Rotteveel Aug 04 '20 at 11:40