下面列出了java.util.jar.JarFile#stream ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* loads both classes and other files at the same time
*/
public void loadFiles(JarFile jar) throws IOException {
long mem = Runtime.getRuntime().totalMemory();
if (mem / (double) maxMem > 0.75) {
JByteMod.LOGGER.warn("Memory usage is high: " + Math.round((mem / (double) maxMem * 100d)) + "%");
}
System.gc();
Map<String, ClassNode> classes = new HashMap<String, ClassNode>();
Map<String, byte[]> otherFiles = new HashMap<String, byte[]>();
Stream<JarEntry> str = jar.stream();
str.forEach(z -> readJar(jar, z, classes, otherFiles));
jar.close();
ja.setClasses(classes);
ja.setOutput(otherFiles);
return;
}
@Test
public void testClosedJarFile() throws IOException {
JarFile jf = new JarFile(new File(System.getProperty("test.src", "."), "input.jar"));
jf.close();
try {
Stream s = jf.stream();
fail("Should have thrown IllegalStateException");
} catch (IllegalStateException e) {
// expected;
}
}
@Test
public void testClosedJarFile() throws IOException {
JarFile jf = new JarFile(new File(System.getProperty("test.src", "."), "input.jar"));
jf.close();
try {
Stream s = jf.stream();
fail("Should have thrown IllegalStateException");
} catch (IllegalStateException e) {
// expected;
}
}
@Test
public void testClosedJarFile() throws IOException {
JarFile jf = new JarFile(new File(System.getProperty("test.src", "."), "input.jar"));
jf.close();
try {
Stream s = jf.stream();
fail("Should have thrown IllegalStateException");
} catch (IllegalStateException e) {
// expected;
}
}
/**
* Creates a map of <String(Class name), ClassNode> for a given jar file
*
* @param jarFile
* @author Konloch (Bytecode Viewer)
* @return
* @throws IOException
*/
public static Map<String, ClassNode> loadClasses(File jarFile) throws IOException {
Map<String, ClassNode> classes = new HashMap<String, ClassNode>();
JarFile jar = new JarFile(jarFile);
Stream<JarEntry> str = jar.stream();
// For some reason streaming = entries in messy jars
// enumeration = no entries
// Or if the jar is really big, enumeration = infinite hang
// ...
// Whatever. It works now!
str.forEach(z -> readJar(jar, z, classes, null));
jar.close();
return classes;
}
public static Map<String, ClassNode> loadRT() throws IOException {
Map<String, ClassNode> classes = new HashMap<String, ClassNode>();
JarFile jar = new JarFile(getRT());
Stream<JarEntry> str = jar.stream();
// TODO: Make ignoring these packages optional
str.forEach(z -> readJar(jar, z, classes, Arrays.asList("com/sun/", "com/oracle/", "jdk/", "sun/")));
jar.close();
return classes;
}
@Test
public void testClosedJarFile() throws IOException {
JarFile jf = new JarFile(new File(System.getProperty("test.src", "."), "input.jar"));
jf.close();
try {
Stream s = jf.stream();
fail("Should have thrown IllegalStateException");
} catch (IllegalStateException e) {
// expected;
}
}
/**
* Annotates the methods and method parameters in the classes in the given jar with the specified
* annotations.
*
* @param inputJar JarFile to annotate.
* @param jarOS OutputStream of the output jar file.
* @param nonnullParams Map from methods to their nonnull params.
* @param nullableReturns List of methods that return nullable.
* @param debug flag to output debug logs.
* @throws IOException if an error happens when reading or writing to jar or class streams.
*/
public static void annotateBytecodeInJar(
JarFile inputJar,
JarOutputStream jarOS,
MethodParamAnnotations nonnullParams,
MethodReturnAnnotations nullableReturns,
boolean stripJarSignatures,
boolean debug)
throws IOException {
BytecodeAnnotator.debug = debug;
LOG(debug, "DEBUG", "nullableReturns: " + nullableReturns);
LOG(debug, "DEBUG", "nonnullParams: " + nonnullParams);
// Do not use JarInputStream in place of JarFile/JarEntry. JarInputStream misses MANIFEST.MF
// while iterating over the entries in the stream.
// Reference: https://bugs.openjdk.java.net/browse/JDK-8215788
// Note: we can't just put the code below inside stream().forach(), because it can throw
// IOException.
for (JarEntry jarEntry : (Iterable<JarEntry>) inputJar.stream()::iterator) {
InputStream is = inputJar.getInputStream(jarEntry);
copyAndAnnotateJarEntry(
jarEntry,
is,
jarOS,
nonnullParams,
nullableReturns,
javaxNullableDesc,
javaxNonnullDesc,
stripJarSignatures);
}
}
/**
* Checks if the given jar file contains the expected annotations. The annotations that are
* expected are specified in the form of a map. For example: map = {"ExpectNullable;",
* "Ljavax/annotation/Nullable;"} will check if all methods and params contain
* "Ljavax/annotation/Nullable;" iff "ExpectNullable;" is present.
*
* @param jarFile Path to the input jar file.
* @param expectedToActualAnnotations Map from 'Expect*' annotations to the actual annotations
* that are expected to be present.
* @return True when the actual annotations that are expected to be present are present iff the
* 'Expect*' annotations are present.
* @throws IOException if an error happens when reading the jar file.
*/
public static boolean checkMethodAnnotationsInJar(
String jarFile, Map<String, String> expectedToActualAnnotations) throws IOException {
Preconditions.checkArgument(jarFile.endsWith(".jar"), "invalid jar file: " + jarFile);
JarFile jar = new JarFile(jarFile);
for (JarEntry entry : (Iterable<JarEntry>) jar.stream()::iterator) {
if (entry.getName().endsWith(".class")
&& !checkMethodAnnotationsInClass(
jar.getInputStream(entry), expectedToActualAnnotations)) {
return false;
}
}
return true;
}
@Test
public void testClosedJarFile() throws IOException {
JarFile jf = new JarFile(new File(System.getProperty("test.src", "."), "input.jar"));
jf.close();
try {
Stream s = jf.stream();
fail("Should have thrown IllegalStateException");
} catch (IllegalStateException e) {
// expected;
}
}
@Test
public void testClosedJarFile() throws IOException {
JarFile jf = new JarFile(new File(System.getProperty("test.src", "."), "input.jar"));
jf.close();
try {
Stream s = jf.stream();
fail("Should have thrown IllegalStateException");
} catch (IllegalStateException e) {
// expected;
}
}
@Test
public void testClosedJarFile() throws IOException {
JarFile jf = new JarFile(new File(System.getProperty("test.src", "."), "input.jar"));
jf.close();
try {
Stream s = jf.stream();
fail("Should have thrown IllegalStateException");
} catch (IllegalStateException e) {
// expected;
}
}
/**
* Creates a map of <String(Class name), ClassNode> for a given jar file
*
* @param jarFile
* @author Konloch (Bytecode Viewer)
* @return
* @throws IOException
*/
public static Map<String, ClassNode> loadClasses(File jarFile) throws IOException {
Map<String, ClassNode> classes = new HashMap<String, ClassNode>();
JarFile jar = new JarFile(jarFile);
Stream<JarEntry> str = jar.stream();
// For some reason streaming = entries in messy jars
// enumeration = no entries
// Or if the jar is really big, enumeration = infinite hang
// ...
// Whatever. It works now!
str.forEach(z -> readJar(jar, z, classes, null));
jar.close();
return classes;
}
public static Map<String, ClassNode> loadRT() throws IOException {
Map<String, ClassNode> classes = new HashMap<String, ClassNode>();
JarFile jar = new JarFile(getRT());
Stream<JarEntry> str = jar.stream();
// TODO: Make ignoring these packages optional
str.forEach(z -> readJar(jar, z, classes, Arrays.asList("com/sun/", "com/oracle/", "jdk/", "sun/")));
jar.close();
return classes;
}
@Test
public void testClosedJarFile() throws IOException {
JarFile jf = new JarFile(new File(System.getProperty("test.src", "."), "input.jar"));
jf.close();
try {
Stream s = jf.stream();
fail("Should have thrown IllegalStateException");
} catch (IllegalStateException e) {
// expected;
}
}
@Test
public void testClosedJarFile() throws IOException {
JarFile jf = new JarFile(new File(System.getProperty("test.src", "."), "input.jar"));
jf.close();
try {
Stream s = jf.stream();
fail("Should have thrown IllegalStateException");
} catch (IllegalStateException e) {
// expected;
}
}
@Test
public void testClosedJarFile() throws IOException {
JarFile jf = new JarFile(new File(System.getProperty("test.src", "."), "input.jar"));
jf.close();
try {
Stream s = jf.stream();
fail("Should have thrown IllegalStateException");
} catch (IllegalStateException e) {
// expected;
}
}
@Test
public void testClosedJarFile() throws IOException {
JarFile jf = new JarFile(new File(System.getProperty("test.src", "."), "input.jar"));
jf.close();
try {
Stream s = jf.stream();
fail("Should have thrown IllegalStateException");
} catch (IllegalStateException e) {
// expected;
}
}
@Test
public void testClosedJarFile() throws IOException {
JarFile jf = new JarFile(new File(System.getProperty("test.src", "."), "input.jar"));
jf.close();
try {
Stream s = jf.stream();
fail("Should have thrown IllegalStateException");
} catch (IllegalStateException e) {
// expected;
}
}
/**
* Returns a stream of versioned entries, derived from the base names of
* all entries in a multi-release {@code JarFile} that are present either in
* the base directory or in any versioned directory with a version number
* less than or equal to the {@code Runtime.Version::major} that the
* {@code JarFile} was opened with. These versioned entries are aliases
* for the real entries -- i.e. the names are base names and the content
* may come from a versioned directory entry. If the {@code jarFile} is not
* a multi-release jar, a stream of all entries is returned.
*
* @param jf the input JarFile
* @return stream of entries
* @since 9
*/
public static Stream<JarEntry> stream(JarFile jf) {
if (jf.isMultiRelease()) {
int version = jf.getVersion().major();
return jf.stream()
.map(je -> getBaseSuffix(je, version))
.filter(Objects::nonNull)
.distinct()
.map(jf::getJarEntry);
}
return jf.stream();
}