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

标签 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)



这是我的 Spring 配置

<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 应用程序类加载器,它可以访问类加载器需要的所有库。但是在加载 MXBeans 时,JConsole/java 使用 Tomcat 的类加载器。

我的问题是:有没有办法在加载 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);
    }

最佳答案

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

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

关于java - 无法使 MXBean 通过 JConsole 连接到数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10658584/

相关文章:

java - Spring Security的ACL配置问题

web-services - 网络服务,tomcat

java - 如何在Tomcat 7上部署多个应用

maven - 如何构建 WAR 文件以从 JHipster Spring Boot 项目部署到 Tomcat 上?

java - CardLayout没有完全隐藏其他卡片?

java - 如何在组件绘制时创建 "please wait"Swing 对话框

java - Apache Tomcat 上的两个 MySQL 数据源配置

java - 在 Android 和 iOS 中本地使用 krpano 的问题

spring - Azure B2C 访问 token NULL Spring OAuth 2.0

java - 如何使用注解在 Spring 中执行基于构造函数的依赖注入(inject)?