2011-10-05 18 views
27

मुझे पता है कि जावा 7 की रनटाइम विशेषताएं जावा 6 के साथ उपलब्ध नहीं हैं लेकिन से कोई नया बाइट कोड जोड़ा नहीं गया है नया बाइट कोड invokedynamic गैर-जावा भाषाओं के लिए केवल प्रासंगिक है , मैं सोच रहा था कि जावा 7 स्रोत कोड (नया switch कथन, हीरा ऑपरेटर) को शुद्ध जावा 6 में परिवर्तित करना कितना मुश्किल होगा (यानी जावा 6 संगतता खोए बिना स्रोत को जावा 7 में परिवर्तित करने में सक्षम होना चाहिए)।जावा 7 को जावा 6 संकलन करना 6

कोई बात नहीं?

+3

मुझे प्रेरणा जानने के लिए उत्सुकता है। बस एक अकादमिक रुचि? –

+0

वास्तव में जावा 7 में एक नया बाइटकोड जोड़ा गया है: 'invokedynamic' (जब आप जावा स्रोत कोड संकलित करते हैं तो जावा कंपाइलर इसका उत्पादन नहीं करेगा)। – Jesper

+0

मैंने सोचा कि invokedynamic समर्थन का मतलब नया बाइट कोड जोड़ना था? – SteveD

उत्तर

6

मार्क संस्करण 1.6.0 (यानी 0x32) के साथ जावा 7 javac द्वारा एक .class फ़ाइल आउटपुट

 
printf "\x00\x00\x00\x32" |dd of=Example.class seek=4 bs=1 count=4 conv=notrunc 
( http://en.wikipedia.org/wiki/Java_class_file#General_layout के अनुसार)

आपको लगता है कि (फ़ाइल नाम के लिए $ 1 का प्रयोग करके) डाल दिया

 
find . -name \*.class |xargs -I {} ./j6patch {} 

मैं एक बड़ी (~ 4.8 एमबी जार) कोड के आधार पर यह प्रयोग किया जाता है और यहां तक ​​कि जावा पर RetroTranslator प्रयोग किया है: j6patch में आप के साथ सभी वर्ग फ़ाइलों कर सकते हैं 6 जार तो जावा 7 भाषा सुविधाओं का उपयोग जावा पर चलने वाले ऐप पर किया जा सकता है। इसके अलावा जावा 7 कंपाइलर (javac) बहुत सारे अतिरिक्त अनुकूलन (उदा। विश्लेषण से बचें) जो बहुत ही उल्लेखनीय रूप से प्रदर्शन में सुधार करता है।

RetroTranslator-verify -target 1.5 और जेआरई 1.6 रनटाइम जार के साथ उपयोग करने की अनुमति देता है कि जावा 7 रनटाइम सुविधाओं का उपयोग नहीं किया जाता है।

+0

क्या आपने कोशिश की? यह अभ्यास में कितनी अच्छी तरह से काम किया? –

+0

हां, एक बड़े (~ 4.8 एमबी जार) कोडेबेस पर और जावा 6 जार पर रेट्रोट्रांसलेटर का भी उपयोग किया जाता है, इसलिए जावा 7 भाषा सुविधाओं को जावा 5 में चलने वाले ऐप पर इस्तेमाल किया जा सकता है। इसके अलावा जावा 7 कंपाइलर (जावा) बहुत सारे करता है अतिरिक्त opimizations (जैसे बचने का विश्लेषण) जो प्रदर्शन में काफी ध्यान देता है। – karmakaze

+2

इसके अतिरिक्त आप रेट्रोट्रांसलेटर का उपयोग -verify-target 1.5 और जेआरई 1.6 रनटाइम जार के साथ कर सकते हैं यह सत्यापित करने के लिए कि कोई जावा 7 रनटाइम उपयोग नहीं किया जाता है। – karmakaze

11

जहां तक ​​मुझे पता है, इस समय इस समस्या का कोई समाधान नहीं है। जावा 1.7 संरचनाओं से निपटने के लिए सबसे अच्छी शर्त retrotranslator का विस्तार करना होगा। हीरा ऑपरेटर बहुत आसान होना चाहिए, क्योंकि इसमें कोई बाइटकोड संशोधन की आवश्यकता नहीं है।

आपका कथन "कोई नया बाइट कोड जोड़ा नहीं गया है" सही नहीं है: एक नया आविष्कारिक बाइट कोड है और अधिक महत्वपूर्ण बात यह है कि जेनरेट किए गए बाइटकोड 1.6 जेआरई के लिए मान्य नहीं होंगे, इसलिए रेट्रोट्रांसलेटर को उसे फिक्स करें।

+0

क्या आप एक उदाहरण दे सकते हैं जहां बाइट कोड जेनरेट किया गया है जो जावा 6 वीएम के साथ मान्य नहीं है? 'invokedynamic' का प्रयोग जावा द्वारा ही नहीं किया जाता है, यह केवल गतिशील भाषाओं जैसे ग्रोवी या ज्योथन (और दोनों इसके बिना रह सकते हैं) के लिए है। –

+2

आपको जावा एसई 7 विनिर्देश के अनुलग्नक 3 (http://download.oracle.com/otndocs/jcp/java_se-7-final-eval-spec/index.html) के माध्यम से जाना होगा, इसमें एक पीडीएफ है जावा एसई 6 के संबंध में अंतर। एक सरसरी नज़र में ऐसा लगता है कि सभी तोड़ने वाले बदलाव (जैसे नए निरंतर पूल प्रकार) इनवॉडीडेमिक समर्थन से संबंधित हैं। –

+0

समस्या यह है कि बाइट कोड संस्करण संख्या कक्षा फ़ाइल में निहित है, इसलिए 1.6 JVM एक 1.7 वर्ग फ़ाइल लोड नहीं करेगा। –

3

आप सही हैं कि जावा द्वारा invokedynamic निर्देश का उपयोग नहीं किया जाता है, हालांकि जावा में कुछ अन्य संबंधित परिवर्तन भी उपयोग किए जा सकते हैं। Invokedynamic एक नए 'गतिशील लिंकेज तंत्र - विधि हैंडल' पर निर्भर करता है जिसके लिए invokevirtual निर्देश में कुछ बदलाव भी हैं। आप 'ए न्यू डायनामिक लिंकेज मैकेनिज्म: मेथड हैंडल' सेक्शन में this article में अधिक जानकारी प्राप्त कर सकते हैं।

विधि हैंडल प्रतिबिंब के लिए एक तेज़ विकल्प भी प्रदान करते हैं, और इसलिए जावा में उपयोगी हैं। जावा 6 पर विधि हैंडल का उपयोग कर कोड को कनवर्ट करना संभव नहीं होगा क्योंकि सुविधा जावा 7 वीएम पर निर्भर करती है।

+0

संदर्भित लेख का एक पठन यह इंगित करता है कि नया 'गतिशील लिंकेज तंत्र' किसी भी नए बाइटकोड के साथ समर्थित नहीं है बल्कि java.dyn (java.lang.invoke.MethodHandle) रनटाइम समर्थन के साथ समर्थित है। बेशक बाइटकोड को यह देखने के लिए जांचना चाहिए कि जावा 6 संगतता के लिए इसका संदर्भ नहीं दिया गया है। – karmakaze

2

यह शायद कुछ काम है, लेकिन इस प्रयास करें:

अपने classpath को ग्रहण के जावा संकलक जोड़ें। यह प्लगइन org.eclipse.jdt.core में है (org.eclipse.jdt.core_*.jar फ़ोल्डर plugins में खोजें)।

इस जेएआर में कंपाइलर और पार्सर शामिल है। पार्स पेड़ को पार करने के लिए आप अपने आप को पार्सर और फिर use the ASTVisitor का आह्वान कर सकते हैं।

तब आप पेड़ को संशोधित कर सकते हैं और इस से नया स्रोत कोड बना सकते हैं जिसे आप सामान्य रूप से संकलित कर सकते हैं।

कंपाइलर बाइट कोड उत्पन्न करने से पहले एएसटी पेड़ को "प्रीप्रोसेस" करना भी संभव हो सकता है; यह आपको "स्रोतों को डिस्क पर वापस लिखने और उन्हें वहां से संकलित" चरण बचाएगा।

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