我的Java EE 7应用程序使用Spring,在Tomcat 7上运行.它使用JNDI数据源访问数据库,该数据源由context.xml中的此行定义:
我创建了一些JUnit测试.当我尝试运行它们时(在Eclipse中,通过右键单击测试类并选择Run As | JUnit Test),发生了异常:
javax.persistence.PersistenceException: [PersistenceUnit: leadmanager] Unable to build EntityManagerFactory ... Caused by: org.hibernate.service.jndi.JndiException: Error parsing JNDI name [java:/comp/env/jdbc/leadmanager] ... Caused by: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial ...
感谢这篇有用的帖子 - https://blogs.oracle.com/randystuph/entry/injecting_jndi_datasources_for_junit - 我找到了一个解决方案.我把它添加到我的测试类中:
@BeforeClass public static void setUpClass() throws Exception { // create initial context System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory"); System.setProperty(Context.URL_PKG_PREFIXES, "org.apache.naming"); InitialContext ic = new InitialContext(); ic.createSubcontext("java:"); ic.createSubcontext("java:/comp"); ic.createSubcontext("java:/comp/env"); ic.createSubcontext("java:/comp/env/jdbc"); PGPoolingDataSource ds = new PGPoolingDataSource(); ds.setServerName("localhost:5432/leadmanager"); ds.setUser("postgres"); ds.setPassword("xxxxxxxx"); ic.bind("java:/comp/env/jdbc/leadmanager", ds); }
但那太可怕了!我被迫两次定义我的数据源,一次在context.xml中,另一次在我的测试类中.而且我被迫将我的数据库密码存储在Java代码中,该代码将被检入源代码控制.
我已经查阅了这篇文章:在jUnit中设置JNDI数据源
有没有更好的办法?