下面列出了怎么用java.util.jar.JarFile的API类实例代码及写法,或者点击链接到github查看源代码。
protected void scanBootstrapDependency(File file) {
try (JarFile jar = new JarFile(file)) {
ZipEntry entry = jar.getEntry("wildfly-swarm-bootstrap.conf");
if (entry != null) {
try (InputStream in = jar.getInputStream(entry)) {
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line = null;
while ((line = reader.readLine()) != null) {
line = line.trim();
if (!line.isEmpty()) {
this.bootstrapModules.add(line);
}
}
}
}
} catch (IOException e) {
}
}
@Test(expected = UnsupportedOperationException.class)
public void whenJarMemberWithEmptyManifestIsQueriedThenThrow() throws IOException {
Assume.assumeFalse(fileHashCacheMode == FileHashCacheMode.PARALLEL_COMPARISON);
Assume.assumeFalse(fileHashCacheMode == FileHashCacheMode.LIMITED_PREFIX_TREE_PARALLEL);
ProjectFilesystem filesystem = new FakeProjectFilesystem();
DefaultFileHashCache cache =
DefaultFileHashCache.createDefaultFileHashCache(filesystem, fileHashCacheMode);
Path abiJarPath = Paths.get("empty-manifest.jar");
Path memberPath = Paths.get("Empty.class");
try (CustomZipOutputStream jar =
ZipOutputStreams.newOutputStream(filesystem.newFileOutputStream(abiJarPath))) {
jar.writeEntry(JarFile.MANIFEST_NAME, new ByteArrayInputStream(new byte[0]));
jar.writeEntry(
memberPath.toString(),
new ByteArrayInputStream("Contents".getBytes(StandardCharsets.UTF_8)));
}
cache.getForArchiveMember(abiJarPath, memberPath);
}
static void checkTimestamp(String file, String policyId, String digestAlg)
throws Exception {
try (JarFile jf = new JarFile(file)) {
JarEntry je = jf.getJarEntry("META-INF/OLD.RSA");
try (InputStream is = jf.getInputStream(je)) {
byte[] content = IOUtils.readFully(is, -1, true);
PKCS7 p7 = new PKCS7(content);
SignerInfo[] si = p7.getSignerInfos();
if (si == null || si.length == 0) {
throw new Exception("Not signed");
}
PKCS9Attribute p9 = si[0].getUnauthenticatedAttributes()
.getAttribute(PKCS9Attribute.SIGNATURE_TIMESTAMP_TOKEN_OID);
PKCS7 tsToken = new PKCS7((byte[]) p9.getValue());
TimestampToken tt =
new TimestampToken(tsToken.getContentInfo().getData());
if (!tt.getHashAlgorithm().toString().equals(digestAlg)) {
throw new Exception("Digest alg different");
}
if (!tt.getPolicyID().equals(policyId)) {
throw new Exception("policyId different");
}
}
}
}
/**
* Extract the source {@link JarFile} to target directory with specified {@link JarEntryFilter}
*
* @param jarResourceURL
* The resource URL of {@link JarFile} or {@link JarEntry}
* @param targetDirectory
* target directory
* @param jarEntryFilter
* {@link JarEntryFilter}
* @throws IOException
* When the source jar file is an invalid {@link JarFile}
*/
public static void extract(URL jarResourceURL, File targetDirectory, JarEntryFilter jarEntryFilter) throws IOException {
final JarFile jarFile = JarUtils.toJarFile(jarResourceURL);
final String relativePath = JarUtils.resolveRelativePath(jarResourceURL);
final JarEntry jarEntry = jarFile.getJarEntry(relativePath);
final boolean isDirectory = jarEntry.isDirectory();
List<JarEntry> jarEntriesList = filter(jarFile, new JarEntryFilter() {
@Override
public boolean accept(JarEntry filteredObject) {
String name = filteredObject.getName();
if (isDirectory && name.equals(relativePath)) {
return true;
} else if (name.startsWith(relativePath)) {
return true;
}
return false;
}
});
jarEntriesList = doFilter(jarEntriesList, jarEntryFilter);
doExtract(jarFile, jarEntriesList, targetDirectory);
}
private static List<Class<?>> getClassesFromJar(URL url, String basePack) throws IOException, ClassNotFoundException {
List<Class<?>> classes = new ArrayList<>();
JarURLConnection connection = (JarURLConnection) url.openConnection();
if (connection != null) {
JarFile jarFile = connection.getJarFile();
if (jarFile != null) {
//得到该jar文件下面的类实体
Enumeration<JarEntry> jarEntryEnumeration = jarFile.entries();
while (jarEntryEnumeration.hasMoreElements()) {
JarEntry entry = jarEntryEnumeration.nextElement();
String jarEntryName = entry.getName();
//这里我们需要过滤不是class文件和不在basePack包名下的类
if (jarEntryName.contains(".class") && jarEntryName.replaceAll("/", ".").startsWith(basePack)) {
String className = jarEntryName.substring(0, jarEntryName.lastIndexOf(".")).replace("/", ".");
Class cls = Class.forName(className);
classes.add(cls);
}
}
}
}
return classes;
}
public int getVersion() throws IOException
{
try (JarFile jar = new JarFile(this.jar))
{
for (Enumeration<JarEntry> it = jar.entries(); it.hasMoreElements();)
{
JarEntry entry = it.nextElement();
if (!entry.getName().equals("client.class"))
continue;
InputStream in = jar.getInputStream(entry);
ClassReader reader = new ClassReader(in);
VersionClassVisitor v = new VersionClassVisitor();
reader.accept(v, 0);
return v.getVersion();
}
}
return -1;
}
public static InputStream getInputStream(String fname, JarFile jarFile,
JspCompilationContext ctxt, ErrorDispatcher err)
throws JasperException, IOException {
InputStream in = null;
if (jarFile != null) {
String jarEntryName = fname.substring(1, fname.length());
ZipEntry jarEntry = jarFile.getEntry(jarEntryName);
if (jarEntry == null) {
throw new FileNotFoundException(Localizer.getMessage(
"jsp.error.file.not.found", fname));
}
in = jarFile.getInputStream(jarEntry);
} else {
in = ctxt.getResourceAsStream(fname);
}
if (in == null) {
throw new FileNotFoundException(Localizer.getMessage(
"jsp.error.file.not.found", fname));
}
return in;
}
static void copyJarFile(JarInputStream in, JarOutputStream out) throws IOException {
if (in.getManifest() != null) {
ZipEntry me = new ZipEntry(JarFile.MANIFEST_NAME);
out.putNextEntry(me);
in.getManifest().write(out);
out.closeEntry();
}
byte[] buffer = new byte[1 << 14];
for (JarEntry je; (je = in.getNextJarEntry()) != null; ) {
out.putNextEntry(je);
for (int nr; 0 < (nr = in.read(buffer)); ) {
out.write(buffer, 0, nr);
}
}
in.close();
markJarFile(out); // add PACK200 comment
}
static void copyJarFile(JarInputStream in, JarOutputStream out) throws IOException {
if (in.getManifest() != null) {
ZipEntry me = new ZipEntry(JarFile.MANIFEST_NAME);
out.putNextEntry(me);
in.getManifest().write(out);
out.closeEntry();
}
byte[] buffer = new byte[1 << 14];
for (JarEntry je; (je = in.getNextJarEntry()) != null; ) {
out.putNextEntry(je);
for (int nr; 0 < (nr = in.read(buffer)); ) {
out.write(buffer, 0, nr);
}
}
in.close();
markJarFile(out); // add PACK200 comment
}
public static void compareJars(JarFile jf1, JarFile jf2) throws Exception {
try {
if (jf1.size() != jf2.size()) {
throw new Exception("Jars " + jf1.getName() + " and " + jf2.getName()
+ " have different number of entries");
}
for (JarEntry elem1 : Collections.list(jf1.entries())) {
JarEntry elem2 = jf2.getJarEntry(elem1.getName());
if (elem2 == null) {
throw new Exception("Element " + elem1.getName() + " is missing from " + jf2.getName());
}
if (!elem1.isDirectory() && elem1.getCrc() != elem2.getCrc()) {
throw new Exception("The crc of " + elem1.getName() + " is different.");
}
}
} finally {
jf1.close();
jf2.close();
}
}
public static void main(String args[]) throws IOException {
JarFile bootclasses = new JarFile("BootSupport.jar");
JarFile agentclasses = new JarFile("AgentSupport.jar");
Instrumentation ins = Agent.getInstrumentation();
// Test 1: Add BootSupport.jar to boot class path and check that
// BootSupport is loaded by the bootstrap class loader
ins.appendToBootstrapClassLoaderSearch(bootclasses);
checkLoadedByLoader("BootSupport", null);
// Test 2: Add AgentSupport.jar to the system class path and check that
// AgentSupport is loaded by the system class loader.
try {
ins.appendToSystemClassLoaderSearch(agentclasses);
checkLoadedByLoader("AgentSupport", ClassLoader.getSystemClassLoader());
} catch (UnsupportedOperationException x) {
System.out.println("System class loader does not support adding to class path");
}
// throw exception if a test failed
if (failures > 0) {
throw new RuntimeException(failures + " test(s) failed.");
}
}
private void findClasses(List<Class<?>> classList, String packageName, URL url, boolean recursive) throws Throwable {
JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();
JarFile jarFile = jarURLConnection.getJarFile();
Enumeration<JarEntry> jarEntries = jarFile.entries();
// jarCount.incrementAndGet();
// LOGGER.info("Scanning jar: " + jarFile.getName());
while (jarEntries.hasMoreElements()) {
try {
JarEntry jarEntry = jarEntries.nextElement();
String jarEntryName = jarEntry.getName();
String jarEntryClassName = getClassName(jarEntryName);
if (jarEntryClassName != null) {
String jarEntryPackageName = getPackageName(jarEntryClassName);
if (jarEntryPackageName.equals(packageName) ||
(recursive && jarEntryPackageName.startsWith(packageName))) {
tryAddClass(classList, jarEntryClassName);
}
}
} catch (Throwable t) {
LOGGER.warn(t.getMessage(), t);
}
}
}
static void generateLargeJar(File result, File source) throws IOException {
if (result.exists()) {
result.delete();
}
try (JarOutputStream copyTo = new JarOutputStream(new FileOutputStream(result));
JarFile srcJar = new JarFile(source)) {
for (JarEntry je : Collections.list(srcJar.entries())) {
copyTo.putNextEntry(je);
if (!je.isDirectory()) {
copyStream(srcJar.getInputStream(je), copyTo);
}
copyTo.closeEntry();
}
int many = Short.MAX_VALUE * 2 + 2;
for (int i = 0 ; i < many ; i++) {
JarEntry e = new JarEntry("F-" + i + ".txt");
copyTo.putNextEntry(e);
}
copyTo.flush();
copyTo.close();
}
}
@Test
public void testEmpty() throws PackagingException, IOException {
AbstractVertxMojo mojo = mock(AbstractVertxMojo.class);
when(mojo.getLog()).thenReturn(new SystemStreamLog());
Archive archive = new Archive();
archive.setIncludeClasses(false);
File output = new File(out, "test-empty.jar");
PackageConfig config = new PackageConfig()
.setMojo(mojo)
.setOutput(output)
.setArchive(archive);
service.doPackage(config);
assertThat(output).isFile();
JarFile jar = new JarFile(output);
List<String> list = jar.stream().map(ZipEntry::getName)
.filter(s -> ! s.endsWith("/")) // Directories
.collect(Collectors.toList());
assertThat(list).containsExactly("META-INF/MANIFEST.MF");
}
private void scanDirectory(File directory, ClassLoader classloader, String packagePrefix) throws IOException {
File[] files = directory.listFiles();
if (files == null) {
logger.warning("Cannot read directory " + directory);
// IO error, just skip the directory
return;
}
for (File f : files) {
String name = f.getName();
if (f.isDirectory()) {
scanDirectory(f, classloader, packagePrefix + name + "/");
} else {
String resourceName = packagePrefix + name;
if (!resourceName.equals(JarFile.MANIFEST_NAME)) {
resources.get(classloader).add(resourceName);
}
}
}
}
boolean isNativeClass(JarFile jar, JarEntry entry) throws IOException, ConstantPoolException {
String name = entry.getName();
if (name.startsWith("META-INF") || !name.endsWith(".class"))
return false;
//String className = name.substring(0, name.length() - 6).replace("/", ".");
//System.err.println("check " + className);
InputStream in = jar.getInputStream(entry);
ClassFile cf = ClassFile.read(in);
for (int i = 0; i < cf.methods.length; i++) {
Method m = cf.methods[i];
if (m.access_flags.is(AccessFlags.ACC_NATIVE)) {
// System.err.println(className);
return true;
}
}
return false;
}
public static File extractJarEntry(
final String entry,
final File source,
final File target) throws IOException {
JarFile jar = new JarFile(source);
FileOutputStream out = new FileOutputStream(target);
try {
StreamUtils.transferData(jar.getInputStream(jar.getEntry(entry)), out);
return target;
} finally {
jar.close();
out.close();
}
}
/** Replies if the given JAR file contains a SRE bootstrap.
*
* <p>The SRE bootstrap detection is based on the service definition within META-INF folder.
*
* @param jarFile the JAR file to test.
* @return <code>true</code> if the given directory contains a SRE. Otherwise <code>false</code>.
* @since 0.7
* @see #containsUnpackedBootstrap(File)
*/
public static boolean containsPackedBootstrap(File jarFile) {
try (JarFile jFile = new JarFile(jarFile)) {
final ZipEntry jEntry = jFile.getEntry(SREManifestPreferenceConstants.SERVICE_SRE_BOOTSTRAP);
if (jEntry != null) {
try (InputStream is = jFile.getInputStream(jEntry)) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
String line = reader.readLine();
if (line != null) {
line = line.trim();
if (!line.isEmpty()) {
return true;
}
}
}
}
}
} catch (IOException exception) {
//
}
return false;
}
/**
* Constructs jar or nativelib tag for jars using custom name
* @param f
* @param dashcnb
* @return
* @throws IOException
*/
private String constructJarHref(File f, String dashcnb, String name) throws IOException {
String tag = "jar";
if (nativeLibraries != null && nativeLibraries.contains(name)) {
tag = "nativelib";
}
if (processJarVersions) {
if (!f.exists()) {
throw new BuildException("JAR file " + f + " does not exist, cannot extract required versioning info.");
}
JarFile extJar = new JarFile(f);
String version = getJarVersion(extJar);
if (version != null) {
return " <" + tag + " href='" + dashcnb + '/' + name + "' version='" + version + "' size='" + f.length() + "'/>\n";
}
}
return " <" + tag + " href='" + dashcnb + '/' + name + "'/>\n";
}
private static List<String> loadFromJar(String path) throws IOException {
if(path.startsWith("file:")) {
path = path.substring(5);
}
List<String> files = new ArrayList<>();
String [] parts = StringUtils.split(path, '!');
try(JarFile jf = new JarFile(parts[0])) {
Enumeration<JarEntry> entries = jf.entries();
while(entries.hasMoreElements()) {
String name = entries.nextElement().getName();
if(isDefinitionFolder(name) && name.endsWith("xml")) {
files.add(name);
}
}
}
return files;
}
@Parameterized.Parameters(name="Compatibility Test: {0}")
@SuppressWarnings("unchecked")
public static Collection<Object[]> data() throws Exception {
final String zipPath = System.getProperty("testVectorZip");
if (zipPath == null) {
return Collections.emptyList();
}
final JarURLConnection jarConnection = (JarURLConnection) new URL("jar:" + zipPath + "!/").openConnection();
try (JarFile jar = jarConnection.getJarFile()) {
final Map<String, Object> manifest = readJsonMapFromJar(jar, "manifest.json");
final Map<String, Object> metaData = (Map<String, Object>) manifest.get("manifest");
// We only support "awses-decrypt" type manifests right now
if (!"awses-decrypt".equals(metaData.get("type"))) {
throw new IllegalArgumentException("Unsupported manifest type: " + metaData.get("type"));
}
if (!Integer.valueOf(1).equals(metaData.get("version"))) {
throw new IllegalArgumentException("Unsupported manifest version: " + metaData.get("version"));
}
final Map<String, KeyEntry> keys = parseKeyManifest(readJsonMapFromJar(jar, (String) manifest.get("keys")));
final KmsMasterKeyProvider kmsProv = KmsMasterKeyProvider
.builder()
.withCredentials(new DefaultAWSCredentialsProviderChain())
.build();
List<Object[]> testCases = new ArrayList<>();
for (Map.Entry<String, Map<String, Object>> testEntry :
((Map<String, Map<String, Object>>) manifest.get("tests")).entrySet()) {
testCases.add(new Object[]{testEntry.getKey(),
parseTest(testEntry.getKey(), testEntry.getValue(), keys, jar, kmsProv)});
}
return testCases;
}
}
/**
* Constructor that allows browsing a given PEAR package without unarchiving it.
*
* @param pearPackage
* The given archived PEAR package to browse.
* @throws IOException if a problem with IO
*/
public PackageBrowser(JarFile pearPackage) throws IOException {
_pearPackage = pearPackage;
_pearFile = new File(pearPackage.getName());
int nameEndIndex = _pearFile.getAbsolutePath().lastIndexOf('.');
// set root dir = PEAR file path (w/o file name extension)
String rootDirPath = (nameEndIndex > 0) ? _pearFile.getAbsolutePath()
.substring(0, nameEndIndex) : _pearFile.getAbsolutePath();
_rootDir = new File(rootDirPath);
_archived = true;
// add directories and files to the lists
_allDirs.addAll(FileUtil.createDirList(pearPackage));
_allFiles.addAll(FileUtil.createFileList(pearPackage));
}
/**
* Update content of a jar file.
*
* @param src the original jar file name
* @param dest the new jar file name
* @param changes a map of changes, key is jar entry name, value is content.
* Value can be Path, byte[] or String. If key exists in
* src but value is Boolean FALSE. The entry is removed.
* Existing entries in src not a key is unmodified.
* @throws IOException
*/
public static void updateJar(String src, String dest,
Map<String,Object> changes)
throws IOException {
// What if input changes is immutable?
changes = new HashMap<>(changes);
System.out.printf("Creating %s from %s...\n", dest, src);
if (dest.equals(src)) {
throw new IOException("src and dest cannot be the same");
}
try (JarOutputStream jos = new JarOutputStream(
new FileOutputStream(dest))) {
try (JarFile srcJarFile = new JarFile(src)) {
Enumeration<JarEntry> entries = srcJarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String name = entry.getName();
if (changes.containsKey(name)) {
System.out.println(String.format("- Update %s", name));
updateEntry(jos, name, changes.get(name));
changes.remove(name);
} else {
System.out.println(String.format("- Copy %s", name));
jos.putNextEntry(entry);
Utils.transferTo(srcJarFile.getInputStream(entry), jos);
}
}
}
for (Map.Entry<String, Object> e : changes.entrySet()) {
System.out.println(String.format("- Add %s", e.getKey()));
updateEntry(jos, e.getKey(), e.getValue());
}
}
System.out.println();
}
public static Map<String, byte[]> exactResourcesInJar(URL url, Predicate<String> tester) throws IOException {
Map<String, byte[]> map = new HashMap<>();
JarFile jarFile = null;
try {
String prefix = "";
String urlPath = url.getPath();
int separatorIndex = urlPath.lastIndexOf(JAR_URL_SEPARATOR);
if (separatorIndex != -1 && separatorIndex + JAR_URL_SEPARATOR.length() < urlPath.length()) {
prefix = urlPath.substring(separatorIndex + JAR_URL_SEPARATOR.length());
if (!prefix.endsWith("/")) {
prefix += "/";
}
}
jarFile = ((JarURLConnection) url.openConnection()).getJarFile();
Enumeration<JarEntry> jarEntryEnum = jarFile.entries();
while (jarEntryEnum.hasMoreElements()) {
JarEntry entry = jarEntryEnum.nextElement();
String entityName = entry.getName();
if (entry.isDirectory() || !entityName.startsWith(prefix)) {
continue;
}
if (tester != null && !tester.test(entityName)) {
continue;
}
byte[] bs = StreamUtil.extractData(jarFile.getInputStream(entry), true);
map.put(entityName, bs);
}
} finally {
if (jarFile != null) {
jarFile.close();
}
}
return map;
}
/**
* Add a resources JAR. The contents of /META-INF/resources/ will be used if
* a requested resource can not be found in the main context.
*/
public void addResourcesJar(URL url) {
try {
JarURLConnection conn = (JarURLConnection) url.openConnection();
JarFile jarFile = conn.getJarFile();
ZipEntry entry = jarFile.getEntry("/");
WARDirContext warDirContext = new WARDirContext(jarFile,
new WARDirContext.Entry("/", entry));
warDirContext.loadEntries();
altDirContexts.add(warDirContext);
} catch (IOException ioe) {
log.warn(sm.getString("resources.addResourcesJarFail", url), ioe);
}
}
@Override
public Manifest getManifest() {
return withJarFile(new Function<JarFile, Manifest>() {
@Override
public Manifest apply(JarFile jarFile) {
try {
return jarFile.getManifest();
} catch (IOException e) {
log.warnf("Failed to parse manifest for %s", jarPath);
return null;
}
}
});
}
/**
* Callback method of the URLJarFileCloseController to
* indicate that the JarFile is close. This way we can
* remove the JarFile from the cache
*/
public void close(JarFile jarFile) {
synchronized (instance) {
URL urlRemoved = urlCache.remove(jarFile);
if (urlRemoved != null)
fileCache.remove(urlKey(urlRemoved));
}
}
private static void extractFromJar(final ClassLoader classLoader, final Set<String> classNames) throws Exception {
final List<JarFile> filesToProcess = getJarFilesToProcess();
for (final JarFile jarFile : filesToProcess) {
final Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
final JarEntry entry = entries.nextElement();
processEntry(entry, classNames);
}
}
}
public static synchronized boolean requiresExplosion(URL base) throws IOException {
try (AutoCloseable locateHandle = Performance.accumulate("Is explosion needed?")) {
String urlString = base.toExternalForm();
if (urlString.startsWith("jar:file:")) {
int endLoc = urlString.indexOf(JAR_SUFFIX);
if (endLoc > 0) {
String jarPath = urlString.substring(9, endLoc + 4);
//if it has spaces or other characters that would be URL encoded we need to decode them
jarPath = URLDecoder.decode(jarPath, StandardCharsets.UTF_8.name());
File exp = exploded.get(jarPath);
if (exp != null) {
return true;
}
if (explosionNotRequired.contains(jarPath)) {
return false;
}
try (JarFile jarFile = JarFiles.create(jarPath)) {
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry each = entries.nextElement();
if (!each.isDirectory()) {
if (each.getName().startsWith("modules") && !each.getName().endsWith("/module.xml")) {
return true;
}
}
}
}
explosionNotRequired.add(jarPath);
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return false;
}
@DataProvider(name = "versions")
public Object[][] createVersionData() throws Exception {
return new Object[][]{
{JarFile.baseVersion(), 8},
{JarFile.runtimeVersion(), Runtime.version().major()},
{Runtime.version(), Runtime.version().major()},
{Runtime.Version.parse("7.1"), JarFile.baseVersion().major()},
{Runtime.Version.parse("9"), 9},
{Runtime.Version.parse("9.1.5-ea+200"), 9}
};
}