Project structure:
JavaScript
x
src
|
|--resource
|
|--PMD
|-pmd-bin
|-test.bat
|-report
|-report.xml
|
|--staticresource
Using maven-assembly
plugin, I am including the resources in the jar file.
As PMD folder will be used by the applcaition, I would like to create a copy of the PMD folder in the temp directory, so that I can start reading the bat files and other files from that temp directory.
ISSUE
When the jar loads, it fails to read the PMD folder inside resource.
Tried :
JavaScript
InputStream pmdFolder = classLoader.getResourceAsStream("PMD");
InputStreamReader isr = new InputStreamReader(pmdFolder, StandardCharsets.UTF_8);
BufferedReader br = new BufferedReader(isr);
List<URL> collect = br.lines().map(l -> "PMD" + "/" + l)
.map(r -> classLoader.getResource(r))
.collect(toList());
Path tempPMDFolder = null;
Path pmd = Files.createTempDirectory("PMD");
for (URL url : collect) {
System.out.println(url.toString());
createSameTempStructure(url, pmd);
}
private static void createSameTempStructure(URL url, Path pmd) throws IOException {
//tempPMDFolder.toFile().deleteOnExit();
try(final InputStream is = url.openStream()) {
File file = FileUtils.toFile(url);
System.out.println("file -> "+file.getName());
if(file.isDirectory()){
Path tempPMDFolder = createTempPMDFolder(pmd, file.getName());
System.out.println("tempPMDFolder -> "+tempPMDFolder.toString());
FileUtils.copyDirectory(file, tempPMDFolder.toFile());
} else {
try (OutputStream outputStream = new FileOutputStream(file)) {
IOUtils.copy(is, outputStream);
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
}
Here it just creates the PMD folder in temp directory and nothing, inner files and folders are not copied. Any way we can achieve this?
Advertisement
Answer
Here is what I came up with.
Converted the folder to zip
and put that zipped file in resources.
As inputstream can only read through a file.
JavaScript
InputStream pmdFolder = classLoader.getResourceAsStream("PMD.zip");
Path tempPMDDirectory = Files.createTempDirectory("PMD");
Then extracted the zip contents to the temp directory and then using that overall application.
JavaScript
if (pmdFolder != null) {
try (ZipInputStream zipInputStream = new ZipInputStream(pmdFolder)) {
// Extract the zip contents and keep in temp directory
extract(zipInputStream, tempPMDDirectory.toFile());
}
}
public static void extract(ZipInputStream zip, File target) throws IOException {
try {
ZipEntry entry;
while ((entry = zip.getNextEntry()) != null) {
File file = new File(target, entry.getName());
if (!file.toPath().normalize().startsWith(target.toPath())) {
throw new IOException("Bad zip entry");
}
if (entry.isDirectory()) {
file.mkdirs();
continue;
}
byte[] buffer = new byte[BUFFER_SIZE];
file.getParentFile().mkdirs();
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
int count;
while ((count = zip.read(buffer)) != -1) {
out.write(buffer, 0, count);
}
out.close();
}
} finally {
zip.close();
}
}