복붙노트

[SPRING] Grails 3에 임베디드 Tomcat 서버에 JNDI 추가하기

SPRING

Grails 3에 임베디드 Tomcat 서버에 JNDI 추가하기

grails 3.0 또는 run-app에서 test-app를 실행할 때 grails는 자체적 인 버전의 임베디드 Tomcat 서버를 실행합니다. 나는 다음 링크에서 이것을 결론 지었다. https://roshandawrani.wordpress.com/2011/03/13/grails-tip-configuring-embedded-tomcat-instance-used-in-developmenttest-env/

그러나 context.xml 및 server.xml 파일은 풀 다운 된 라이브러리와 함께 사전 컴파일됩니다. grails 앱을 처음부터 만들 때 두 파일 중 하나를 찾을 수 없습니다. config.groovy가 외부 라이브러리 내에 있기 때문에 config.groovy도 마찬가지입니다.

컨테이너에 JNDI 자원을 주입하려고하는데이를 호출 할 수 있습니다. 이 같은:

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

첫 번째 링크에서 저자는 scripts / _Events.groovy 디렉토리에서이를 수행 할 수있는 방법을 제공하지만이 방법도 없습니다.

업데이트 1 : 작동하지 않는 코드

import grails.boot.GrailsApp
import grails.boot.config.GrailsAutoConfiguration
import org.apache.catalina.Context
import org.apache.catalina.startup.Tomcat
import org.apache.tomcat.util.descriptor.web.ContextResource
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory
import org.springframework.context.annotation.Bean

@SpringBootApplication
class Application extends GrailsAutoConfiguration {
    static void main(String[] args) {
        GrailsApp.run(Application, args)
    }

    @Bean
    public TomcatEmbeddedServletContainerFactory tomcatFactory() {
        return new TomcatEmbeddedServletContainerFactory() {

            @Override
            protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(
                    Tomcat tomcat) {
                tomcat.enableNaming();
                return super.getTomcatEmbeddedServletContainer(tomcat);
            }

            @Override
            protected void postProcessContext(Context context) {
                context.getNamingResources().addResource(preconfigureDbResource("oneSource", "127.0.0.1"))
                context.getNamingResources().addResource(preconfigureDbResource("nextSource", "127.0.0.1"))
            }
        }

    }

    private ContextResource preconfigureDbResource(String name, String ip) {
        ContextResource resource = new ContextResource()
        resource.setType("javax.sql.DataSource")
        resource.setName("jdbc/" + name)
        resource.setProperty("url", "jdbc:oracle:thin:@" + ip + ":1521:ucop")
        resource.setProperty("driverClassName", "oracle.jdbc.driver.OracleDriver")
        resource.setProperty("username", "coolio")
        resource.setProperty("password", "password")
        resource.setProperty("auth", "Container")
        resource.setProperty("maxTotal", "100")
        resource.setProperty("maxIdle", "30")
        resource.setProperty("maxWaitMillis", "10000")
        return resource;
    }


}

내 서비스 파일에서 다음과 같이이 소스를 호출합니다.

public DataSource getOneSource() {
    Context context = (Context) new InitialContext().lookup("java:/comp/env")
        oneSource= (DataSource) context.lookup("jdbc/oneSource")
    return oneSource
}    

그러나 나는 진술하는 과실을 얻고있다 :

javax.naming.NameNotFoundException: Name [comp/env] is not bound in this Context. Unable to find [comp].

누구든지 전에 이것을 했습니까? 컨텍스트를 덮어 쓰는 여분의 스레드가 있으면 나는 놀라지 않을 것입니다.

해결법

  1. ==============================

    1.Grails 3에서는 다음과 같이 처리합니다. SampleTomcatJndiApplication

    Grails 3에서는 다음과 같이 처리합니다. SampleTomcatJndiApplication

    일반적으로 Grails 웹 애플리케이션에서는 /grails-app/init/Application.groovy에 있습니다.

    (제 경우에는 jndiDataSource () 부분을 주석 처리하고 postProcessContext ()를 사용했습니다.)

    출처 : Graeme Rocher

  2. ==============================

    2.이 문제에 대한 해결책은 두 단계로 해결됩니다. 첫째, 나는이 질문에서 발견되는 올바른 맥락을 설정하기 위해 아동 접근법을 사용해야 만했다. 임베디드 Tomcat에서 올바른 컨텍스트 설정하기

    이 문제에 대한 해결책은 두 단계로 해결됩니다. 첫째, 나는이 질문에서 발견되는 올바른 맥락을 설정하기 위해 아동 접근법을 사용해야 만했다. 임베디드 Tomcat에서 올바른 컨텍스트 설정하기

    상상했던 것처럼 getTomcatEmbeddedServletContainer 메서드를 사용하여 변경해야 할 사항이 있습니다. 원본을 다음과 같이 편집했습니다.

    @Override
    protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(Tomcat tomcat) {
        tomcat.enableNaming();
        TomcatEmbeddedServletContainer container =
        super.getTomcatEmbeddedServletContainer(tomcat);
        for (Container child: container.getTomcat().getHost().findChildren()) {
            if (child instanceof Context) {
                ClassLoader contextClassLoader =((Context)child).getLoader().getClassLoader();
                Thread.currentThread().setContextClassLoader(contextClassLoader);
                break;
            }
        }
        return container;
    }
    

    다음으로, dbcp BasicDataSource Dependency를 포함하도록 gradle 빌드 파일을 편집해야했습니다. 내 gradble 빌드 파일에 다음이 포함됩니다.

    dependencies {
        // Embedded tomcat dependencies
        compile "org.apache.tomcat:tomcat-dbcp:9.0.0.M1"
    }
    
  3. from https://stackoverflow.com/questions/35465278/adding-jndi-to-embedded-tomcat-server-in-grails-3 by cc-by-sa and MIT license