in plugins/engines/beam/src/main/java/org/apache/hop/beam/pipeline/fatjar/FatJarBuilder.java [82:267]
public void buildTargetJar() throws HopException {
fileContentMap = new HashMap<>();
classCollisionMap = new HashMap<>();
collisionFileSet = new HashSet<>();
fileSet = new HashSet<>();
// The real target file to write to...
//
String realTargetJarFile = variables.resolve(targetJarFile);
Indexer indexer = new Indexer();
try {
byte[] buffer = new byte[1024];
try (JarOutputStream zipOutputStream =
new JarOutputStream(new FileOutputStream(realTargetJarFile))) {
for (String jarFile : jarFiles) {
// Let's do a duplicate jar file check on the base name of the file
//
File jarFileFile = new File(jarFile);
String jarFileBaseName = jarFileFile.getName();
if (fileSet.contains(jarFileBaseName)) {
// Already processed
log.logDetailed("Skipping duplicate jar file: " + jarFile);
continue;
}
if (jarFileBaseName.contains("jersey-bundle")) {
// Skip this file
// TODO: replace this bundle by separate packages of a more recent jersey glassfish
// version
//
continue;
}
fileSet.add(jarFileBaseName);
try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(jarFile))) {
ZipEntry zipEntry = zipInputStream.getNextEntry();
while (zipEntry != null) {
try {
boolean skip = false;
boolean merge = false;
boolean index = false;
String entryName = zipEntry.getName();
if (zipEntry.isDirectory()) {
skip = true;
} else if (entryName.contains("META-INF/INDEX.LIST")) {
skip = true;
} else if (entryName.contains("META-INF/MANIFEST.MF")) {
skip = true;
} else if (entryName.startsWith(CONST_META_INF) && entryName.endsWith(".SF")) {
skip = true;
} else if (entryName.startsWith(CONST_META_INF) && entryName.endsWith(".DSA")) {
skip = true;
} else if (entryName.startsWith(CONST_META_INF) && entryName.endsWith(".RSA")) {
skip = true;
} else if (entryName.startsWith("META-INF/services/")) {
merge = true;
skip = true;
}
// Skip module metadata in */module-info.class
else if (entryName.endsWith("module-info.class")) {
skip = true;
}
// Skip module metadata in */package-info.class
else if (entryName.endsWith("package-info.class")) {
skip = true;
}
// Spark has UnusedStubClass.class in every library
//
else if (entryName.endsWith("UnusedStubClass.class")) {
skip = true;
}
// Skip because we rebuild a new one from cache
else if (entryName.endsWith("META-INF/jandex.idx")) {
skip = true;
} else if (entryName.endsWith(".class")) {
index = true;
// Is this class file already in the fat jar?
//
String otherJar = classCollisionMap.get(entryName);
if (otherJar != null) {
skip = true;
// Did we already warn about this?
if (!collisionFileSet.contains(jarFile)) {
collisionFileSet.add(jarFile);
log.logDetailed(
"Duplicate class(es) detected in " + jarFile + " from : " + otherJar);
log.logDetailed(" Example class: " + entryName);
}
} else {
log.logDebug("Adding class " + entryName + " for " + jarFile);
classCollisionMap.put(entryName, jarFile);
}
}
// Nothing to index in guava as it gives an error for some reason
//
if (zipEntry.getName().contains("$") // skip anonymous inner classes
|| jarFileBaseName.startsWith("guava")
|| jarFileBaseName.startsWith("akka-")
|| jarFileBaseName.startsWith("scala-")
|| jarFileBaseName.startsWith("flink-runtime")
|| jarFileBaseName.startsWith("beam-sdks-java-io")
|| jarFileBaseName.startsWith("beam-runners-spark")
|| jarFileBaseName.startsWith("beam-runners-direct")
|| jarFileBaseName.startsWith("beam-runners-flink")
|| jarFileBaseName.startsWith("beam-sdks-java-core")
|| jarFileBaseName.startsWith("beam-runners-core")) {
index = false;
}
if (!skip) {
try {
zipOutputStream.putNextEntry(new ZipEntry(zipEntry.getName()));
} catch (ZipException ze) {
// Duplicate entry!
//
skip = true;
}
}
if (merge) {
String fileContent = IOUtils.toString(zipInputStream, StandardCharsets.UTF_8);
fileContentMap.merge(entryName, fileContent, (a, b) -> a + Const.CR + b);
} else if (!skip) {
int len;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while ((len = zipInputStream.read(buffer)) > 0) {
zipOutputStream.write(buffer, 0, len);
if (index) {
baos.write(buffer, 0, len);
}
}
if (index) {
indexer.index(new ByteArrayInputStream(baos.toByteArray()));
}
}
zipInputStream.closeEntry();
if (!skip) {
zipOutputStream.closeEntry();
}
zipEntry = zipInputStream.getNextEntry();
} catch (Exception e) {
throw new HopException("Error adding jar file entry: " + zipEntry.getName(), e);
}
}
} catch (Exception e) {
throw new HopException("Error adding jar file: " + jarFile, e);
}
}
// Add the META-INF/services files...
//
for (String entryName : fileContentMap.keySet()) {
String fileContent = fileContentMap.get(entryName);
zipOutputStream.putNextEntry(new ZipEntry(entryName));
zipOutputStream.write(fileContent.getBytes(StandardCharsets.UTF_8));
zipOutputStream.closeEntry();
}
// Add META-INF/jandex.idx file
//
log.logBasic("Adding Jandex index");
zipOutputStream.putNextEntry(new ZipEntry(JarCache.ANNOTATION_INDEX_LOCATION));
IndexWriter indexWriter = new IndexWriter(zipOutputStream);
indexWriter.write(indexer.complete());
zipOutputStream.closeEntry();
}
} catch (Exception e) {
throw new HopException("Unable to build far jar file '" + realTargetJarFile + "'", e);
} finally {
fileContentMap.clear();
}
}