无法通过JConsole使MXBean连接到数据库

时间:2012-05-18 19:22:56

标签: java spring tomcat jmx jconsole

我只是希望有人看到并解决了这个问题。我有一个MBean和一个MXBean类。两者都使用相同的服务类来通过DAO类访问数据库。我使用spring 3.0来初始化这些类并使用JConsole来测试这些bean。这两个bean都有相同的方法名称来访问它们的服务类,比如说methodA()。但是当连接到oracle数据库时,只有MBean类返回数据。另一个MXBean类会产生一些错误。


这是错误


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)



这是我的弹簧配置

<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" />

DocumentMBean是一个常规MBean。 DocumentMXBean是一个MXBean。这两个bean都使用相同的documentService服务类,它使用相同的DAO类从Oracle数据库中获取数据。 DocumentMBean正确返回数据。 DocumentMXBean具有上述错误。

有谁知道为什么类oracle.ucp.jdbc.LabelableConnection在类加载器中不可见?只有在我执行MXBean时才会发生这种情况。我的MBean正确返回数据。我的WEB-INF / lib文件夹中包含该类的jar文件。这部署在Tomcat中。我从Eclipse中启动Tomcat。

更新1:

我能够通过将这些“不可见”类的jar文件添加到Eclipse中的Tomcat类路径来临时解决此问题。看起来像加载MBean,JConsole / java正在使用我的Web应用程序类加载器,它可以访问类加载器所需的所有库。但是在使用Tomcat的类加载器加载MXBeans时,JConsole / java。

我的问题是:在加载MBean或MXBean时,有没有办法强制Tomcat / Eclipse / Java使用相同的类加载器(这是我的Web应用程序类加载器)?

更新2:

我发现在加载我的Web应用程序时,Spring使用Web应用程序的类加载器而Tomcat在加载任何MXBean时,它使用JVM类加载器,它没有我的oracle类路径。因此,解决方法是使用我的类的类加载器而不是JVM中的类加载器。代码应为:


    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);
    }

1 个答案:

答案 0 :(得分:0)

MXBean可能是由容器类加载器加载的,而不是由Web应用程序加载的。如果驱动程序位于应用程序li​​b目录中,那么这将导致您遇到的问题。

如果是这种情况,请将驱动程序移至tomcat / lib目录。