Tôi đang sử dụng một thư viện bytecode được gọi là ASM để thay đổi các tệp lớp, sau đó tôi muốn viết từng tệp lớp vào một tệp jar hơn là một thư mục chứa các tệp lớp. Tôi làm điều này bằng cách chạy mã này:Invalid Entry Compressed Size
Vấn đề của tôi xảy ra khi một ZipException là ném vì không kích thước dự kiến, tức là
java.util.zip.ZipException: invalid entry compressed size (expected 695 but got 693 bytes)
at java.util.zip.ZipOutputStream.closeEntry(Unknown Source)
at org.steinburg.client.accessor.Accessor.accessJar(Accessor.java:64)
at org.steinburg.client.accessor.Accessor.<init>(Accessor.java:41)
at Loader.main(Loader.java:5)
package org.steinburg.client.accessor;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
public class Accessor {
private String input;
private File inFile;
private JarEntry jarEntry;
private JarFile jarFile;
private Enumeration<JarEntry> entries;
private InputStream is;
private String out;
private File outFile;
private FileOutputStream fos;
private JarOutputStream jos;
private byte[] bytes;
public Accessor(){
try{
input = new String("Input Jar.jar");
inFile = new File(input);
jarFile = new JarFile(inFile);
entries = jarFile.entries();
out = new String("Output Jar.jar");
outFile = new File(out);
fos = new FileOutputStream(outFile);
jos = new JarOutputStream(fos);
accessJar();
} catch (Exception e) {
e.printStackTrace();
}
}
protected final void accessJar(){
try {
while (entries.hasMoreElements()){
jarEntry = entries.nextElement();
is = jarFile.getInputStream(jarEntry);
if (jarEntry.getName().endsWith(".class")){
ClassReader cr = new ClassReader(is);
ClassWriter cw = new ClassWriter(cr, 0);
FieldAdapter fa = new FieldAdapter(cw);
cr.accept(fa, 0);
bytes = cw.toByteArray();
} else {
bytes = readBytes(is);
}
JarEntry je = new JarEntry(jarEntry);
jos.putNextEntry(je);
jos.write(bytes);
jos.closeEntry();
}
jos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
protected byte[] readBytes(InputStream inputStream){
try{
DataInputStream reader = new DataInputStream(inputStream);
byte[] toReturn = new byte[reader.available()];
reader.readFully(toReturn);
reader.close();
return toReturn;
} catch (Exception e){
e.printStackTrace();
return null;
}
}
}
Các ClassReader, ClassWriter (mỗi phần của thư viện), và FieldAdapter (làm bởi bản thân mình) chỉ cần bàn thờ mã, và để có được các byte của toàn bộ lớp tôi sử dụng cw.toByteArray(). Không có vấn đề gì đối với thao tác bytecode chính nó, nó chỉ là văn bản cho một tệp jar mới thông qua một JarOutputStream. Bất cứ ai biết làm thế nào để giải quyết vấn đề này?
Những phương pháp ném ngoại lệ này? Bạn có thể đăng toàn bộ dấu vết ngăn xếp không? – ShyJ