在 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,但它从未进入规范。因此无法以 standard 和 portable(在每个 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)
我想使用 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,但它从未进入规范。因此无法以 standard 和 portable(在每个 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)