【问题标题】:Sharing database connection with an external program与外部程序共享数据库连接
【发布时间】:2026-01-04 09:00:02
【问题描述】:

我们在 Web 容器 (WildFly 14) 中启动了应用程序 Foo。它通过 JNDI 以标准方式获取数据库连接。因此,连接不是在应用程序内部配置的,而是在 WildFly 中配置的。

现在,Foo 在同一台机器上启动了一个外部程序 Bar。这个外部程序完全独立于主应用程序,但需要访问相同的数据库。 Bar 也是通过管道连接到 Foo 的,因此将可序列化的对象从一个传递到另一个是没有问题的。

通过简单的实现,我需要单独配置 Bar 对数据库的访问权限,而不是 Foo

是否有可能自动将必要的数据库连接参数从 Foo 传递到 Bar?由于我们使用两种不同类型的数据库,这也将包括 JDBC 驱动程序(Foo 从 WildFly 部署中“免费”获取)。加上 JDBC URL、用户名和密码。自动确定其中的一些也会有所帮助。

我们控制并可以更改此设置中的几乎所有内容(FooBar 来源,WildFly 配置)。

【问题讨论】:

  • 为什么您的外部应用程序也不使用 JNDI 来获取数据源(来自 Wildfly 服务器)? DataSource datasource =(DataSource)initialContext.lookup("java:comp/env/jdbc/demo");
  • 因为它作为一个单独的进程运行并且无权访问 WildFly。
  • 你的进程,即使是独立的,只需要访问..网络。您的应用程序将包含一个 JNDI 客户端,该客户端通过网络查找远程 JNDI 服务器。属性 jndiProperties = new Properties(); jndiProperties.put(Context.PROVIDER_URL, """); InitialContext context = new InitialContext(jndiProperties);
  • 我对 JNDI 有非常基本的了解,简短的研究表明(对我而言)它非常令人困惑。您能否写一个答案,详细说明在同一台机器上运行的进程如何通过 JNDI 连接到 WildFly 并检索绑定对象?例如。是否需要额外的库等?(另外,我希望进程建立连接后直接与数据库对话,不涉及WildFly,对吧?)

标签: java jakarta-ee jdbc wildfly


【解决方案1】:

实际上还有另外两个替代方案(比 JNDI 更轻量级)

  1. 您可以使用 Wildfly 的 admin REST api 来读取服务器上定义的数据源设置(在 /configuration/standalone-***.xml 中)。您的应用可以发出一个简单的(经过身份验证的)http GET 请求并解析获得的 xml。

http://localhost:9990/management/subsystem/datasources/data-source/ExampleDS?operation=resource&recursive=true&json.pretty=1

  1. Wildfly 也同样在 JMX 中公开了这些设置。您只需要阅读它们,要么使用 JDK 的 JMX api,要么使用众多开源库之一来简化 JMX 查询。 只需运行“jconsole”,连接到运行 WF 服务器的进程,然后查找数据源的属性。 => 找到“ConnectionUrl”、“userName”和“password”属性。然后对您的应用进行编码以读取这 3 个属性。

祝你好运!

【讨论】:

  • 有一个小怪癖。如果我“稍后”执行 JMX 查询,当 WildFly 已经完全初始化时,一切都很好。但是,如果我在服务器启动时这样做,我会得到奇怪的行为:MBeanServer.queryMBeans(...) 正确返回 JDBC 连接配置列表,但它们上的MBeanServer.getAttribute() 失败并显示“WFLYCTL0013: Operation ("read-attribute")失败... WFLYCTL0216:找不到管理资源“[(\"subsystem\" => \"datasources\")]'”。您是否偶然知道如何等到服务器引导完成?
  • 没关系,找到了如何使用 JMX 来做到这一点。显然 WildFly 从不发送通知,至少对于 jboss.as:management-root=server 的更改,但我可以每秒轮询一次。