2012-02-10 11 views
10

से निर्देशों को हटा रहा है, मैं Javassist का उपयोग कर गतिशील रूप से कक्षाओं को लोड करने के लिए उपयोग कर रहा हूं। एक विधि में कोड जोड़ने के दौरान जावासिस्ट का उपयोग करके अपेक्षाकृत आसान है, मैं कोड को हटाने का कोई तरीका नहीं ढूंढ पाया।जावा बाइटकोड

इस समय मैं लक्षित opcodes और किसी भी पैरामीटर को प्रतिस्थापित करने के लिए nop निर्देशों का उपयोग कर कोड को हटाने का अनुकरण कर रहा हूं। हालांकि, मैं इस पर विचार ज्यादातर एक हैक होने के लिए:

  • प्रत्येक opcode, अलग से इलाज किया जाना है के बाद से मानकों के बाइट लंबाई अलग है। कुछ मामलों में मुझे nop और पॉप के बीच चयन करने की आवश्यकता है, इस पर निर्भर करता है कि हटाए गए ओपोड स्टैक को प्रभावित करता है या नहीं। इस तरह के हेरफेर को थकाऊ होना शुरू हो रहा है - और जो कोड करता है वह तदनुसार घुल रहा है। तो, स्वाभाविक रूप से, मैं एक मौजूदा समाधान की उम्मीद कर रहा हूं।

  • अंतिम परिणाम nop निर्देशों से भरा हुआ है। जबकि JVM को प्रदर्शन प्रदर्शन के बिना उन लोगों को अनुकूलित करना चाहिए, परिणामी बाइटकोड अभी भी काफी सुरुचिपूर्ण और इससे बड़ा होना चाहिए। यह सौंदर्यशास्त्र का एक मुद्दा है, लेकिन यह अभी भी विचार करने के लिए कुछ है।

दुर्भाग्य से, बाईटकोड सरणी की खाई को बंद करने का केवल स्थानांतरण भागों पर्याप्त नहीं है - चले गए कोड (जैसे शाखा अनुदेश अनुक्रमित) के लिए किसी भी संदर्भ के रूप में अच्छी तरह से अद्यतन किया जाना चाहिए।

क्या जावासिस्ट का उपयोग करके निर्देशों को हटाना संभव है? वैकल्पिक रूप से, क्या एक बाइटकोड मैनिपुलेशन लाइब्रेरी है जो मुझे आसानी से बाइटकोड को पार्स किए बिना आसानी से ऐसा करने की अनुमति देगी?

+2

मैं सिर्फ उत्सुक हूं। तुम ऐसा क्यों करना चाहते हो? कक्षाओं को कम करने, उन्हें संशोधित करने और उन्हें फिर से संकलित करना आसान नहीं होगा? – Luixv

+0

@ लुईक्सव: मैं चाहता हूं कि मैनिपुलेशन प्रक्रिया रनटाइम पर स्वचालित रूप से हो - वास्तविक स्रोत कोड को मैन्युअल रूप से संशोधित करना एक विकल्प नहीं है, क्योंकि परिवर्तन ठीक नहीं होते हैं। – thkala

+0

यदि आप कक्षा को 'जार' में रखते हैं, तो अनावश्यक 'एनओपी' काफी अच्छी तरह से संपीड़ित हो जाएगा और संकुचित आकार बहुत बड़ा नहीं होगा। –

उत्तर

3

Apache BCELdelete instructions करने की अनुमति देता:

निर्देश का विलोपन भी बहुत सीधा है; सभी निर्देश हैंडल और किसी दिए गए सीमा के भीतर निहित निर्देश निर्देश सूची से हटा दिए जाते हैं और निपटाए जाते हैं। हालांकि डिलीट() विधि एक लक्ष्यLostException फेंक सकती है जब निर्देश लक्ष्यक अभी भी हटाए गए निर्देशों में से किसी एक का संदर्भ दे रहे हैं। उपयोगकर्ता को कोशिश-पकड़ खंड में ऐसे अपवादों को संभालने के लिए मजबूर होना पड़ता है और इन संदर्भों को कहीं और रीडायरेक्ट करता है।

आप मैनुअल में भी एक उदाहरण पा सकते हैं।

+0

+1 मैंने अभी तक बीसीईएल को नहीं देखा है, लेकिन यह वादा करता है। मैं देखूंगा कि मेरे मौजूदा कोड में शामिल करना कितना आसान होगा ... – thkala

0

javassist ट्यूटोरियल से:

Javassist एक विधि या क्षेत्र को दूर करने की अनुमति नहीं है, लेकिन यह नाम बदलने के लिए अनुमति देता है। इसलिए यदि कोई विधि जरूरी नहीं है, तो इसका नाम बदला जाना चाहिए और सेटनाम() और setModifiers() को CtMethod में घोषित करके एक निजी विधि के रूप में बदला जाना चाहिए।

+0

मैं एक विधि को हटाना नहीं चाहता - मैं * विधि * के भीतर से निर्देशों को हटाना चाहता हूं ... – thkala

+0

ओह, मेरे बुरे! पूर्णता के लिए हालांकि, ट्यूटोरियल यह भी कहता है: 'फ़ील्ड या विधि को निकालने के लिए, CtClass में RemoveField() या removeMethod() को कॉल करें।' : एस – user1205938

संबंधित मुद्दे