in src/main/java/org/apache/maven/plugins/shade/DefaultShader.java [572:634]
private void addRemappedClass(
JarOutputStream jos, File jar, String name, long time, InputStream is, DefaultPackageMapper packageMapper)
throws IOException, MojoExecutionException {
if (packageMapper.relocators.isEmpty()) {
try {
JarEntry entry = new JarEntry(name);
entry.setTime(time);
jos.putNextEntry(entry);
IOUtil.copy(is, jos);
} catch (ZipException e) {
logger.debug("We have a duplicate " + name + " in " + jar);
}
return;
}
// Keep the original class, in case nothing was relocated by ShadeClassRemapper. This avoids binary
// differences between classes, simply because they were rewritten and only details like constant pool or
// stack map frames are slightly different.
byte[] originalClass = IOUtil.toByteArray(is);
ClassReader cr = new ClassReader(new ByteArrayInputStream(originalClass));
// We don't pass the ClassReader here. This forces the ClassWriter to rebuild the constant pool.
// Copying the original constant pool should be avoided because it would keep references
// to the original class names. This is not a problem at runtime (because these entries in the
// constant pool are never used), but confuses some tools such as Felix' maven-bundle-plugin
// that use the constant pool to determine the dependencies of a class.
ClassWriter cw = new ClassWriter(0);
final String pkg = name.substring(0, name.lastIndexOf('/') + 1);
final ShadeClassRemapper cv = new ShadeClassRemapper(cw, pkg, packageMapper);
try {
cr.accept(cv, ClassReader.EXPAND_FRAMES);
} catch (Throwable ise) {
throw new MojoExecutionException("Error in ASM processing class " + name, ise);
}
// If nothing was relocated by ShadeClassRemapper, write the original class, otherwise the transformed one
final byte[] renamedClass;
if (cv.remapped) {
logger.debug("Rewrote class bytecode: " + name);
renamedClass = cw.toByteArray();
} else {
logger.debug("Keeping original class bytecode: " + name);
renamedClass = originalClass;
}
// Need to take the .class off for remapping evaluation
String mappedName = packageMapper.map(name.substring(0, name.indexOf('.')), true, false);
try {
// Now we put it back on so the class file is written out with the right extension.
JarEntry entry = new JarEntry(mappedName + ".class");
entry.setTime(time);
jos.putNextEntry(entry);
jos.write(renamedClass);
} catch (ZipException e) {
logger.debug("We have a duplicate " + mappedName + " in " + jar);
}
}