How to load/find a JAR resource from inside GMaven script?

764 views Asked by At

This is my gmaven script, which is trying to find and load a file located somewhere inside the provided dependency (it's a section of pom.xml):

[...]
<plugin>
  <groupId>org.codehaus.gmaven</groupId>
  <artifactId>gmaven-plugin</artifactId>
  <executions>
    <execution>
      <configuration>
        <source>
          <![CDATA[
          def File = // how to get my-file.txt?
          ]]>
        </source>
      </configuration>
    </execution>
  </executions>
  <dependencies>
    <dependency>
      <groupId>my-group</groupId>
      <artifactId>my-artifact</artifactId>
      <version>1.0</version>
    </dependency>
  </dependencies>
</plugin>
[...]

The my-file.txt is located in my-group:my-artifact:1.0 JAR file.

3

There are 3 answers

0
yegor256 On BEST ANSWER

The answer is very simple:

def url = getClass().getClassLoader().getResource("my-file.txt");

Then the URL will be in the following format:

jar:file:/usr/me/.m2/repository/grp/art/1.0-SNAPSHOT/art.jar!/my-file.tex

The rest is trivial.

1
Sean Patrick Floyd On

If the file is in the Jar, then it's technically not a file, but a Jar entry. Which means you have these possibilities:

6
AdamH On

I'm not sure how to resolve the path to a jar to an external repository, but assuming the jar is in your local repository then you should have access to that via the settings.localRepository implicit variable. You then known your group and artifact id already, so the path to your jar, in this case would be settings.localRepository + "/my-group/my-artifact/1.0/my-artifact-1.0.jar"

This code should allow you to read in the jar file and get the text file from it. Note I wouldn't normally write this code to read a file into a byte[] myself, I just put it here for completeness. Ideally use something from apache commons or a similar library to do it:

    def file = null
    def fileInputStream = null
    def jarInputStream = null
    try {
        //construct this with the path to your jar file. 
        //May want to use a different stream, depending on where it's located
        fileInputStream = new FileInputStream("$settings.localRepository/my-group/my-artifact/1.0/my-artifact-1.0.jar")
        jarInputStream = new JarInputStream(fileInputStream)

        for (def nextEntry = jarInputStream.nextEntry; (nextEntry != null) && (file == null); nextEntry = jarInputStream.nextEntry) {
            //each entry name will be the full path of the file, 
            //so check if it has your file's name
            if (nextEntry.name.endsWith("my-file.txt")) {
                file = new byte[(int) nextEntry.size]
                def offset = 0
                def numRead = 0
                while (offset < file.length && (numRead = jarInputStream.read(file, offset, file.length - offset)) >= 0) {
                  offset += numRead
                }
            }
        }
    }
    catch (IOException e) {
        throw new RuntimeException(e)
    }
    finally {
        jarInputStream.close()
        fileInputStream.close()
    }