在Grails 3中将JNDI添加到嵌入式Tomcat服务器

时间:2016-02-17 18:55:06

标签: spring tomcat grails groovy spring-boot

在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也是如此,因为它位于外部库中。

我正在尝试将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].

以前有人这样做过吗?如果有一个额外的线程覆盖了上下文,我不会感到惊讶。

2 个答案:

答案 0 :(得分:0)

在Grails 3中,你这样做:SampleTomcatJndiApplication

通常,在Grails Web应用程序中,这位于/grails-app/init/Application.groovy

(在我的情况下,我注释了jndiDataSource()部分并且只使用了postProcessContext()。)

来源:Graeme Rocher

答案 1 :(得分:0)

这个问题的解决方案分两步解决。首先,我必须使用子方法来设置正确的上下文,在这个问题中找到。 Setting the right context in embedded 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;
}

接下来,我必须编辑gradle构建文件,以包含dbcp BasicDataSource依赖项。我的gradle构建文件现在包含:

dependencies {
    // Embedded tomcat dependencies
    compile "org.apache.tomcat:tomcat-dbcp:9.0.0.M1"
}