3

I just hope if there is somebody who have seen and resolved this problem. I have a MBean and a MXBean classes. Both are using the same service class to get access to the database through a DAO class. I am using spring 3.0 to initialized those classes and using the JConsole to test those beans. Both those beans have the same method name to access to their service class, lets say methodA(). But when connecting to the oracle database, only the MBean class returns data. The other MXBean class produces some errors.


Here are the errors


EL Severe]: 2012-05-18 10:37:54.134--ServerSession(1992289)--Thread(Thread[RMI TCP Connection(6)-10.208.138.241,5,RMI Runtime])--java.lang.IllegalArgumentException: interface oracle.ucp.jdbc.LabelableConnection is not visible from class loader
    at java.lang.reflect.Proxy.getProxyClass(Proxy.java:353)
    at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:581)
    at oracle.ucp.jdbc.proxy.ConnectionProxyFactory.createConnectionProxy(ConnectionProxyFactory.java:78)
    at oracle.ucp.jdbc.PoolDataSourceImpl.getConnection(PoolDataSourceImpl.java:658)
    at oracle.ucp.jdbc.PoolDataSourceImpl.getConnection(PoolDataSourceImpl.java:613)
    at oracle.ucp.jdbc.PoolDataSourceImpl.getConnection(PoolDataSourceImpl.java:607)
    at org.springframework.jdbc.datasource.DelegatingDataSource.getConnection(DelegatingDataSource.java:83)
    at com.trgr.cobalt.dataorch.datasource.BaseDODataSource.getRawConnection(BaseDODataSource.java:76)
    at com.trgr.cobalt.dataorch.datasource.BaseDODataSource.getConnection(BaseDODataSource.java:46)
    at com.trgr.cobalt.dataorch.datasource.BaseDODataSource.getConnection(BaseDODataSource.java:35)
    at org.eclipse.persistence.sessions.JNDIConnector.connect(JNDIConnector.java:126)
    at org.eclipse.persistence.sessions.JNDIConnector.connect(JNDIConnector.java:94)
    at org.eclipse.persistence.sessions.DatasourceLogin.connectToDatasource(DatasourceLogin.java:162)
    at org.eclipse.persistence.internal.databaseaccess.DatasourceAccessor.connectInternal(DatasourceAccessor.java:327)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.connectInternal(DatabaseAccessor.java:291)
    at org.eclipse.persistence.internal.databaseaccess.DatasourceAccessor.connect(DatasourceAccessor.java:415)
    at org.eclipse.persistence.sessions.server.ConnectionPool.buildConnection(ConnectionPool.java:155)
    at org.eclipse.persistence.sessions.server.ExternalConnectionPool.startUp(ExternalConnectionPool.java:118)
    at org.eclipse.persistence.sessions.server.ServerSession.connect(ServerSession.java:495)
    at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.login(DatabaseSessionImpl.java:627)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:230)
    at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:389)
    at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:164)



Here is my spring configuration

<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"
    lazy-init="false">
    <property name="namingStrategy" ref="namingStrategy"></property>
    <property name="assembler" ref="assembler"></property>
    <property name="autodetect" value="true" />
</bean>

<bean id="attributeSource"
    class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource" />
<bean id="assembler"
    class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
    <property name="attributeSource" ref="attributeSource" />
</bean>
<bean id="namingStrategy"
    class="org.springframework.jmx.export.naming.MetadataNamingStrategy">
    <property name="attributeSource" ref="attributeSource" />
</bean>


<bean class="myclass.jmx.DocumentMBean"
    p:schedulerService-ref="documentService" />

<bean class="myclass.jmx.DocumentMXBean"
    p:schedulerService-ref="documentService" />

The DocumentMBean is a regular MBean. The DocumentMXBean is a MXBean. Both those beans using the same documentService service class, which using the same DAO class to get data from Oracle database. The DocumentMBean returns data correctly. The DocumentMXBean has the errors mentioned above.

Does anyone know why the class oracle.ucp.jdbc.LabelableConnection is not visible from class loader? This happens ONLY when I execute my MXBean. My MBean returns data correctly. I have the jar file containing that class inside my WEB-INF/lib folder. And this is deployed in Tomcat. And I start Tomcat from within Eclipse.

Update 1:

I was able to temporary resolve this by adding the jar files for those "not visible" classes to Tomcat classpath inside Eclipse. It seems like for loading the MBeans, JConsole/java is using my web application class loader, which have access to all the libraries that the class loader needs. But when loading the MXBeans, JConsole/java using the class loader of Tomcat.

My question is: is there a way to force Tomcat/Eclipse/Java using the same class loader (which is my web app class loader) when loading either MBean or MXBean?

Update 2:

I found out that when loading my web application, Spring uses the web application's class loader while Tomcat when loading any MXBean, it uses the JVM class loader, which doesn't have my oracle class path in it. So, the work-around solution is to use the class loader of my classes instead of the one from JVM. The codes should be:


    try
    {
    // your codes here

    // Get the current class-loader. This might be the class-loader from Tomcat
    ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();

    // Set the class-loader to be the one from the DO and not the one from Tomcat
    Thread.currentThread().setContextClassLoader(getClass().getClassLoader());

    // your codes here
    }
    catch (Exception e)
    {
       // your codes here
    }
    finally
    {
       // Remember to set back the original class-loader
       Thread.currentThread().setContextClassLoader(contextClassLoader);
    }
Tuan
  • 249
  • 1
  • 2
  • 4

1 Answers1

0

The MXBean is probably being loaded by the container classloader, rather than by the web application. If the driver is in the application lib directory then this will cause the problem you're seeing.

If this is the case, move the driver to the tomcat/lib directory.

Pidster
  • 628
  • 4
  • 9
  • Thanks for the response. The requirement of this task requires me to have all the jar files in the lib folder of the application. Is there a way to grant MXBean the access to those jar files without moving them into the tomcat/lib folder? BTW, I tried your suggestion but it didn't work. – Tuan May 19 '12 at 22:39