3

我正在尝试从容器外部的胖客户端访问在 Web 容器 (JBoss) 中定义的数据源。

我决定通过 JNDI 查找数据源。实际上,我的持久性框架(Ibatis)就是这样做的。

执行查询时,我总是会收到此错误:

java.lang.IllegalAccessException: Method=public abstract java.sql.Connection java.sql.Statement.getConnection() throws java.sql.SQLException does not return Serializable 

Stacktrace:
org.jboss.resource.adapter.jdbc.remote.WrapperDataSourceService.doStatementMethod(WrapperDataSourceS
ervice.java:411),
org.jboss.resource.adapter.jdbc.remote.WrapperDataSourceService.invoke(WrapperDataSourceService.java
:223),
sun.reflect.GeneratedMethodAccessor106.invoke(Unknown Source),
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25),
java.lang.reflect.Method.invoke(Method.java:585),
org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155),
org.jboss.mx.server.Invocation.dispatch(Invocation.java:94),
org.jboss.mx.server.Invocation.invoke(Invocation.java:86),
org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264),
org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659),

我的数据源:

<?xml version="1.0" encoding="UTF-8"?>
<datasources>
  <local-tx-datasource>
        <jndi-name>jdbc/xxxxxDS</jndi-name>
        <connection-url>jdbc:oracle:thin:@xxxxxxxxx:1521:xxxxxxx</connection-url>
        <use-java-context>false</use-java-context>
        <driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
        <user-name>xxxxxxxx</user-name>
        <password>xxxxxx</password>
        <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>
        <min-pool-size>5</min-pool-size>
        <max-pool-size>20</max-pool-size>
    </local-tx-datasource>
</datasources>

有谁知道这可能来自哪里?

也许有人甚至知道如何实现这一目标的更好方法。任何提示都非常感谢!

干杯,

迈克尔

4

6 回答 6

1

@Michael好吧, java.sql.Connection 是一个接口-从技术上讲,您从 JBoss 获得的具体实现可能是可序列化的-但我认为您真的不会有任何可以使用的选项. 如果可能的话,这可能很容易:)

我认为@toolkit 可能在 VM 之外使用了正确的话 - 我猜 JDBC 驱动程序将与运行在底层操作系统中的本机驱动程序代码进行对话,所以这可能解释了为什么你不能只通过网络传递连接别处。

我的建议,(如果你没有得到更好的建议!)将是找到一种不同的方法 - 如果你有权在 JBoss 目录中找到资源,也许实现一个你可以从目录中找到和获取的代理对象这允许您从胖客户端远程使用连接。那是一种称为数据传输对象的设计模式,我认为是维基百科条目

于 2008-09-03T13:03:38.690 回答
1

不确定这是不是同一个问题?

JBoss 数据源配置

DataSource 包装器在服务器 VM 之外不可用

于 2008-09-02T13:29:15.937 回答
0

我现在已经阅读了 Ibatis - 也许你可以让你的 Dao 等实现可序列化,将它们发布到你的目录中,然后检索它们并在你的胖客户端中使用它们?你也会从中获得重用的好处。

这是一个与Wicket相似的示例

于 2008-09-03T17:39:09.510 回答
0

我认为该异常表明您尝试检索的 SQLConnection 对象未实现 Serializable 接口,因此无法按照您的要求将其传递给您。

从我对 JDNI 所做的有限工作来看,如果您通过 JNDI 请求一个对象,它必须是可序列化的。据我所知,没有办法解决这个问题 - 如果我想到更好的方法,我会发布它......

好的,一个明显的选择是为使用它的数据源提供本地的可序列化对象,但不将数据源作为其可序列化对象图的一部分。然后胖客户端可以查找该对象并查询它。

或者创建一个(Web?)服务,通过它来访问数据源 - 你的胖客户端会再次访问该服务 - 如果这些是你所关心的,这可能会是更好的封装和更可重用的方法。

于 2008-09-02T10:04:02.420 回答
0

@toolkit:嗯,不完全是。因为我可以通过 JNDI 访问数据源,所以它实际上是可见的,因此是可用的。

还是我完全错了?

@Brabster:我认为您走在正确的轨道上。没有办法使连接可序列化吗?可能只是配置问题...

于 2008-09-02T14:42:44.713 回答
0

JBoss 用它自己的数据源封装了所有数据源。

这让它可以使用自动提交来从 JDBC 连接中获取指定的 J2EE 行为。它们大多是可序列化的。但你不必相信他们。

我会仔细看看它的包装纸。我为 JBoss 的 J2EE wrappers 为 JDBC 编写了一个代理,它与 OOCJNDI 一起使用,以使我的 DAO 代码可以独立进行单元测试。

您只需包装 java.sql.Driver,将 OOCJNDI 指向您的类,然后在 JUnit 中运行。

Driver 包装器可以直接创建一个 SQL Driver 并委托给它。

返回您自己在 Connect 上设计的 java.sql.Connection 包装器。

ConnectionWrapper 可以包装你的 Oracle 驱动程序给你的 Connection,它所做的所有特殊的事情就是将 Autocommit 设置为 true。

不要忘记 Eclipse 可以为您提供委托。添加一个您需要委托给的成员,然后选择它并右键单击,source -=>add delgage 方法。

当您通过线路获得报酬时,这很棒;-)

Bada-bing、Bada-boom、JUnit 开箱即用 J2EE 测试。

您的问题可能适用于同样的问题,将 JUnit 划掉并用蜡笔编写 FatCLient。

我的 FatClient 使用 xdoclet 生成的 RMI 与 J2EE 服务器通信,所以我没有你的问题。

于 2008-09-10T23:38:13.297 回答