在grails 3.0中运行test-app或run- 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].
有人做过吗?如果有一个额外的线程正在覆盖上下文,我不会感到惊讶。
分两个步骤解决此问题的解决方案。首先,我不得不使用子方法来设置正确的上下文,这是在这个问题中发现的。在嵌入式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" }