【问题标题】:Getting the absolute path of a file within a JAR within an EAR?在 EAR 中获取 JAR 中文件的绝对路径?
【发布时间】:2009-04-27 00:32:22
【问题描述】:

我有一个作为 EAR 文件部署的 J2EE 应用程序,该文件又包含一个用于业务层代码(包括一些 EJB)的 JAR 文件和一个用于 Web 层代码的 WAR 文件。 EAR 文件部署到 JBoss 3.2.5,它解压了 EAR 和 WAR 文件,但不解压 JAR 文件(这不是问题,仅供参考)。

JAR 文件中的一个文件是一个 MS Word 模板,其绝对路径需要传递给一些本机 MS Word 代码(使用Jacob,FWIW)。

问题是,如果我尝试获取这样的文件(从 JAR 文件中的某些代码中):

URL url = getClass().getResource("myTemplate.dot");
File file = new File(url.toURI()); // <= fails!
String absolutePath = file.getAbsolutePath();
// Pass the absolutePath to MS Word to be opened as a document

... 然后java.io.File 构造函数抛出 IllegalArgumentException “URI 不是分层的”。 URL 和 URI 都有相同的 toString() 输出,即:

jar:file:/G:/jboss/myapp/jboss/server/default/tmp/deploy/tmp29269myapp.ear-contents/myapp.jar!/my/package/myTemplate.dot

这大部分路径在文件系统上是有效的,但其余的则不是(在 JAR 文件内部):

G:/jboss/myapp/jboss/server/default/tmp/deploy/tmp29269myapp.ear-contents

获取此文件的绝对路径的最简单方法是什么?

【问题讨论】:

    标签: java file jakarta-ee path jar


    【解决方案1】:

    我目前的解决方案是将文件复制到服务器的临时目录,然后使用复制的绝对路径:

    File tempDir = new File(System.getProperty("java.io.tmpdir"));
    File temporaryFile = new File(tempDir, "templateCopy.dot");
    InputStream templateStream = getClass().getResourceAsStream("myTemplate.dot");
    IOUtils.copy(templateStream, new FileOutputStream(temporaryFile));
    String absolutePath = temporaryFile.getAbsolutePath();
    

    我更喜欢不涉及复制文件的解决方案。

    【讨论】:

    • 当我发现这个问题时,我的第一个想法是“是的,也许唯一的办法就是写一个临时文件!”。令人惊讶的是,这是唯一的方法!怎么可能无法处理 jar 中的路径?如果你能得到流,你就能得到文件,在一个完美的世界里。
    • EJB 规范的第 21.2.2 节:The enterprise bean must not attempt to create a class loader; obtain the current class loader; set the context class loader; set security manager; create a new security manager; stop the JVM; or change the input, output, and error streams. 这值得 -1
    • 你认为它在做什么?
    【解决方案2】:

    除非您传递 URI 字符串以接受指定 jar/zip 文件中位置的格式的代码或应用程序,否则将文件复制到临时位置的解决方案可能是最好的解决方案。

    如果经常引用这些文件,您可能希望缓存提取文件的位置,并在每次需要时验证它们的存在。

    【讨论】:

    • 谢谢克里斯。我很确定 Word 需要一个绝对路径,并且会被 JAR/ZIP 样式的路径弄糊涂。我确实懒惰地将原始文件复制到临时文件夹,为了简洁起见,我只是将其排除在我的答案之外。
    【解决方案3】:

    您应该将内容复制到临时文件(可能带有缓存),因为尝试访问应用程序容器的内部文件是您要避免的依赖项。甚至可能根本没有提取的文件(可以直接从 JAR 加载)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-26
      • 1970-01-01
      • 2012-04-24
      • 2018-11-11
      • 2010-09-18
      相关资源
      最近更新 更多