Springboot 独立 JAR 应用程序的 JNDI 配置

时间:2020-12-31 15:33:54

标签: java spring-boot jndi

我用 Springboot 创建了一个 JAR 应用程序。 我在 Tomcat 服务器下启动了这个 JAR 应用程序。

有人问我用 JNDI 来检索存储在 Tomcat context.xml 中的数据源,说很简单。

我尝试使用以下代码来做到这一点。

Context initContext;
        try {
            initContext = new InitialContext();
            Context envContext = (Context) initContext.lookup("java:comp/env");
            DataSource ds = (DataSource) envContext.lookup("jdbc/mydatabase");
        } catch (NamingException e) {
            System.out.println("ERROR!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
            e.printStackTrace();
            System.out.println("ERROR!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
        }

但它不起作用。

我收到此错误:

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

解决这个问题的方法很简单吗?

或者使用我的 JAR 独立应用程序,仍然绝对不可能解决这个问题,就像先例帖子 Tomcat JNDI + Standalone Java 通知?

我看到很多帖子、很多文档,但我仍然不清楚。

感谢您的帮助和分享。

托马斯

2 个答案:

答案 0 :(得分:0)

Kedar 给我带来了答案。 我总结了 Kedar 的回答:

  • 使用 jar 命令行运行 JAR 应用程序时,我使用的是嵌入式 Tomcat
  • 当我使用嵌入式 Tomcat 时,可能无法访问我的 JNDI 数据源 这就是我的 JNDI 不起作用的原因。 我将尝试查看这篇文章来配置我的应用程序,以便尝试使用 JNDI: How to create JNDI context in Spring Boot with Embedded Tomcat Container 但是,现在,多亏了 Kedar,我才明白为什么我的 JNDI 代码不起作用。 如果可能的话,我将看到另一篇文章以了解如何配置无论如何使用 JNDI。 谢谢凯达尔。

答案 1 :(得分:0)

抱歉耽误了答复。

感谢 Kedar 告诉我 JNDI 不适用于 JAR,我尝试:

  • 在 Tomcat 服务器上读取 context.xml 文件
  • 从此 context.xml 文件中提取包含与数据库相关的所有属性的 XML 元素
  • 根据该数据库属性构造一个 DataSource 对象

也感谢 Mkyong 提供本教程: https://mkyong.com/java/how-to-read-xml-file-in-java-dom-parser/

这是我在 SpringBoot 下的工作代码:

@Configuration
public class ApplicationConfiguration {

/**
 * Absolute path of the configuration file named context.xml on any Tomcat Server (DEV, TEST, PROD).
 */
private final String CONTEXT_XML_PATH_ON_SERVER = "/opt/tomcat/apache-tomcat-version/conf/context.xml";

@Bean
@Primary
public DataSource dataSource() {
    try {
        Element datasourceElement = getDatasourceElementInTomcatContextXml();
        return DataSourceBuilder
                .create()
                .username(datasourceElement.getAttribute("username"))
                .password(datasourceElement.getAttribute("password"))
                .url(datasourceElement.getAttribute("url"))
                .driverClassName(datasourceElement.getAttribute("driverClassName"))
                .build();
    } catch (ParserConfigurationException e) {
        e.printStackTrace();
    } catch (SAXException | IOException e) {
        e.printStackTrace();
    }
    return null;
}

private Element getDatasourceElementInTomcatContextXml() throws ParserConfigurationException, SAXException, IOException {
    File contextXmlFile = new File(CONTEXT_XML_PATH_ON_SERVER);
    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
    Document doc = dBuilder.parse(contextXmlFile);
    //optional, but recommended
    //read this - http://stackoverflow.com/questions/13786607/normalization-in-dom-parsing-with-java-how-does-it-work
    doc.getDocumentElement().normalize();
    NodeList resourceElementList = doc.getElementsByTagName("Resource");
    Node nNode = resourceElementList.item(0);
    Element eElement = (Element) nNode;
    return eElement;
}

}

感谢 Kedar 和 Mkyong。

托马斯