下面列出了怎么用java.util.jar.JarEntry的API类实例代码及写法,或者点击链接到github查看源代码。
private void processFolder(JarOutputStream jos, String path, File folder, byte[] buffer) throws IOException {
for (File file : folder.listFiles()) {
if (file.isFile()) {
// new entry
jos.putNextEntry(new JarEntry(path + file.getName()));
// put the file content
FileInputStream fis = new FileInputStream(file);
int count;
while ((count = fis.read(buffer)) != -1) {
jos.write(buffer, 0, count);
}
fis.close();
// close the entry
jos.closeEntry();
} else if (file.isDirectory()) {
processFolder(jos, path + file.getName() + "/", file, buffer);
}
}
}
protected AbstractArchiveResource(AbstractArchiveResourceSet archiveResourceSet,
String webAppPath, String baseUrl, JarEntry jarEntry, String codeBaseUrl) {
super(archiveResourceSet.getRoot(), webAppPath);
this.archiveResourceSet = archiveResourceSet;
this.baseUrl = baseUrl;
this.resource = jarEntry;
this.codeBaseUrl = codeBaseUrl;
String resourceName = resource.getName();
if (resourceName.charAt(resourceName.length() - 1) == '/') {
resourceName = resourceName.substring(0, resourceName.length() - 1);
}
String internalPath = archiveResourceSet.getInternalPath();
if (internalPath.length() > 0 && resourceName.equals(
internalPath.subSequence(1, internalPath.length()))) {
name = "";
} else {
int index = resourceName.lastIndexOf('/');
if (index == -1) {
name = resourceName;
} else {
name = resourceName.substring(index + 1);
}
}
}
private static Set<String> getResourcePaths(String path, URL dirUrl)
throws URISyntaxException, IOException {
HashSet<String> result = new HashSet<>();
String protocol = dirUrl.getProtocol();
if ("file".equals(protocol)) {
File dir = new File(dirUrl.toURI());
for (String fileName: dir.list()) {
result.add(path + fileName);
}
} else if ("jar".equals(protocol)) {
String dirPath = dirUrl.getPath();
String jarPath = dirPath.substring(5, dirPath.indexOf("!"));
JarFile jarFile = new JarFile(jarPath);
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
String entryName = entries.nextElement().getName();
if ((entryName.length() > path.length()) && entryName.startsWith(path)) {
result.add(entryName);
}
}
jarFile.close();
}
return result;
}
@Test
public void testNoStripJarWithoutManifest() throws Exception {
JarFile original = new JarFile("third_party/ijar/test/jar-without-manifest.jar");
JarFile stripped = new JarFile("third_party/ijar/test/jar-without-manifest-nostrip.jar");
try {
ImmutableList<String> strippedEntries =
stripped.stream().map(JarEntry::getName).collect(toImmutableList());
assertThat(strippedEntries.get(0)).isEqualTo("META-INF/");
assertThat(strippedEntries.get(1)).isEqualTo("META-INF/MANIFEST.MF");
Manifest manifest = stripped.getManifest();
Attributes attributes = manifest.getMainAttributes();
assertThat(attributes.getValue("Manifest-Version")).isEqualTo("1.0");
assertThat(attributes.getValue("Created-By")).isEqualTo("bazel");
assertThat(attributes.getValue("Target-Label")).isEqualTo("//foo:foo");
assertNonManifestFilesBitIdentical(original, stripped);
} finally {
original.close();
stripped.close();
}
}
/**
*
* @param jarFile
* @param entry
* @param file
* @throws IOException
*/
private static void unpack(JarFile jarFile, JarEntry entry, File file) throws IOException {
InputStream inputStream = jarFile.getInputStream(entry, RandomAccessData.ResourceAccess.ONCE);
try {
OutputStream outputStream = new FileOutputStream(file);
try {
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
} finally {
outputStream.close();
}
} finally {
inputStream.close();
}
}
private static void doJar(String a, File source, File dest,
ClassReader options, String encoding,
Boolean contError) throws IOException {
try {
JarFile jf = new JarFile(source);
for (JarEntry je : Collections.list(jf.entries())) {
String name = je.getName();
if (!name.endsWith(".class")) {
continue;
}
try {
doStream(name, jf.getInputStream(je), dest, options, encoding);
} catch (Exception e) {
if (contError) {
System.out.println("Error processing " + source + ": " + e);
e.printStackTrace();
continue;
}
}
}
} catch (IOException ioe) {
throw ioe;
}
}
private static Set<URL> findPathMatchingJarResources(URL relativeUrl) throws IOException {
URL rootUrl = new URL(relativeUrl, "/");
//在jar包中的相对路径
URLConnection con = relativeUrl.openConnection();
JarURLConnection jarCon = (JarURLConnection) con;
JarFile jarFile = jarCon.getJarFile();
JarEntry jarEntry = jarCon.getJarEntry();
String rootEntryPath = (jarEntry != null ? jarEntry.getName() : "");
if (!"".equals(rootEntryPath) && !rootEntryPath.endsWith("/")) {
rootEntryPath = rootEntryPath + "/";
}
Set<URL> result = new LinkedHashSet<>(8);
for (Enumeration<JarEntry> entries = jarFile.entries(); entries.hasMoreElements();) {
JarEntry entry = entries.nextElement();
String entryPath = entry.getName();
if (entryPath.startsWith(rootEntryPath)) {
if (entryPath.startsWith("/")) {
entryPath = entryPath.substring(1);
}
result.add(new URL(rootUrl, entryPath));
}
}
return result;
}
@Override
public JarContents<ClassNode> load() throws IOException {
JarContents<ClassNode> contents = new JarContents<ClassNode>();
JarURLConnection con = (JarURLConnection) getLocation().openConnection();
JarFile jar = con.getJarFile();
Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
byte[] bytes = read(jar.getInputStream(entry));
if (entry.getName().endsWith(".class")) {
ClassNode cn = create(bytes);
contents.getClassContents().add(cn);
} else {
JarResource resource = new JarResource(entry.getName(), bytes);
contents.getResourceContents().add(resource);
}
}
return contents;
}
/**
* Extracts a Jar file
*
* @param inputJar
* @param outputPath
* @throws IOException
*/
public static void unjar(File inputJar, File outputPath) throws IOException {
outputPath.mkdirs();
JarFile jar = new JarFile(inputJar);
Enumeration<JarEntry> jarEntries = jar.entries();
while (jarEntries.hasMoreElements()) {
JarEntry jarEntry = jarEntries.nextElement();
File file = new File(outputPath.getAbsolutePath() + java.io.File.separator + jarEntry.getName());
new File(file.getParent()).mkdirs();
if (jarEntry.isDirectory()) {
file.mkdir();
continue;
}
InputStream is = jar.getInputStream(jarEntry);
FileOutputStream fos = new FileOutputStream(file);
while (is.available() > 0) {
fos.write(is.read());
}
fos.close();
is.close();
}
jar.close();
}
public static void main(String...args) throws Throwable {
try (JarInputStream jis = new JarInputStream(
new FileInputStream(System.getProperty("test.src", ".") +
System.getProperty("file.separator") +
"BadSignedJar.jar")))
{
JarEntry je1 = jis.getNextJarEntry();
while(je1!=null){
System.out.println("Jar Entry1==>"+je1.getName());
je1 = jis.getNextJarEntry(); // This should throw Security Exception
}
throw new RuntimeException(
"Test Failed:Security Exception not being thrown");
} catch (IOException ie){
ie.printStackTrace();
} catch (SecurityException e) {
System.out.println("Test passed: Security Exception thrown as expected");
}
}
@Override
Resource getResource(final String name, boolean check) {
try {
ensureOpen();
} catch (IOException e) {
throw new InternalError(e);
}
final JarEntry entry = jar.getJarEntry(name);
if (entry != null)
return checkResource(name, check, entry);
if (index == null)
return null;
HashSet<String> visited = new HashSet<>();
return getResource(name, check, visited);
}
@Test
public void shouldCheckThatJarIsWellShaded() throws IOException {
File glowrootCoreJarFile = getGlowrootAgentJarFile();
List<String> acceptableEntries = Lists.newArrayList();
acceptableEntries.add("glowroot\\..*");
acceptableEntries.add("org/");
acceptableEntries.add("org/glowroot/");
acceptableEntries.add("org/glowroot/agent/.*");
acceptableEntries.add("META-INF/");
acceptableEntries.add("META-INF/glowroot\\..*");
acceptableEntries.add("META-INF/services/");
acceptableEntries.add("META-INF/services/org\\.glowroot\\..*");
acceptableEntries.add("META-INF/MANIFEST\\.MF");
acceptableEntries.add("META-INF/LICENSE");
acceptableEntries.add("META-INF/NOTICE");
JarFile jarFile = new JarFile(glowrootCoreJarFile);
List<String> unacceptableEntries = Lists.newArrayList();
for (Enumeration<JarEntry> e = jarFile.entries(); e.hasMoreElements();) {
JarEntry jarEntry = e.nextElement();
if (!acceptableJarEntry(jarEntry, acceptableEntries)) {
unacceptableEntries.add(jarEntry.getName());
}
}
jarFile.close();
assertThat(unacceptableEntries).isEmpty();
}
Resource getResource(final String name, boolean check) {
if (metaIndex != null) {
if (!metaIndex.mayContain(name)) {
return null;
}
}
try {
ensureOpen();
} catch (IOException e) {
throw (InternalError) new InternalError().initCause(e);
}
final JarEntry entry = jar.getJarEntry(name);
if (entry != null)
return checkResource(name, check, entry);
if (index == null)
return null;
HashSet visited = new HashSet();
return getResource(name, check, visited);
}
@Override
protected void setUp() throws Exception {
super.setUp();
System.setProperty("org.netbeans.core.modules.NbInstaller.noAutoDeps", "true");
Manifest man = new Manifest ();
man.getMainAttributes ().putValue ("Manifest-Version", "1.0");
man.getMainAttributes ().putValue ("OpenIDE-Module", "org.test.FormatDependency/1");
String req = "org.openide.modules.ModuleFormat1, org.openide.modules.ModuleFormat2";
man.getMainAttributes ().putValue ("OpenIDE-Module-Requires", req);
clearWorkDir();
moduleJarFile = new File(getWorkDir(), "ModuleFormatTest.jar");
JarOutputStream os = new JarOutputStream(new FileOutputStream(moduleJarFile), man);
os.putNextEntry (new JarEntry ("empty/test.txt"));
os.close ();
}
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();
}
}
/**
* Adds the class file bytes for a given class to a JAR stream.
*/
static void add(JarOutputStream jar, Class<?> c) throws IOException {
String name = c.getName();
String classAsPath = name.replace('.', '/') + ".class";
jar.putNextEntry(new JarEntry(classAsPath));
InputStream stream = c.getClassLoader().getResourceAsStream(classAsPath);
int nRead;
byte[] buf = new byte[1024];
while ((nRead = stream.read(buf, 0, buf.length)) != -1) {
jar.write(buf, 0, nRead);
}
jar.closeEntry();
}
/**
* Adds a compiled class file to the target jar stream.
*
* @param fromClass The class to be added
* @param target The target jar stream
*/
private static void addFile(Class fromClass, JarOutputStream target) throws IOException {
String classEntry = fromClass.getName().replace('.', '/') + ".class";
URL classURL = fromClass.getClassLoader().getResource(classEntry);
if (classURL != null) {
JarEntry entry = new JarEntry(classEntry);
target.putNextEntry(entry);
if (!classURL.toString().contains("!")) {
String fileName = classURL.getFile();
writeBytes(fileName, target);
} else {
try (InputStream stream = fromClass.getClassLoader().getResourceAsStream(classEntry)) {
writeBytes(stream, target);
}
}
target.closeEntry();
}
}
static List<Class<?>> getClasses(int count) throws Exception {
String resource = ClassLoader.getSystemClassLoader().getResource("java/lang/Object.class").toString();
Pattern pattern = Pattern.compile("jar:file:(.*)!.*");
Matcher matcher = pattern.matcher(resource);
matcher.matches();
resource = matcher.group(1);
List<Class<?>> classes = new ArrayList<>();
try (JarFile jarFile = new JarFile(resource)) {
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
String name = entries.nextElement().getName();
if (name.startsWith("java") && name.endsWith(".class")) {
classes.add(Class.forName(name.substring(0, name.indexOf(".")).replace('/', '.')));
if (count == classes.size()) {
break;
}
}
}
}
return classes;
}
private static Map<String, ClassCode> loadJar(JarInputStream jarInputStream) {
Map<String, ClassCode> map = new HashMap<>(100);
try (jarInputStream) {
JarEntry jarEntry;
while ((jarEntry = jarInputStream.getNextJarEntry()) != null) {
if (!jarEntry.isDirectory() && jarEntry.getName().endsWith(Constants.CLASS_SUFFIX)) {
byte[] bytes = IOUtils.toByteArray(jarInputStream);
ClassCode classCode = load(bytes);
map.put(classCode.name, classCode);
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
return map;
}
private List<Class> getRegionEntryClassesFromJar(String jarFile, String pkg) throws Exception {
List<Class> regionEntryClasses = new ArrayList<Class>();
JarFile gfJar = new JarFile(jarFile, true);
Enumeration<JarEntry> enm = gfJar.entries();
while (enm.hasMoreElements()) {
JarEntry je = enm.nextElement();
String name = je.getName().replace('/', '.');
if (name.startsWith(pkg)
&& name.endsWith(".class")) {
Class jeClass = Class.forName(name.replaceAll(".class", ""));
if (!jeClass.isInterface()
&& RegionEntry.class.isAssignableFrom(jeClass)
&& !isInExclusionList(jeClass)) {
int modifiers = jeClass.getModifiers();
if ((modifiers & Modifier.ABSTRACT) == 0) {
regionEntryClasses.add(jeClass);
}
}
}
}
return regionEntryClasses;
}
private static Set<String> scanJarClass(String packagePath, URL url)
throws IOException
{
JarFile jarFile = ((JarURLConnection) url.openConnection()).getJarFile();
Set<String> classSet = new HashSet<>();
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String name = entry.getName();
if (name.charAt(0) == '/') {
name = name.substring(1);
}
if (!name.startsWith(packagePath)) {
continue;
}
if (name.endsWith(".class") && !entry.isDirectory()) {
classSet.add(name);
}
}
return classSet;
}
private static void doJar(String a, File source, File dest,
ClassReader options, String encoding,
Boolean contError) throws IOException {
try {
JarFile jf = new JarFile(source);
for (JarEntry je : Collections.list(jf.entries())) {
String name = je.getName();
if (!name.endsWith(".class")) {
continue;
}
try {
doStream(name, jf.getInputStream(je), dest, options, encoding);
} catch (Exception e) {
if (contError) {
System.out.println("Error processing " + source + ": " + e);
e.printStackTrace();
continue;
}
}
}
} catch (IOException ioe) {
throw ioe;
}
}
@Test
public void packageInfoSrcjar() throws IOException {
Path srcjar = temporaryFolder.newFile("lib.srcjar").toPath();
try (JarOutputStream jos = new JarOutputStream(Files.newOutputStream(srcjar))) {
jos.putNextEntry(new JarEntry("package-info.java"));
jos.write("@Deprecated package test;".getBytes(UTF_8));
}
Path output = temporaryFolder.newFile("output.jar").toPath();
Main.compile(
optionsWithBootclasspath()
.setSourceJars(ImmutableList.of(srcjar.toString()))
.setOutput(output.toString())
.build());
Map<String, byte[]> data = readJar(output);
assertThat(data.keySet()).containsExactly("test/package-info.class");
}
/** Combines the JARs into one. If both JARs have the same entry, the entry from the first JAR is used. */
static public void mergeJars (String firstJar, String secondJar, String outJar) throws IOException {
if (DEBUG) debug("scar", "Merging JARs: " + firstJar + " + " + secondJar + " -> " + outJar);
JarFile firstJarFile = new JarFile(firstJar);
JarFile secondJarFile = new JarFile(secondJar);
HashSet<String> names = new HashSet();
for (Enumeration<JarEntry> entries = firstJarFile.entries(); entries.hasMoreElements();)
names.add(entries.nextElement().getName().replace('\\', '/'));
for (Enumeration<JarEntry> entries = secondJarFile.entries(); entries.hasMoreElements();)
names.add(entries.nextElement().getName().replace('\\', '/'));
mkdir(parent(outJar));
JarOutputStream outJarStream = new JarOutputStream(new FileOutputStream(outJar));
outJarStream.setLevel(Deflater.BEST_COMPRESSION);
for (String name : names) {
InputStream input;
ZipEntry entry = firstJarFile.getEntry(name);
if (entry != null)
input = firstJarFile.getInputStream(entry);
else {
entry = firstJarFile.getEntry(name.replace('/', '\\'));
if (entry != null)
input = firstJarFile.getInputStream(entry);
else {
entry = secondJarFile.getEntry(name);
input = secondJarFile.getInputStream(entry != null ? entry : secondJarFile.getEntry(name.replace('/', '\\')));
}
}
outJarStream.putNextEntry(new JarEntry(name));
copyStream(input, outJarStream);
outJarStream.closeEntry();
}
firstJarFile.close();
secondJarFile.close();
outJarStream.close();
}
private void addFile(final JarOutputStream os, final File source, final String key) throws IOException {
if (source.isDirectory()) {
os.putNextEntry(new JarEntry(key));
os.closeEntry();
} else {
os.putNextEntry(new JarEntry(key));
final FileInputStream input = new FileInputStream(source);
os.write(IOUtil.toByteArray(input));
input.close();
os.closeEntry();
}
}
/**
* Validate the security certificates (signers) for the class data.
*/
private Certificate[] getSigners(String className, JarEntry je) throws IOException {
try {
Certificate[] list = je.getCertificates();
if ((list == null) || (list.length == 0)) {
return null;
}
for (Certificate aList : list) {
if (!(aList instanceof X509Certificate)) {
String msg = MessageService.getTextMessage(
MessageId.CM_UNKNOWN_CERTIFICATE, className,
getJarName());
throw new SecurityException(msg);
}
X509Certificate cert = (X509Certificate) aList;
cert.checkValidity();
}
return list;
} catch (GeneralSecurityException gse) {
// convert this into an unchecked security
// exception. Unchecked as eventually it has
// to pass through a method that's only throwing
// ClassNotFoundException
throw handleException(gse, className);
}
}
/**
* this will place the jarInputStream at the depTxtPath location or throws a ComponentException if not found
*/
private static void locateDependencyFileEntry(JarInputStream jarInputStream, String depTxtPath) throws IOException {
JarEntry nextJarEntry = jarInputStream.getNextJarEntry();
while (nextJarEntry != null) {
if (depTxtPath.equals(nextJarEntry.getName())) {// we got it so return it
return;
}
nextJarEntry = jarInputStream.getNextJarEntry();
}
throw new ComponentException(ComponentsApiErrorCode.COMPUTE_DEPENDENCIES_FAILED,
ExceptionContext.withBuilder().put("path", depTxtPath).build());
}
/**
* Create the in-memory JAR containing all the classes in this module.
*/
public byte[] createJar(long blockTimeStamp) throws IOException {
// set jar file timestamp to block timestamp so the whole network is in agreement over this.
FileTime timestamp = FileTime.fromMillis(blockTimeStamp);
// manifest, we explicitly write it so that can can control its timestamps.
Manifest manifest = new Manifest();
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
manifest.getMainAttributes().put(Attributes.Name.MAIN_CLASS, this.mainClass);
ZipEntry manifestEntry = new ZipEntry(JarFile.MANIFEST_NAME);
manifestEntry.setLastModifiedTime(timestamp);
manifestEntry.setLastAccessTime(timestamp);
manifestEntry.setCreationTime(timestamp);
// Create a temporary memory location for this JAR.
ByteArrayOutputStream tempJarStream = new ByteArrayOutputStream(MAX_JAR_BYTES);
// create the jar file
try (JarOutputStream target = new JarOutputStream(tempJarStream)) {
// first, write the manifest file
target.putNextEntry(manifestEntry);
manifest.write(target);
target.closeEntry();
// add the classes
for (String clazz : this.classes.keySet()) {
JarEntry entry = new JarEntry(clazz.replace('.', '/') + ".class");
entry.setLastModifiedTime(timestamp);
entry.setLastAccessTime(timestamp);
entry.setCreationTime(timestamp);
target.putNextEntry(entry);
target.write(this.classes.get(clazz));
target.closeEntry();
}
}
return tempJarStream.toByteArray();
}
/**
* 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();
}
/**
* 从 APK 中读取签名
* @param file 文件
* @return {@link Certificate}[]
*/
public static Certificate[] getCertificateFromApk(final File file) {
try {
JarFile jarFile = new JarFile(file);
JarEntry je = jarFile.getJarEntry("AndroidManifest.xml");
byte[] readBuffer = new byte[8192];
return loadCertificates(jarFile, je, readBuffer);
} catch (Exception e) {
LogPrintUtils.eTag(TAG, e, "getCertificateFromApk");
}
return null;
}