我正在尝试从容器外部的胖客户端访问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>
有没有人知道这可能来自哪里?
也许有人甚至知道如何实现这一目标的更好方法。 任何提示都非常感谢!
干杯,
迈克尔
答案 0 :(得分:1)
答案 1 :(得分:1)
@Michael嗯,java.sql.Connection是一个接口 - 从技术上来说,从JBoss获得的具体实现可能是Serializable - 但我不认为你真的会有任何选择您可以使用。如果有可能,那可能很容易:)
我认为@toolkit可能已经说出了在VM外部可用的正确单词 - JDBC驱动程序将与底层操作系统中运行的本机驱动程序代码进行通信我猜,这可能解释了为什么你不能只传递连接通过其他地方的网络。
我的建议,(如果你没有得到任何更好的建议!)将找到一个不同的方法 - 如果你有权在JBoss目录上找到资源,可能实现一个你可以找到并获得的代理对象从允许您从胖客户端远程使用连接的目录中。这是一种称为数据传输对象的设计模式,我认为Wikipedia entry
答案 2 :(得分:0)
我认为异常表明您尝试检索的SQLConnection对象没有实现Serializable接口,因此无法按照您要求的方式传递给您。
从我用JDNI完成的有限工作开始,如果你通过JNDI要求一个对象,它必须是可序列化的。据我所知,没有办法解决这个问题 - 如果我想到一个更好的方法,我会发布它......
好的,一个显而易见的选择是提供一个可序列化的对象本地数据源使用它,但没有数据源作为其可序列化对象图的一部分。胖客户端然后可以查找该对象并进行查询。
或者创建一个(web?)服务来管理访问数据源 - 再次你的胖客户端会点击服务 - 这可能是更好的封装和更可重用的方法,如果那些是您的担忧。
答案 3 :(得分:0)
@toolkit: 好吧,不完全是。由于我可以通过JNDI访问数据源,因此它实际上是可见的,因此可用。
或者我得到了一些完全错误的东西?
@Brabster: 我认为你走在正确的轨道上。有没有办法使连接可序列化?也许这只是一个配置问题......
答案 4 :(得分:0)
我现在已经阅读过Ibatis了 - 也许你可以让你的Dao等实现Serializable,将它们发布到你的目录中,然后检索它们并在你的胖客户端中使用它们?你也可以获得重用的好处。
以下是Wicket
的类似示例答案 5 :(得分:0)
JBoss用它自己的数据包装所有DataSource。
这让它可以通过自动提交来实现从JDBC连接中获取指定的J2EE行为。它们主要可以选择。但你不必相信他们。
我仔细看看它的包装纸。我已经为JBoss的J2EE包装器编写了一个代理,用于与OOCJNDI一起使用,以使我的DAO代码单元可单独测试。
你只需要包装java.sql.Driver,在你的类中指向OOCJNDI,然后在JUnit中运行。
Driver包装器可以直接创建一个SQL驱动程序并委托给它。
在Connect上返回您自己设计的java.sql.Connection包装。
ConnectionWrapper可以封装您的Oracle驱动程序为您提供的连接, 并且所有特殊功能都设置为Autocommit true。
不要忘记Eclipse可以为你提供帮助。添加您需要委派的成员,然后选择它并右键单击,来源 - =&gt;添加附加方法。
当你通过线路获得报酬时这很好; - )
Bada-bing,Bada-boom,JUnit开箱即用的J2EE测试。
你的问题可能是同样的事情,JUnit划掉了,FatCLient写在蜡笔上。
我的FatClient使用xdoclet生成的RMI与J2EE服务器通信,所以我没有你的问题。