3

Context

I have a JBoss where I have sucessfully deployed a datasource mydatasource-ds.xml. It's JNDI name is java:mydatasourceDS. JBoss claims that the datasource is succesfully deployed. The JMX console agress too.

Problem

I want to use this datasource from a client java app launched on a separate JVM. But I get an exception saying the java:mydatasourceDS cannot be found.

java.lang.ClassCastException: javax.naming.Reference cannot be cast to javax.sql.DataSource

Details

Here is the persistence.xml file :

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="mydatasource-db" transaction-type="JTA">
    <jta-data-source>java:mydatasourceDS</jta-data-source>
    <properties>
        <property name="hibernate.show_sql" value="true" />
        <property name="hibernate.format_sql" value="true" />

        <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
        <property name="hibernate.hbm2ddl.auto" value="update" />
        <property name="hibernate.default_schema" value="rec" />

        <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
    </properties>
</persistence-unit>

Here is the jndi.properties file :

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=jnp://localhost:1099
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces

Here is the application classpath :

jndi.properties
log4j.properties
META-INF\persistence.xml
hibernate-jpa-2.0-api-1.0.0.Final.jar
jnp-client-5.0.3.GA.jar
jboss-common-core-2.2.14.GA.jar
jboss-logging-spi-2.1.0.GA.jar
hibernate-entitymanager-3.6.4.Final.jar
hibernate-core-3.6.4.Final.jar
antlr-2.7.6.jar
commons-collections-3.1.jar
dom4j-1.6.1.jar
hibernate-commons-annotations-3.2.0.Final.jar
jta-1.1.jar
javassist-3.12.0.GA.jar
slf4j-api-1.6.1.jar
slf4j-log4j12-1.6.1.jar
log4j-1.2.16.jar
xstream-1.4.1.jar
xmlpull-1.1.3.1.jar
xpp3_min-1.1.4c.jar

EDIT I have found the source of the problem. The javax.sql.DataSource that was available to my client application was NOT the one received from JNDI. The one I receive from JNDI is the JBoss javax.sql.DataSource. Same name BUT slightly different classes hence the ClassCastException...

As of this writing, the JBoss javax.sql.DataSource can be found in this package : jboss-j2ee-4.2.3.GA.jar

Stephan
  • 41,764
  • 65
  • 238
  • 329
  • glad to know you worked it out :D – oers Dec 22 '11 at 19:50
  • well not really. I have found the root cause but I can't solve it. How can I get rid of javax.sql.DataSource from the JDK in favor of the one from JBoss ? I can remove rt.jar from classpath but I need java.lang.String :-o – Stephan Dec 24 '11 at 02:32

2 Answers2

3

If you get a

javax.naming.Reference 

that means you are missing runtime dependencies that are required for it to resolve. You can inspect the classFactory member of the Reference object via

getFactoryClassName() 

to figure out the first dependency you are missing.

In my case using JBoss6.1 it was:

org.jboss.resource.adapter.jdbc.remote.DataSourceFactory

Putting the jar this class is in on the classpath (common/lib/jbosscx-client.jar) got me past the first step and then it was a matter of tracking down all the ClassNotFoundException errors.

The full list for JBoss6.1 turned out to be:

- client/jnp-client.jar
- client/jboss-logging.jar
- common/lib/jbosscx-client.jar
- client/concurrent.jar
- client/jboss-client.jar
- client/jboss-common-core.jar
- client/jboss-integration.jar
- client/jboss-remoting.jar
- client/jboss-security-spi.jar
- client/jboss-serialization.jar
- client/jboss-transaction-api_1.1_spec.jar
enrico.bacis
  • 30,497
  • 10
  • 86
  • 115
work.asr
  • 41
  • 1
2

This guide says that you have to set

<use-java-context>false</use-java-context>

in mydatasource-ds.xml. Not sure if you did.

oers
  • 18,436
  • 13
  • 66
  • 75
  • Tks for your suggestion. In one of the comments from the guide , one says that when the connection pool is full, no more connections can be established. How can we address this issue ? – Stephan Dec 22 '11 at 10:56
  • You have to make sure that your application has enough connections in the pool. How many that is depends on your environment. If the pool is full, the pool manager will wait a certain amount of time until it retries. Make sure you close every connection, after you used it. You could also define a second datasource that is only used by the client. – oers Dec 22 '11 at 11:05
  • I can now retrieve the DataSource but I have a CCE :\ `java.lang.ClassCastException: javax.naming.Reference cannot be cast to javax.sql.DataSource` – Stephan Dec 22 '11 at 12:12
  • I have read this resource. I put the postgresql jar in the classpath and no luck. I have found this one too : http://www.mastertheboss.com/jboss-howto/42-jboss-config/222-how-to-solve-qjavaxnamingreference-cannot-be-cast-to-javaxnamingreference-cannot-be-cast-to-q.html. No luck either. – Stephan Dec 22 '11 at 13:39
  • are you sure that you have a jar file containing the DataSource implementation/interface in your classpath? Seems that driver alone is not enough. – oers Dec 22 '11 at 13:41
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/6061/discussion-between-stephan-and-oers) – Stephan Dec 22 '11 at 14:02