2011-09-27 2 views
3

Tomcat 6에 배포하는 사용자 정의 MBean을 작성했습니다.이 태스크 중 하나는 데이터베이스 값을 쿼리하는 것입니다. JNDI를 사용하여 데이터베이스 자원을로드하여이 작업을 수행합니다. 자원은 Tomcat의 server.xml에 정의되어 있습니다.Tomcat의 사용자 정의 MBean - InitialContext를 만들 때 javaURLContextFactory를 찾을 수 없습니다.

문제는 javax.naming.InitialContext 인스턴스를 만들 때 ClassNotFoundException을 던집니다. org.apache.naming.java.javaURLContextFactory을 찾을 수 없기 때문입니다. 이 클래스는 catalina.jar에 있으며 공통 클래스 로더에 의해로드됩니다. 내 MBean 코드가 들어있는 jar는 공유 클래스 로더에 의해로드됩니다.

이 문제를 해결하는 방법에 대한 아이디어가 있습니까?

참고 사항 : 내 MBean은 tomcat/conf/web.xml에 정의한 ContextListener에 의해로드됩니다. 나는 또한 차이점이없는 웹 애플리케이션 web.xml에 정의했다. 공유 클래스 로더에 의해로드 된 클래스에 의존하므로 공용 클래스 로더에 의해로드되도록 항아리를 옮길 수는 없습니다. 사전에

감사합니다,

+0

당신이 정확한 구성을 게시 할 수 있습니다 jconsole 통해 sayHello()는 다음과 같은 인쇄 호출? web.xml, server.xml 등등. – Tarlog

답변

6

그것은 이상한 클래스 로딩 또는 보안/권한 문제를 보인다. 아래는 해결 방법입니다.

주요 아이디어 : ServletContextListenerClassNotFoundException없이 new InitialContext()을 호출 할 수 있으므로, MBean을 등록하기 전에 수신기에서 가져 와서 MBean 객체의 생성자에 전달하십시오. 간단한 웹 응용 프로그램을 사용하고 수정하지 않았습니다. tomcat/conf/web.xml. tomcat/conf/context.xml

자원 구성 :

<Context> 
... 
    <Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource" 
     maxActive="100" maxIdle="30" maxWait="10000" 
     username="root" password="..." driverClassName="com.mysql.jdbc.Driver" 
     url="jdbc:mysql://localhost:3306/javatest?autoReconnect=true"/> 
... 
<Context> 

web.xml 자원 구성 :

<resource-ref> 
    <description>DB Connection</description> 
    <res-ref-name>jdbc/TestDB</res-ref-name> 
    <res-type>javax.sql.DataSource</res-type> 
    <res-auth>Container</res-auth> 
</resource-ref> 

MBean의 레지스터 ServletContextListener :

import java.lang.management.ManagementFactory; 

import javax.management.MBeanServer; 
import javax.management.ObjectName; 
import javax.naming.Context; 
import javax.naming.InitialContext; 
import javax.servlet.ServletContextEvent; 
import javax.servlet.ServletContextListener; 
import javax.servlet.annotation.WebListener; 

@WebListener 
public class ContextListener implements ServletContextListener { 

    private ObjectName objectName; 

    public void contextInitialized(final ServletContextEvent sce) { 
     System.out.println("---> bean context listener started"); 

     final MBeanServer mbeanServer = 
      ManagementFactory.getPlatformMBeanServer(); 
     try { 
      final InitialContext initialContext = new InitialContext(); 
      final Context envContext = 
       (Context) initialContext.lookup("java:/comp/env"); 

      objectName = new ObjectName("com.example:type=Hello"); 
      final Hello helloMbean = new Hello(envContext); 
      mbeanServer.registerMBean(helloMbean, objectName); 
      System.out.println("---> registerMBean ok"); 
     } catch (final Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public void contextDestroyed(final ServletContextEvent sce) { 
     System.out.println("---> bean context listener destroyed"); 
     final MBeanServer mbeanServer = 
      ManagementFactory.getPlatformMBeanServer(); 
     try { 
      mbeanServer.unregisterMBean(objectName); 
      System.out.println("---> unregisterMBean ok"); 
     } catch (final Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

MBean 인터페이스를 :

,451,515,
public interface HelloMBean { 
    void sayHello(); 
} 

MBean의 구현 :

import java.sql.Connection; 

import javax.naming.Context; 
import javax.sql.DataSource; 

public class Hello implements HelloMBean { 

    private final Context envContext; 

    public Hello(final Context envContext) { 
     this.envContext = envContext; 
     System.out.println("new hello " + envContext); 
    } 

    @Override 
    public void sayHello() { 
     System.out.println("sayHello()"); 

     try { 
      final DataSource ds = 
       (DataSource) envContext.lookup("jdbc/TestDB"); 
      final Connection conn = ds.getConnection(); 
      System.out.println(" conn: " + conn); 
      // more JDBC code 
     } catch (final Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

MBean Descriptor How Tombeans-descriptor.xml이 필요하지만 그것을 잘하지 않고 일을 말한다. HelloMBean에 jconsole으로 연결할 수 있습니다.

conn: jdbc:mysql://localhost:3306/javatest?autoReconnect=true, \ 
[email protected], MySQL-AB JDBC Driver 

소스 :

+1

우수, 감사합니다. – Will

관련 문제