2014-11-14 1 views
1

Apache Tomcat 7 용 사용자 정의 Valve을 개발 중이며, 밸브는 Apache Tomcat server.xml 구성 파일의 레벨 Host container에 정의되어 있습니다.Apache Tomcat 7.x에서 컨텍스트 컨테이너 외부의 글로벌 JNDI 리소스에 액세스하는 방법은 무엇입니까?

<Engine defaultHost="localhost" name="Catalina"> 

    <Realm className="org.apache.catalina.realm.DataSourceRealm" dataSourceName="jdbc/qgw" 
    roleNameCol="role_name" userCredCol="user_pass" userNameCol="user_name" userRoleTable="user_roles" userTable="users"/> 

    <Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true"> 
     <Valve className="org.mycompany.valves.CustomValve"/> 
     <Valve className="org.apache.catalina.authenticator.SingleSignOn"/> 
     <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" 
     pattern="%h %l %u %t &quot;%r&quot; %s %b" prefix="localhost_access_log." suffix=".txt"/> 
    </Host> 

</Engine> 

밸브는 몇 가지 질의를 할 수있는 데이터베이스에 대한 연결을 얻을 필요가있다.

GlobalNamingResources에 글로벌 리소스로 정의 된 JNDI 리소스를 가져 오려고합니다. ResourceLink가의 context.xml 구성 파일에 정의되어 있기 때문에

<GlobalNamingResources> 
    <Resource auth="Container" driverClassName="com.mysql.jdbc.Driver" 
    logAbandoned="true" maxActive="25" maxIdle="10" name="jdbc/qgw" 
    password="pass" removeAbandoned="true" removeAbandonedTimeout="300" 
    testOnBorrow="true" type="javax.sql.DataSource" 
    url="jdbc:mysql://localhost/qgw?autoReconnect=true" 
    username="username" validationQuery="SELECT 1"/> 
</GlobalNamingResources> 

문제는이 자원은 Context 컨테이너 수준에서 accesible입니다. 밸브가

InitialContext initCtx = new InitialContext(); 
DataSource ds = (DataSource)initCtx.lookup("java:comp/env/jdbc/qgw"); 

JNDI

를 통해 데이터 소스를 얻을 할려고

분명히
<ResourceLink global="jdbc/qgw" name="jdbc/qgw" type="javax.sql.DataSource"/> 

는 호스트 컨테이너 수준에서 리소스를 사용할 수있는 방법이,

javax.naming.NameNotFoundException: Name comp/env/jdbc/qgw is not bound in this Context 

그래서 NameNotFoundException가에게 가져 정의 된 데이터베이스에 연결 하시겠습니까?

+0

왜 ResourceLink를 사용하고 있습니까? – AliR

+0

왜 안 되니? ResourceLink는 컨테이너의 모든 배포 된 응용 프로그램에 필요하기 때문에 컨텍스트 수준에서 선언됩니다. – vzamanillo

+0

나는 여기서 한 일을 시도했지만 밸브가 엔진 레벨에 있더라도 사용자 정의 Valve가 GlobalResource에 액세스 할 수 있다는 문서는없는 것 같습니다. – AliR

답변

1

오랜 시간 후,이 내가 container에서 카탈 StandardService을 받고는 DataSource를 얻을 수있는 유일한 방법이이 작업을 수행하는 가장 좋은 방법인지는 모르겠지만, 그것을 작동합니다.

private static final String RESOURCE = "jdbc/qgw"; 

private DataSource ds; 

@Override 
protected synchronized void startInternal() throws LifecycleException { 
    super.startInternal(); 

    StandardService service = (StandardService)((StandardEngine)((StandardHost) container).getParent()).getService(); 
    try { 
     // Accesible via GlobalNamingResources too 
     //service.getServer().getGlobalNamingResources().findResource(RESOURCE); 
     ds = (DataSource)service.getServer().getGlobalNamingContext().lookup(RESOURCE); 
     if (ds==null) { 
      throw new LifecycleException("Can't get the datasource to connect to database from the valve."); 
     } 
    } catch (Exception e) { 
     container.getLogger().error(e); 
     throw new LifecycleException(e.getMessage()); 
    } 
} 
+0

Tomcat 8.5에서도 작동하는지 확인할 수 있습니다. 감사 ! – Hari

관련 문제