How to load/find a JAR resource from inside GMaven script?
-
12-10-2020 - |
Question
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.
Solution
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.
OTHER TIPS
If the file is in the Jar, then it's technically not a file, but a Jar entry. Which means you have these possibilities:
- Load it as an
InputStream
using either the ClassLoader or manual Jar processing - Extract it to a file (perhaps with
dependency:unpack
ordependency:unpack-dependencies
)
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()
}