मैं हाल ही में मेरे अपने ConstantPool नक्शाकार लिखा था क्योंकि एएसएम और JarJar निम्न समस्याओं था:
- धीमा करने के लिए
- सभी वर्ग निर्भरता के बिना फिर से लिखने का समर्थन नहीं किया
स्ट्रीमिंग का समर्थन नहीं किया था
- ट्री एपीआई मोड में रीमेपर का समर्थन नहीं किया
- स्टैकमैप्स
का विस्तार और पतन करना था
public void process(DataInputStream in, DataOutputStream out, Function mapper) throws IOException {
int magic = in.readInt();
if (magic != 0xcafebabe) throw new ClassFormatError("wrong magic: " + magic);
out.writeInt(magic);
copy(in, out, 4); // minor and major
int size = in.readUnsignedShort();
out.writeShort(size);
for (int i = 1; i < size; i++) {
int tag = in.readUnsignedByte();
out.writeByte(tag);
Constant constant = Constant.constant(tag);
switch (constant) {
case Utf8:
out.writeUTF(mapper.apply(in.readUTF()));
break;
case Double:
case Long:
i++; // "In retrospect, making 8-byte constants take two constant pool entries was a poor choice."
// See http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4.5
default:
copy(in, out, constant.size);
break;
}
}
Streams.copyAndClose(in, out);
}
private final byte[] buffer = new byte[8];
private void copy(DataInputStream in, DataOutputStream out, int amount) throws IOException {
in.readFully(buffer, 0, amount);
out.write(buffer, 0, amount);
}
और फिर
public enum Constant {
Utf8(1, -1),
Integer(3, 4),
Float(4, 4),
Long(5, 8),
Double(6,8),
Class(7, 2),
String(8, 2),
Field(9, 4),
Method(10, 4),
InterfaceMethod(11, 4),
NameAndType(12, 4),
MethodHandle(15, 3),
MethodType(16, 2),
InvokeDynamic(18, 4);
public final int tag, size;
Constant(int tag, int size) { this.tag = tag; this.size = size; }
private static final Constant[] constants;
static{
constants = new Constant[19];
for (Constant c : Constant.values()) constants[c.tag] = c;
}
public static Constant constant(int tag) {
try {
Constant constant = constants[tag];
if(constant != null) return constant;
} catch (IndexOutOfBoundsException ignored) { }
throw new ClassFormatError("Unknown tag: " + tag);
}
बस सोचा था कि मैं पुस्तकालयों के बिना विकल्प दिखाने चाहते हैं के रूप में यह काफी एक अच्छी जगह से हैकिंग शुरू करने के लिए है:
मैं निम्नलिखित के साथ समाप्त हो गया। मेरा कोड javap से प्रेरित कोड
एएसएम और बीसीईएल जैसी कुछ बाइटकोड मैनिपुलेशन लाइब्रेरीज़ हैं, जो आपको क्लासफ़ाइल को अपनी पसंद के अनुसार ट्विक करने की अनुमति देते हैं। बेहतर समाधान, आईएमओ, निरंतर संपत्ति के रूप में निकालने और निष्कर्षण के लिए जरूरी एक बार पुनर्मूल्यांकन की असुविधा के माध्यम से जाना है। –
@ नाथन डी। रयान मैं निश्चित रूप से इसे निकालने जा रहा हूं और इसे भविष्य के लिए एक कॉन्फ़िगरेशन फ़ाइल में डाल रहा हूं, लेकिन इस विशिष्ट मामले में तैनात संस्करण को पुन: संकलित करने के लिए बहुत असुविधाजनक होगा, जो कि पुराना है। –
प्रश्न में स्ट्रिंग एक संकलन-समय निरंतर है? –