2012-04-20 16 views
7

का उपयोग कर जावा .class फ़ाइल में फ़ंक्शन इंजेक्ट करें मैंने हास्केल का उपयोग करके जावा बाइटकोड पार्सर लिखा है, और यह ठीक काम करता है। हालांकि अगले चरण में मुझे पूरी तरह से स्टंप किया गया है।हास्केल

एक विधि को क्रियान्वित करने से पहले "में प्रवेश [विधि यहाँ नाम]", और

":

मेरे हास्केल कार्यक्रम है, ताकि जब मार डाला, जावा प्रोग्राम प्रिंट .class फ़ाइल को संशोधित करने की जरूरत है बाहर निकलने के तरीके [विधि का नाम] "विधि को निष्पादित करने के बाद।

मुझे पता है कि हमें निरंतर पूल और विधि तालिका को System.out.println पर कॉल के साथ जोड़ना होगा, लेकिन मुझे लगता है कि मुझे अभी भी कुछ याद आ रहा है।

  • इस समस्या से संपर्क करने का सबसे अच्छा तरीका क्या है?
  • आप कैसे जानते हैं कि System.out.println बाइटकोड में कैसे कॉल करें?
  • आप स्ट्रिंग को विधि के नाम से कैसे स्टोर करते हैं, जिसे बाद में System.out.println का तर्क कहा जाता है?
+2

[VMSpec] (http://docs.oracle.com/javase/specs/jvms/se5.0/html/ClassFile.doc.html#80959) आपका मित्र है। :) – biziclop

+1

बाइटकोड में नई कार्यक्षमता इंजेक्शन ??? मैं वास्तव में बहुत खुश हूं कि आपको – ControlAltDel

+1

भयभीत होने वाली आवाजों में समस्याएं आ रही हैं, मुझे विश्वास नहीं है कि आपको जावा के बाहर इस समाधान के लिए जाना होगा - मुझे संदेह होगा कि कुछ प्रकार की प्रॉक्सी तकनीक काम करेगी। (उसने कहा, आपको इस तरह से ऐसा करने का प्रयास करने का मेरा सम्मान है।)) –

उत्तर

2

ठीक है, यह विभिन्न बाइट कोड इंजीनियरिंग पुस्तकालय आपको देता है। एएसएम, बीसीईएल, आदि। आपके होमवर्क का विवरण पहलू है, और AspectJ ठीक है।

होमवर्क की तरह लगता है कि हास्केल बाइट कोड इंजीनियरिंग अभ्यास लिखना है, इसलिए आपको कक्षा फ़ाइल को स्वयं संशोधित करने की आवश्यकता होगी। @biziclop द्वारा उपरोक्त सुझाव सही है। कक्षा फ़ाइल पर पहले और बाद में करें, डेल्टा को नोट करें, और खुद को हास्केल से ही करें।

[ps: ज़ाहिर है, उपरोक्त "शॉर्ट-कट": पी यह है कि यदि आप जेवीएम स्पेक (जैसा कि आपके क्यू पर टिप्पणी में उल्लेख किया गया है) पढ़ना पसंद नहीं है और यह पता लगाना कि आप इसे कैसे करें एक जावा कंपाइलर लिखना होगा। आप मूल रूप से इनवेक के लिए विभिन्न बाइट कोडों में से एक का उपयोग करके एक विधि को कॉल करते हैं - यहां एक इंटरफ़ेस विधि कॉल - जिसके पहले आपको रिसीवर होना चाहिए वर्ग प्रणाली से स्थिर क्षेत्र और ढेर पर विधि का नाम। Spec में विवरण।]

2

शायद सबसे आसान दृष्टिकोण एक जावा वर्ग उस में एक System.out.println() कोड के साथ एक एकल विधि है कि लिखने के लिए है, javac साथ यह संकलन और परिणामों पर नज़र डालें।

एक बार जब आप इससे परिचित हो जाएं, चरण-दर-चरण आगे बढ़ें।

  1. System.out.println() जोड़ें जावा फ़ाइल में कहीं भी कॉल करें जिसे आप उपकरण बनाना चाहते हैं। यह निरंतर पूल का ख्याल रखता है। हास्केल कोड लिखें जो प्रासंगिक स्थिरांक पाता है और बाइटकोड इंजेक्ट करता है।
  2. जावा फ़ाइल से "क्रच" कॉल निकालें और हास्केल में निरंतर पूल मैनिपुलेशन लागू करें।
2

बस अपनी जावा बाइटकोड सूची को पकड़ें और केवल System.out.println() पर फ़ंक्शन कॉल के साथ एक साधारण संकलित कक्षा खोलें और एक झलक लें। आपको जो भी तरीकों की आवश्यकता है, उसके लिए ऐसा करें। इसे खोजने का सबसे अच्छा तरीका कुछ सरल कोड फ़ाइलों और रिवर्स इंजीनियर के साथ कुछ जांच करना है जैसा आप साथ जाते हैं। आपको उस संदेश का अनुवाद करना होगा जिसे आप यूनिकोड में चाहते हैं और उसे अपने फ़ंक्शन में पास कर दें। उस भाग के बारे में भी मत भूलना। ऐसे कई कार्यक्रम हैं जो बाइटकोड को जीतने के लिए आपकी खोज में आपकी मदद करेंगे।

0

मुझे लगता है कि इस समस्या से संपर्क करने का सबसे अच्छा तरीका Javassist लाइब्रेरी (Java Programming Assistant) का उपयोग करना है। Javassist.bytecode कक्षा में कुछ फ़ंक्शन हैं जो उपयोगी हो सकते हैं।