2008-09-02 21 views
3

J'essaie d'accéder à une source de données définie dans un conteneur Web (JBoss) à partir d'un gros client à l'extérieur du conteneur. J'ai décidé de rechercher la source de données via JNDI. En fait, mon cadre de persistance (Ibatis) le fait.Accès à la source de données depuis l'extérieur d'un conteneur Web (via JNDI)

Lorsque vous effectuez des requêtes je finis toujours obtenir cette erreur:

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), 

Mon DataSource

<?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> 

Est-ce que quelqu'un a une idée d'où cela pourrait venir?

Peut-être que quelqu'un sait même une meilleure façon d'y parvenir. Tous les indices sont très appréciés!

Cheers,

Michael

Répondre

0

Je pense que l'exception indique que l'objet SQLConnection que vous essayez de récupérer ne met pas en oeuvre l'interface Serializable, donc il ne peut pas être transmis à la façon dont vous vous demandé pour cela. D'après le travail limité que j'ai fait avec JDNI, si vous demandez un objet via JNDI, il doit être sérialisable. Autant que je sache, il n'y a pas moyen de contourner cela - si je pense à un meilleur moyen, je le posterai ...

OK, une option évidente est de fournir un objet sérialisable local à la source de données qui l'utilise mais n'a pas la source de données dans le cadre de son graphe d'objet sérialisable. Le gros client pourrait alors rechercher cet objet et l'interroger à la place. Ou créer un service (web?) Par lequel accéder à la source de données est gérée - encore une fois votre gros client toucherait le service - cette approche serait probablement mieux encapsulée et plus réutilisable si cela vous préoccupe.

0

@toolkit: Eh bien, pas exactement. Depuis que je peux accéder à la source de données sur JNDI, il est réellement visible et donc utilisable. Ou est-ce que je me trompe?

@Brabster: Je pense que vous êtes sur la bonne voie. N'y at-il pas un moyen de rendre la connexion sérialisable? Peut-être juste un problème de configuration ...

1

Eh bien @ Michael, java.sql.Connection est une interface - il pourrait être techniquement possible pour la mise en œuvre concrète que vous obtenez de JBoss être Serializable - mais je ne pense que vous allez vraiment avoir des options que vous pouvez utiliser. Si c'était possible, ce serait probablement facile :)

Je pense que @toolkit pourrait avoir dit les bons mots avec utilisable en dehors de la VM - les pilotes JDBC parleront au code pilote natif fonctionnant dans l'OS sous-jacent, je suppose, cela pourrait expliquer pourquoi vous ne pouvez pas simplement passer une connexion sur le réseau ailleurs.Mon conseil, (si vous n'avez pas de meilleur conseil!) Serait de trouver une approche différente - si vous avez accès à localiser la ressource sur le répertoire JBoss, peut-être implémenter un objet proxy que vous pouvez localiser et obtenir à partir du répertoire qui vous permet d'utiliser la connexion à distance à partir de votre client de graisse. C'est un motif de design appelé objet de transfert de données je pense Wikipedia entry

0

J'ai lu sur Ibatis maintenant - peut-être vous pouvez faire vos implémentations de Dao etc. Serializable, postez-les dans votre répertoire et ainsi les récupérer et les utiliser dans votre gros client? Vous obtiendrez des avantages de réutilisation de cela aussi.

Voici un exemple de quelque chose ressemble à Wicket

0

enveloppements JBoss toutes les sources de données avec ses propres petits.

Cela laisse jouer des tours avec autocommit pour obtenir le comportement J2EE spécifié sur une connexion JDBC. Ils sont la plupart du temps serailizable. Mais vous n'avez pas besoin de leur faire confiance.

Je regarde attentivement à son wrappers. J'ai écrit un substitut pour wrappers J2EE JBoss wrapper pour JDBC qui fonctionne avec OOCJNDI pour obtenir mon unité de code DAO test autonome capable.

Vous venez enveloppez java.sql.Driver point OOCJNDI à votre classe, et exécutez à JUnit.

L'enveloppe du pilote peut simplement créer directement un pilote SQL et déléguer.

Retourner un emballage java.sql.Connection de votre propre conception sur Connect.

Un ConnectionWrapper peut simplement enrouler la connexion que votre pilote Oracle vous donne, et tout ce qu'il fait de spécial est mis Autocommit vrai.

Ne pas oublier Eclipse peut pour vous par rapport'a Biographie des délégués. Ajouter un membre, vous devez déléguer, puis sélectionnez-le et cliquez droit, source - => ajouter des méthodes de delgage.

C'est super quand vous êtes payé par la ligne ;-)

Bada-bing, Bada-boom JUnit de la boîte test J2EE.

Votre problème est probablement prête à la même chose, avec JUnit barré et écrit dans un client lourd crayon.

Mon RMI utilise généré client lourd avec XDoclet pour parler au serveur J2EE, donc je n'ai pas votre problème.