在 Wildfly 18 中使用 OS 系统变量作为 @DataSourceDefinition 密码失败

Using OS system variable for @DataSourceDefinition password failed in Wildfly 18

我想使用 OS 系统变量 ${appuserpwd} 外部化 Java @DataSourceDefinition 的密码。下面是我的@DataSourceDefinition

@DataSourceDefinition(
    name = "java:app/jdbc/mydb", 
    className = "com.mysql.cj.jdbc.MysqlConnectionPoolDataSource", 
    portNumber = 3306, 
    serverName = "localhost", 
    databaseName = "mydb", 
    user = "appuser", 
    password = "${appuserpwd}", 
    isolationLevel = Connection.TRANSACTION_READ_COMMITTED, 
    properties = {})

我正在使用 Wildfly 18。在子系统 ee 中,我已经打开了这些属性:

Annotation Property Replacement:  ON
JBoss Descriptor Property Replacement:  ON
Spec Descriptor Property Replacement:  ON

我总是收到如下异常错误:

Caused by: java.sql.SQLException: Access denied for user 'appuser'@'localhost' (using password: YES)

这意味着 Wildfly 无法将 ${appuserpwd} 从名为 appuserpwd 的 OS 系统环境转换为真实密码。

我已经尝试 ${env.appuserpwd} 获取@DataSourceDefinition 密码,但我收到了相同的消息。

如果我将 ${appuserpwd} 替换为应用用户的真实密码 -> 应用运行正常,没有问题。

有帮助吗?谢谢!

有一个 Java EE 7 规范提案支持 password aliasing,但它从未进入规范。因此无法以 standardportable(在每个 Java EE 兼容服务器上工作)方式替换变量。

幸运的是,不同的应用服务器提供了自己的解决方案来实现这一点。

对于 Wildfly,您必须首先在 standalone.xml:

中启用注释 属性 替换
<subsystem xmlns="urn:jboss:domain:ee:5.0">
    <annotation-property-replacement>true</annotation-property-replacement>
</subsystem>

现在可以开始替换变量了(语法是${ENV_VARIABLE:default}):

@DataSourceDefinition(
    name = "java:app/jdbc/pqsql",
    className = "org.postgresql.xa.PGXADataSource",
    user = "${DB_USER:postgres}",
    password = "${DB_PASSWORD:password}",
    serverName = "${DB_SERVERNAME:localhost}",
    portNumber = 5432,
    databaseName = "${DB_DATABASENAME:testdatabase}")

您可以找到更多信息 here

更新:我tried this with a recent Wildfly version (20.0.0.Final) and it seems there is a bug when replacing annotation variables. As a fallback you can use the traditional way of specifying the datasource using the Jboss CLI and use environment variables as expected

# First create the new module for the JDBC driver
/subsystem=datasources/jdbc-driver=postgresql:add(driver-name=postgresql, driver-module-name=org.postgresql, driver-class-name=org.postgresql.Driver, driver-datasource-class-name=org.postgresql.ds.PGPoolingDataSource)
 
# Create a data source
/subsystem=datasources/data-source=PostgresDS:add(jndi-name=java:jboss/datasources/postgres, driver-name=postgresql, connection-url=jdbc:postgresl://localhost:5432/postgres, user-name=postgres, password=postgres)