将 JNDI 添加到 Grails 3 中的嵌入式 Tomcat 服务器 [英] Adding JNDI to embedded Tomcat server in Grails 3
问题描述
在 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/
When running test-app in grails 3.0, or run-app, grails runs its own version of the embedded Tomcat server. I was able to conclude this from the following link: https://roshandawrani.wordpress.com/2011/03/13/grails-tip-configuring-embedded-tomcat-instance-used-in-developmenttest-env/
但是,context.xml 和 server.xml 文件是使用下拉库预编译的.从头开始创建 grails 应用程序时,我找不到两个文件中的任何一个.config.groovy 也是如此,因为它位于外部库中.
However, the context.xml and server.xml files are precompiled with the pulled down libraries. When creating a grails app from scratch, I cannot find either of there two files. Same is true for config.groovy, as it is located within an external library.
我正在尝试将 JNDI 资源注入容器,以便我可以调用它们.像这样:
I am trying to inject JNDI resources, into the container, so that I can invoke them. Something like this:
<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 目录中执行此操作的方法,但我也没有.
In the first link, the authors provide a way to do it in a scripts/_Events.groovy directory, but I do not have this either.
更新 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;
}
}
我在我的服务文件中这样调用这个源:
I am calling this source like this in my service file:
public DataSource getOneSource() {
Context context = (Context) new InitialContext().lookup("java:/comp/env")
oneSource= (DataSource) context.lookup("jdbc/oneSource")
return oneSource
}
但我收到一条错误消息:
But I am getting an error stating:
javax.naming.NameNotFoundException: Name [comp/env] is not bound in this Context. Unable to find [comp].
以前有人这样做过吗?如果有一个额外的线程覆盖了上下文,我不会感到惊讶.
Has anyone done this before? I would not be surprised if there is an extra thread that is overwriting the context.
推荐答案
此问题的解决方案分为两个步骤.首先,我必须使用 child 方法来设置正确的上下文,在这个问题中找到.在嵌入式中设置正确的上下文雄猫
The solution to this issue is addressed in two steps. First, I had to use the child approach to setting the right context, found in this question. Setting the right context in embedded Tomcat
正如想象的那样,我当时唯一要做的改变是对 getTomcatEmbeddedServletContainer 方法.我已将原件编辑为如下所示:
As imagined, The only change I then had to make was to the getTomcatEmbeddedServletContainer method. I have edited the original to look like this:
@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 构建文件现在包含:
Next, I had to edit the gradle build file, to include the dbcp BasicDataSource Dependency. My gradle build file now contains:
dependencies {
// Embedded tomcat dependencies
compile "org.apache.tomcat:tomcat-dbcp:9.0.0.M1"
}
这篇关于将 JNDI 添加到 Grails 3 中的嵌入式 Tomcat 服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!