Bug #117620 NumberFormatException in JDBC

Submitted: 5 Mar 2025 3:20 Modified: 5 Mar 2025 7:50
Reporter: chi zhang (OCA) Email Updates:
Status: Duplicate Impact on me:
None 
Category:Connector / J Severity:S3 (Non-critical)
Version:9.2.0 OS:Any
Assigned to: CPU Architecture:Any

[5 Mar 2025 3:20] chi zhang
Description:
The following test case triggered a java.lang.NumberFormatException in JDBC driver:
```
DROP DATABASE IF EXISTS database6;
CREATE DATABASE database6;
USE database6;
CREATE TABLE t0(c0 FLOAT ZEROFILL) ;
INSERT INTO t0(c0) VALUES("-0.0");
SELECT t0.c0 FROM t0;
```

When I run it in command line, I get the following outputs:
```
mysql> DROP DATABASE IF EXISTS database6;
Query OK, 1 row affected (0.24 sec)

mysql> CREATE DATABASE database6;
Query OK, 1 row affected (0.07 sec)

mysql> USE database6;
Database changed, 1 warning
mysql> CREATE TABLE t0(c0 FLOAT ZEROFILL) ;
Query OK, 0 rows affected, 1 warning (0.20 sec)

mysql> INSERT INTO t0(c0) VALUES("-0.0");
Query OK, 1 row affected (0.06 sec)

mysql> SELECT t0.c0 FROM t0;
+--------------+
| c0           |
+--------------+
| 0000000000-0 |
+--------------+
1 row in set (0.00 sec)
```

But when I run it with a harness, it triggers an exception. This is the outputs:
```
Connect ...
Connect success.
Query: DROP DATABASE IF EXISTS database6;
Query: CREATE DATABASE database6;
Query: USE database6;
Query: CREATE TABLE t0(c0 FLOAT ZEROFILL) ;
Query: INSERT INTO t0(c0) VALUES("-0.0");
Query: SELECT t0.c0 FROM t0;
For input string: "0000000000-0"
java.lang.NumberFormatException: For input string: "0000000000-0"
        at java.base/jdk.internal.math.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2054)
        at java.base/jdk.internal.math.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
        at java.base/java.lang.Double.parseDouble(Double.java:543)
        at com.mysql.cj.protocol.a.MysqlTextValueDecoder.getDouble(MysqlTextValueDecoder.java:249)
        at com.mysql.cj.protocol.a.MysqlTextValueDecoder.decodeDouble(MysqlTextValueDecoder.java:134)
        at com.mysql.cj.protocol.a.MysqlTextValueDecoder.decodeFloat(MysqlTextValueDecoder.java:130)
        at com.mysql.cj.protocol.result.AbstractResultsetRow.decodeAndCreateReturnValue(AbstractResultsetRow.java:116)
        at com.mysql.cj.protocol.result.AbstractResultsetRow.getValueFromBytes(AbstractResultsetRow.java:243)
        at com.mysql.cj.protocol.a.result.ByteArrayRow.getValue(ByteArrayRow.java:91)
        at com.mysql.cj.jdbc.result.ResultSetImpl.getObject(ResultSetImpl.java:1334)
        at com.mysql.cj.jdbc.result.ResultSetImpl.getFloat(ResultSetImpl.java:819)
        at com.mysql.cj.jdbc.result.ResultSetImpl.getObject(ResultSetImpl.java:1207)
        at reproduce_mysql$MySQLHandle.batchDate(reproduce_mysql.java:80)
        at reproduce_mysql$MySQLHandle.runSqlByReadFileContent(reproduce_mysql.java:144)
        at reproduce_mysql.main(reproduce_mysql.java:24)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at jdk.compiler/com.sun.tools.javac.launcher.Main.execute(Main.java:404)
        at jdk.compiler/com.sun.tools.javac.launcher.Main.run(Main.java:179)
        at jdk.compiler/com.sun.tools.javac.launcher.Main.main(Main.java:119)
```

How to repeat:
This is the harness:
```
```
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;

import java.text.SimpleDateFormat;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.IOException;

public class reproduce_mysql {
    public static void main(String[] args) throws Exception {
        MySQLHandle sh = new MySQLHandle();
        try {
            sh.runSqlByReadFileContent(args[0]);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sh.ReleaseConnect();
        }
    }

    static class MySQLHandle {
        private Connection connection;

        String host = "127.0.0.1";
        int port = 3306;
        String username = "root";
        String password = "123456";
        String url = String.format("jdbc:mysql://%s:%d?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true", host, port);

        public MySQLHandle(){
            try {
                System.out.println("Connect ...");
                connection = DriverManager.getConnection(url, username, password);
                System.out.println("Connect success.");
            } catch (Exception e) {
                e.printStackTrace();
                connection = null;
            }
        }

        public Connection getConnection(){
            return connection;
        }

        public void ReleaseConnect(){
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }

        public int batchDate(ArrayList<String> sql){
            try (Statement statement = connection.createStatement()){
                for(String script: sql) {
                    if (script.startsWith("--")) {
                        continue;
                    }
                    System.out.println("Query: " + script);
                    if (script.startsWith("SELECT") || script.startsWith("WITH")) {
                        try (ResultSet rs = statement.executeQuery(script)) {
                            ResultSetMetaData metaData = rs.getMetaData();
                            Integer columnCount = metaData.getColumnCount();
                            while (rs.next()) {
                                for (int i = 1; i <= columnCount; i++) {
                                    try {
                                        Object value = rs.getObject(i);
                                    } catch (Exception e) {
                                        System.out.println(e.getMessage());
                                        e.printStackTrace();
                                        System.exit(0);
                                    }
                                }
                            }
                        } catch(Exception e) {
                            System.out.println(e.getMessage());
                            e.printStackTrace();
                            System.exit(0);
                        }
                        
                        
                    } else {
                        try {
                            statement.execute(script);
                        } catch (Exception e) {
                            System.out.println("Error Query: " + script);
                        }
                    }
                }
                return 1;
            }catch (Exception e) {
                e.printStackTrace();
                return 0;
            }
        }

        private ArrayList<String> readFileByLines(String filePath) throws Exception {
            ArrayList<String> listStr=new ArrayList<>();
            BufferedReader reader = null;
            try {
                reader = new BufferedReader(new InputStreamReader(
                        new FileInputStream(filePath), "UTF-8"));
                String tempString = null;
                while ((tempString = reader.readLine()) != null) {
                    if(tempString.trim().equals(""))
                        continue;
                    if(tempString.startsWith("--"))
                        continue;
                    listStr.add(tempString);
                }
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
                throw e;
            } finally {
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (IOException e1) {
                    }
                }
            }

            return listStr;
        }

        public void runSqlByReadFileContent(String sqlPath){
            try {
                ArrayList<String> sqlStr = readFileByLines(sqlPath);
                if (sqlStr.size() > 0) {
                    int num=batchDate(sqlStr);
                    if(num>0)
                        System.out.println("success!");
                    else
                        System.out.println("failed!");
                }
                else{
                    System.out.println("no sql statements!");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

```
```
I run the MySQL in docker with version `Server version: 9.1.0 MySQL Community Server - GPL`
I use the jdbc driver 8.0.30
I reproduce the exception with the following command:
```
java -cp ~/.m2/repository/mysql/mysql-connector-java/8.0.30/mysql-connector-java-8.0.30.jar ./reproduce_mysql.java database6-reduce.sql
```
[5 Mar 2025 7:44] MySQL Verification Team
Hello chi zhang,

Thank you for the report and test case.
Verified as described.

regards,
Umesh
[5 Mar 2025 7:45] MySQL Verification Team
-- C/J 9.2.0, Server version: 9.2.0 MySQL Community Server - GPL

java -cp mysql-connector-j-9.2.0/mysql-connector-j-9.2.0.jar ./Reproduce_mysql.java database-reduce.sql
Connect ...
Connect success.
Query: CREATE DATABASE database6;
Query: USE database6;
Query: CREATE TABLE t0(c0 FLOAT ZEROFILL) ;
Query: INSERT INTO t0(c0) VALUES("-0.0");
Query: SELECT t0.c0 FROM t0;
For input string: "0000000000-0"
java.lang.NumberFormatException: For input string: "0000000000-0"
	at java.base/jdk.internal.math.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2054)
	at java.base/jdk.internal.math.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
	at java.base/java.lang.Double.parseDouble(Double.java:651)
	at com.mysql.cj.protocol.a.MysqlTextValueDecoder.getDouble(MysqlTextValueDecoder.java:258)
	at com.mysql.cj.protocol.a.MysqlTextValueDecoder.decodeDouble(MysqlTextValueDecoder.java:140)
	at com.mysql.cj.protocol.a.MysqlTextValueDecoder.decodeFloat(MysqlTextValueDecoder.java:135)
	at com.mysql.cj.protocol.result.AbstractResultsetRow.decodeAndCreateReturnValue(AbstractResultsetRow.java:108)
	at com.mysql.cj.protocol.result.AbstractResultsetRow.getValueFromBytes(AbstractResultsetRow.java:235)
	at com.mysql.cj.protocol.a.result.ByteArrayRow.getValue(ByteArrayRow.java:82)
	at com.mysql.cj.jdbc.result.ResultSetImpl.getObject(ResultSetImpl.java:1316)
	at com.mysql.cj.jdbc.result.ResultSetImpl.getFloat(ResultSetImpl.java:841)
	at com.mysql.cj.jdbc.result.ResultSetImpl.getObject(ResultSetImpl.java:1218)
	at Reproduce_mysql$MySQLHandle.batchDate(Reproduce_mysql.java:79)
	at Reproduce_mysql$MySQLHandle.runSqlByReadFileContent(Reproduce_mysql.java:143)
	at Reproduce_mysql.main(Reproduce_mysql.java:23)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
	at jdk.compiler/com.sun.tools.javac.launcher.Main.execute(Main.java:419)
	at jdk.compiler/com.sun.tools.javac.launcher.Main.run(Main.java:192)
	at jdk.compiler/com.sun.tools.javac.launcher.Main.main(Main.java:132)
[5 Mar 2025 7:50] MySQL Verification Team
IMHO this is duplicate of Bug #114533 JDBC exception java.lang.NumberFormatException, which is marked as won't fix and issue is with the server per developer's last note

[8 Jul 2024 13:01] Filipe Silva
Not a bug in MySQL Connector/J. Related to MySQL Server Bug#115493.

Bug#115493 is private hence not visible at the moment.

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.057 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.