JarTransformer { public void transform(@Nonnull ClassPath inputPath) throws IOException { SCAN: { for (ClassPathArchive inputArchive : inputPath) { LOG.debug("Scanning archive {}", inputArchive); for (ClassPathResource inputResource : inputArchive) { Transformable struct = newTransformable(inputResource); processor.scan(struct); } } } OUT: { Set<String> dirs = new HashSet<String>(); JarOutputStream outputJarStream = new JarOutputStream(new FileOutputStream(outputFile)); for (ClassPathArchive inputArchive : inputPath) { LOG.info("Transforming archive {}", inputArchive); for (ClassPathResource inputResource : inputArchive) { Transformable struct = newTransformable(inputResource); if (processor.process(struct) == JarProcessor.Result.DISCARD) continue; addDirs(outputJarStream, struct.name); if (DuplicatePolicy.DISCARD.equals(duplicatePolicy)) { if (!files.add(struct.name)) { LOG.debug("Discarding duplicate {}", struct.name); continue; } } LOG.debug("Writing {}", struct.name); JarEntry outputEntry = new JarEntry(struct.name); outputEntry.setTime(struct.time); outputEntry.setCompressedSize(-1); outputJarStream.putNextEntry(outputEntry); outputJarStream.write(struct.data); } } outputJarStream.close(); } } JarTransformer(@Nonnull File outputFile, @Nonnull JarProcessor processor); void transform(@Nonnull ClassPath inputPath);  }
@Test public void testTransformRename() throws Exception { processor.setSkipManifest(true); transformer.transform(classPath); Method m = getMethod(outputFile, "org.anarres.jarjar.testdata.pkg0.Main", "main", String[].class); m.invoke(null, (Object) new String[]{}); JarFile jarFile = new JarFile(outputFile); assertContains(jarFile, "org/anarres/jarjar/testdata/pkg0/Main.class"); assertContains(jarFile, "org/anarres/jarjar/testdata/pkg1/Cls1.class"); assertContains(jarFile, "org/anarres/jarjar/testdata/pkg2/Cls2.class"); assertContains(jarFile, "org/anarres/jarjar/testdata/pkg3/Cls3.class"); }