如何找到已部署 Java EE 应用程序的父目录?

How to find the parent directory of a deployed Java EE application?

我有一个 Java EE 项目,我将把它变成一个 war 文件。当它运行时,它会生成一个日志文件,我希望该文件在与 war 文件相同的父目录中生成。比如我的war文件是:

C:\project.war

那么我的日志文件的路径将是:

C:\log.txt

但是我发现的只是如何在项目中找到资源。如何在生成日志文件之前找到我的项目的父目录?

你不应该依赖这样的路径。当您将创建的 WAR 分发给某人进行部署时,它可能会部署在完全不同的路径上。它可以部署为 WAR 存档或展开的目录。目标应用程序服务器(Tomcat、JBoss、WebLogic 等)可能会以不同的方式执行此操作,并且做出隐式假设,例如相对于 WAR 部署路径的日志文件路径,在您的直接部署路径之外将不起作用开发环境。另外,Java EE 不会让您访问 WAR 的部署目录的物理位置,仅仅是因为它不知道它(同样,因为 how WAR 的部署不是 Java EE 规范的一部分,而是留给实施者,例如 Tomcat、JBoss...)。

在我看来,正确的方法是创建一个可以保存在类路径中的属性文件,并将日志文件目录的 属性 放入属性文件中,以便可以读取应用程序在运行时将日志发送到该文件。有关更多见解,请参阅 Reading Properties file

    Properties props = ...; // the link above will help you get the properties
    String logDir = props.getProperty("log.dir", "/tmp"); // /tmp is default

    // logDir cannot be null
    File logFile = new File(logDir, "application.log"); 

    // make sure the directories are created if did not exist previously
    logFile.getParent().mkdirs(); 

    // write log statements to logFile
    ...

或者,特别是对于日志记录,您可以查看许多 API(包括 JDK)提供的开箱即用机制来记录。

当然,如果你真的需要使用物理目录,你可以做这样的事情来访问应用程序服务器(部署 WAR 文件)启动的目录:

File f = new File("."); // f is the current directory; where the JVM was launched
System.out.println(f.getAbsolutePath()); 

一旦你有了 'f',你就可以从中推导出其他路径。同样,这不是一个好主意,我会留给您来决定是否应该使用这种方法。

与其尝试获取与应用程序相关的文件,不如尝试使用绝对路径来引用文件。对于跨平台解决方案,请使用 JNDI。

在您 Tomcat 的 context.xml 文件中声明以下内容:

<Context>
    <Environment name="logLocation" value="C:/logs/log.txt" type="java.lang.String"/>
</Context>

获取 logLocation 使用:

InitialContext initialContext = new InitialContext(); 
Context environmentContext = (Context) initialContext.lookup("java:/comp/env");
String logLocation = (String) environmentContext.lookup("logLocation");

然后获取您的文件:

File file = new File(logLocation);