GraalVM 本机图像和 Oracle ojdbc11-21.1
GraalVM native-image and Oracle ojdbc11-21.1
我目前正在试验来自 GraalVM 的本机映像工具和 Oracle 驱动程序。源码编译生成exe文件,没有错误。但是当我启动程序时,它得到一个java.lang.RuntimeException:图像构建时未加载缺少的字符集 id 170。
我正在连接到字符集 NLS_CHARACTERSET = EE8MSWIN1250 的数据库。
当我使用 NLS_CHARACTERSET = AL32UTF8 的数据库时,连接工作正常。
我正在 Windows 10 64 位计算机上使用 GraalVM CE 21.0.0.2(构建 11.0.10+8-jvmci-21.0-b06 和 ojdbc11-21.1.0。0.jar。
错误信息和源代码如下。我使用了 https://github.com/oracle/oracle-db-examples/blob/master/java/jdbc/ConnectionSamples/DataSourceSample.java
中的示例代码
Exception in thread "main" java.lang.RuntimeException: Missing character set id 170 not loaded at image build time at oracle.sql.CharacterSet.make(CharacterSet.java:121) at oracle.jdbc.driver.DBConversion.init(DBConversion.java:184) at oracle.jdbc.driver.DBConversion.(DBConversion.java:137) at oracle.jdbc.driver.T4CConnection.doCharSetNegotiation(T4CConnection.java:2607) at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:2176) at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:644) at oracle.jdbc.driver.PhysicalConnection.connect(PhysicalConnection.java:1069) at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:90) at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:681) at oracle.jdbc.datasource.impl.OracleDataSource.getPhysicalConnection(OracleDataSource.java:569) at oracle.jdbc.datasource.impl.OracleDataSource.getConnection(OracleDataSource.java:355) at oracle.jdbc.datasource.impl.OracleDataSource.getConnectionInternal(OracleDataSource.java:2014) at oracle.jdbc.datasource.impl.OracleDataSource.getConnection(OracleDataSource.java:330) at oracle.jdbc.datasource.impl.OracleDataSource.getConnection(OracleDataSource.java:291) at DataSourceSample.main(DataSourceSample.java:24)
DataSourceSample.java
/* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.*/
import java.sql.SQLException;
import java.util.Properties;
import oracle.jdbc.pool.OracleDataSource;
import oracle.jdbc.OracleConnection;
import java.sql.DatabaseMetaData;
public class DataSourceSample {
final static String DB_URL= "jdbc:oracle:thin:@****:1525/****";
final static String DB_USER = "****";
final static String DB_PASSWORD = "****";
public static void main(String args[]) throws SQLException {
Properties info = new Properties();
info.put(OracleConnection.CONNECTION_PROPERTY_USER_NAME, DB_USER);
info.put(OracleConnection.CONNECTION_PROPERTY_PASSWORD, DB_PASSWORD);
info.put(OracleConnection.CONNECTION_PROPERTY_DEFAULT_ROW_PREFETCH, "20");
OracleDataSource ods = new OracleDataSource();
ods.setURL(DB_URL);
ods.setConnectionProperties(info);
try (OracleConnection connection = (OracleConnection) ods.getConnection()) {
DatabaseMetaData dbmd = connection.getMetaData();
System.out.println("Driver Name: " + dbmd.getDriverName());
System.out.println("Driver Version: " + dbmd.getDriverVersion());
System.out.println("Default Row Prefetch Value is: " +
connection.getDefaultRowPrefetch());
System.out.println("Database Username is: " + connection.getUserName());
System.out.println();
}
}
}
我不是 100% 确定它是罪魁祸首,但这是关于原生图像和字符集的一般想法。
默认情况下本机图像不包含所有可能的字符集,您可以使用以下选项对其进行配置:
-H:+AddAllCharsets
另一种可能的选择是在 class 中初始化 CharSet onject,该对象配置为在构建本机映像时初始化。然后这个charset对象会被保存在“image heap”中,运行时可用
下面是一个说明此行为的示例应用程序:https://github.com/shelajev/workshop/tree/main/3
当然可能会有所不同,但我认为这应该可以解决您遇到的问题。
我目前正在试验来自 GraalVM 的本机映像工具和 Oracle 驱动程序。源码编译生成exe文件,没有错误。但是当我启动程序时,它得到一个java.lang.RuntimeException:图像构建时未加载缺少的字符集 id 170。
我正在连接到字符集 NLS_CHARACTERSET = EE8MSWIN1250 的数据库。 当我使用 NLS_CHARACTERSET = AL32UTF8 的数据库时,连接工作正常。
我正在 Windows 10 64 位计算机上使用 GraalVM CE 21.0.0.2(构建 11.0.10+8-jvmci-21.0-b06 和 ojdbc11-21.1.0。0.jar。
错误信息和源代码如下。我使用了 https://github.com/oracle/oracle-db-examples/blob/master/java/jdbc/ConnectionSamples/DataSourceSample.java
中的示例代码Exception in thread "main" java.lang.RuntimeException: Missing character set id 170 not loaded at image build time at oracle.sql.CharacterSet.make(CharacterSet.java:121) at oracle.jdbc.driver.DBConversion.init(DBConversion.java:184) at oracle.jdbc.driver.DBConversion.(DBConversion.java:137) at oracle.jdbc.driver.T4CConnection.doCharSetNegotiation(T4CConnection.java:2607) at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:2176) at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:644) at oracle.jdbc.driver.PhysicalConnection.connect(PhysicalConnection.java:1069) at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:90) at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:681) at oracle.jdbc.datasource.impl.OracleDataSource.getPhysicalConnection(OracleDataSource.java:569) at oracle.jdbc.datasource.impl.OracleDataSource.getConnection(OracleDataSource.java:355) at oracle.jdbc.datasource.impl.OracleDataSource.getConnectionInternal(OracleDataSource.java:2014) at oracle.jdbc.datasource.impl.OracleDataSource.getConnection(OracleDataSource.java:330) at oracle.jdbc.datasource.impl.OracleDataSource.getConnection(OracleDataSource.java:291) at DataSourceSample.main(DataSourceSample.java:24)
DataSourceSample.java
/* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.*/
import java.sql.SQLException;
import java.util.Properties;
import oracle.jdbc.pool.OracleDataSource;
import oracle.jdbc.OracleConnection;
import java.sql.DatabaseMetaData;
public class DataSourceSample {
final static String DB_URL= "jdbc:oracle:thin:@****:1525/****";
final static String DB_USER = "****";
final static String DB_PASSWORD = "****";
public static void main(String args[]) throws SQLException {
Properties info = new Properties();
info.put(OracleConnection.CONNECTION_PROPERTY_USER_NAME, DB_USER);
info.put(OracleConnection.CONNECTION_PROPERTY_PASSWORD, DB_PASSWORD);
info.put(OracleConnection.CONNECTION_PROPERTY_DEFAULT_ROW_PREFETCH, "20");
OracleDataSource ods = new OracleDataSource();
ods.setURL(DB_URL);
ods.setConnectionProperties(info);
try (OracleConnection connection = (OracleConnection) ods.getConnection()) {
DatabaseMetaData dbmd = connection.getMetaData();
System.out.println("Driver Name: " + dbmd.getDriverName());
System.out.println("Driver Version: " + dbmd.getDriverVersion());
System.out.println("Default Row Prefetch Value is: " +
connection.getDefaultRowPrefetch());
System.out.println("Database Username is: " + connection.getUserName());
System.out.println();
}
}
}
我不是 100% 确定它是罪魁祸首,但这是关于原生图像和字符集的一般想法。
默认情况下本机图像不包含所有可能的字符集,您可以使用以下选项对其进行配置:
-H:+AddAllCharsets
另一种可能的选择是在 class 中初始化 CharSet onject,该对象配置为在构建本机映像时初始化。然后这个charset对象会被保存在“image heap”中,运行时可用
下面是一个说明此行为的示例应用程序:https://github.com/shelajev/workshop/tree/main/3
当然可能会有所不同,但我认为这应该可以解决您遇到的问题。