Getting the absolute path of a file within a JAR within an EAR?

17,792

Solution 1

My current solution is to copy the file to the server's temporary directory, then use the absolute path of the copy:

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();

I'd prefer a solution that doesn't involve copying the file.

Solution 2

Unless the code or application you are passing the URI String to accepts a format that specifies a location within a jar/zip file, your solution of copying the file to a temporary location is probably the best one.

If these files are referenced often, you may want to cache the locations of the extract files and just verify their existance each time they are needed.

Share:
17,792
juckele
Author by

juckele

Senior developer on the JIRA team with Atlassian.

Updated on June 13, 2022

Comments

  • juckele
    juckele almost 2 years

    I have a J2EE app deployed as an EAR file, which in turn contains a JAR file for the business layer code (including some EJBs) and a WAR file for the web layer code. The EAR file is deployed to JBoss 3.2.5, which unpacks the EAR and WAR files, but not the JAR file (this is not the problem, it's just FYI).

    One of the files within the JAR file is an MS Word template whose absolute path needs to be passed to some native MS Word code (using Jacob, FWIW).

    The problem is that if I try to obtain the File like this (from within some code in the JAR file):

    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
    

    ... then the java.io.File constructor throws the IllegalArgumentException "URI is not hierarchical". The URL and URI both have the same toString() output, namely:

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

    This much of the path is valid on the file system, but the rest is not (being internal to the JAR file):

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

    What's the easiest way of getting the absolute path to this file?

  • juckele
    juckele about 15 years
    Thanks Chris. I'm pretty sure Word needs an absolute path, and would be confused by a JAR/ZIP-style path. I am indeed lazy-copying the original file to the temp folder, I just left that out of my answer for the sake of brevity.
  • Federico Giorgi
    Federico Giorgi about 13 years
    When I found this problem, my first idea was "yeah, maybe the only way is to write a temporary file!". And surprise, it IS the only way! How can it be that there is no way to handle a path within a jar? If you can get the stream, you can get the File, in a perfect world.
  • searchengine27
    searchengine27 about 5 years
    Section 21.2.2 of the EJB spec: 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. This deserves a -1
  • juckele
    juckele about 5 years
    Which one of those do you think it is doing?