我正在使用带有标准MySQL连接器API的Jetty 9.2(嵌入式),并且对应该如何设置它感到非常困惑。目前,我的 web.xml 文件中包含以下内容:
<webapp ... <resource-ref> <description>JDBC Data Source</description> <res-ref-name>jdbc/DataSource</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref> </webapp>
…这在我的jetty-env.xml中:
<Configure class="org.eclipse.jetty.webapp.WebAppContext"> <New id="DatabaseConnector" class="org.eclipse.jetty.plus.jndi.Resource"> <Arg></Arg> <Arg>jdbc/DataSource</Arg> <Arg> <New class="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource"> <Set name="Url">jdbc:mysql://localhost:3306/DBName</Set> <Set name="User">user</Set> <Set name="Password">pass</Set> </New> </Arg> </New> </Configure>
…然后执行以下代码初始化:
Context envCtx = (Context) new InitialContext().lookup("java:comp/env"); DataSource datasource = (DataSource) envCtx.lookup("jdbc/DataSource");
当我尝试启动服务器时,出现错误javax.naming.NameNotFoundException; remaining name 'jdbc/DataSource'。我已经在代码初始化中尝试了许多不同的字符串变体,例如删除了lookup对InitialContext对象的调用,但是我只是不断地获得相同错误的变体,只是name值不同。
javax.naming.NameNotFoundException; remaining name 'jdbc/DataSource'
lookup
InitialContext
name
这两个xml文件都位于我的/WAR/WEB-INF目录中。我查看了以前的问题和教程,博客等的大量内容,但是却一无所获。
/WAR/WEB-INF
这是嵌入式Jetty特有的问题的组合。
首先,在我实际启动Web服务器之前(即在调用之前),正在配置和启动Web服务器的启动器代码正在执行JNDI查找server.start(),因此在该阶段未初始化JNDI配置。
server.start()
但是,即使进行此更改也不起作用,因为envCtx.lookup("jdbc/DataSource")需要从与WebApp关联的线程中进行调用。因此,我将该代码移到了静态块,该静态块在Web服务器请求首次请求数据库连接时被调用。
envCtx.lookup("jdbc/DataSource")
最后,我在 启动器代码中得到了以下内容 :
public static void main(String[] args) { Server server = new Server(); //Enable parsing of jndi-related parts of web.xml and jetty-env.xml ClassList classlist = ClassList.setServerDefault(server); classlist.addAfter( "org.eclipse.jetty.webapp.FragmentConfiguration", "org.eclipse.jetty.plus.webapp.EnvConfiguration", "org.eclipse.jetty.plus.webapp.PlusConfiguration"); ... ... server.start();
无法通过该主线程进行JNDI查找,因此将其放置在类似于initservlet请求的方法的地方,或者像我一样,将其放置在servlet使用的静态数据库访问器类的同步方法中,例如
init
public class DatabaseUtils { private static DataSource datasource; private static synchronized Connection getDBConnection() throws SQLException { if (datasource == null) { initDataSource(); } return datasource.getConnection(); } public static void initDataSource() { try { datasource = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/DataSource"); LOG.info("Database connection pool initalized successfully"); } catch (Exception e) { LOG.error("Error while initialising the database connection pool", e); } }