जावा नेटिव इंटरफ़ेस

सॉफ्टवेर डिज़ाइन में, जावा नेटिव इंटरफ़ेस (जेएनआई) एक विदेशी फ़ंक्शन इंटरफ़ेस प्रोग्रामिंग सॉफ्टवेयर ढांचा है जो जावा वर्चुअल मशीन (जेवीएम) में चलने वाले जावा (प्रोग्रामिंग भाषा) कोड को कॉल करने और कॉल करने में सक्षम बनाता है। मूल एप्लिकेशन (हार्डवेयर और ऑपरेटिंग सिस्टम प्लेटफ़ॉर्म के लिए विशिष्ट प्रोग्राम) और लाइब्रेरी (कंप्यूटिंग) अन्य भाषाओं जैसे C (प्रोग्रामिंग भाषा), C++ और असेंबली भाषा में लिखे गए हैं।

उद्देश्य
जेएनआई प्रोग्रामर्स को उन स्थितियों को संभालने के लिए मूल तरीकों को लिखने में सक्षम बनाता है जब कोई एप्लिकेशन पूरी तरह से जावा प्रोग्रामिंग भाषा में नहीं लिखा जा सकता है, उदाहरण के लिए जब मानक जावा क्लास (कंप्यूटर विज्ञान) लाइब्रेरी (कंप्यूटर विज्ञान) प्लेटफ़ॉर्म-विशिष्ट सुविधाओं या प्रोग्राम लाइब्रेरी का समर्थन नहीं करता है। इसका उपयोग किसी मौजूदा एप्लिकेशन (किसी अन्य प्रोग्रामिंग भाषा में लिखा गया) को संशोधित करने के लिए भी किया जाता है ताकि उसे जावा अनुप्रयोगों तक पहुंच योग्य बनाया जा सके। कई मानक पुस्तकालय कक्षाएं डेवलपर और उपयोगकर्ता को कार्यक्षमता प्रदान करने के लिए जेएनआई पर निर्भर करती हैं, उदाहरण के लिए फ़ाइल I/O और ध्वनि क्षमताएं। मानक लाइब्रेरी में प्रदर्शन- और प्लेटफ़ॉर्म-संवेदनशील एपीआई कार्यान्वयन शामिल करने से सभी जावा एप्लिकेशन इस कार्यक्षमता को सुरक्षित और प्लेटफ़ॉर्म-स्वतंत्र तरीके से एक्सेस कर सकते हैं।

जेएनआई फ्रेमवर्क एक मूल विधि को जावा ऑब्जेक्ट (कंप्यूटर विज्ञान) का उसी तरह उपयोग करने देता है जैसे जावा कोड इन ऑब्जेक्ट का उपयोग करता है। एक मूल विधि जावा ऑब्जेक्ट बना सकती है और फिर अपने कार्यों को करने के लिए इन ऑब्जेक्ट का निरीक्षण और उपयोग कर सकती है। एक मूल विधि जावा एप्लिकेशन कोड द्वारा बनाई गई वस्तुओं का निरीक्षण और उपयोग भी कर सकती है।

केवल एप्लिकेशन और हस्ताक्षरित एप्लेट ही जेएनआई को लागू कर सकते हैं।

एक एप्लिकेशन जो जेएनआई पर निर्भर करता है वह जावा द्वारा प्रदान की जाने वाली प्लेटफ़ॉर्म पोर्टेबिलिटी खो देता है (एक आंशिक समाधान यह है कि प्रत्येक प्लेटफ़ॉर्म के लिए जेएनआई कोड का एक अलग कार्यान्वयन लिखा जाए और जावा ऑपरेटिंग सिस्टम का पता लगाए और रनटाइम पर सही लोड करे)।

न केवल मूल कोड जावा के साथ इंटरफ़ेस कर सकता है, बल्कि यह जावा पर आरेखण भी कर सकता है, जो जावा एडब्ल्यूटी नेटिव इंटरफ़ेस के साथ संभव है। प्रक्रिया लगभग वही है, बस कुछ बदलावों के साथ। जावा एडब्ल्यूटी नेटिव इंटरफ़ेस केवल जावा प्लेटफ़ॉर्म, मानक संस्करण 1.3 के बाद से उपलब्ध है।

जेएनआई सी (प्रोग्रामिंग भाषा) ब्रिज से गुजरे बिना भी असेंबली भाषा तक सीधी पहुंच की अनुमति देता है। असेंबली से जावा एप्लिकेशन तक पहुंच उसी तरह संभव है।

डिज़ाइन
जेएनआई ढांचे में, मूल कार्यों को अलग-अलग .c या .cpp फ़ाइलों में लागू किया जाता है। (C++ JNI के साथ थोड़ा सरल इंटरफ़ेस प्रदान करता है।) जब JVM फ़ंक्शन को इनवॉइस करता है, तो यह एक पास करता है  सूचक, ए   सूचक, और जावा विधि द्वारा घोषित कोई भी जावा तर्क। उदाहरण के लिए, निम्नलिखित एक जावा स्ट्रिंग को मूल स्ट्रिंग में परिवर्तित करता है:

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

तर्क जावा ऑब्जेक्ट का एक संदर्भ है जिसके अंदर यह मूल विधि घोषित की गई है।

मूल डेटा प्रकारों को जावा डेटा प्रकारों से मैप किया जा सकता है। वस्तुओं, ऐरे डेटा संरचना और स्ट्रिंग (कंप्यूटर विज्ञान) जैसे यौगिक प्रकारों के लिए मूल कोड को स्पष्ट रूप से कॉल विधियों द्वारा डेटा को परिवर्तित करना होगा.

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

लिनक्स और सोलारिस प्लेटफ़ॉर्म पर, यदि मूल कोड खुद को सिग्नल हैंडलर के रूप में पंजीकृत करता है, तो यह जेवीएम के लिए इच्छित सिग्नल को रोक सकता है। मूल कोड को जेवीएम के साथ बेहतर ढंग से संचालित करने की अनुमति देने के लिए ज़िम्मेदारी की शृंखला का उपयोग किया जा सकता है। विंडोज़ प्लेटफ़ॉर्म पर, माइक्रोसॉफ्ट-विशिष्ट अपवाद हैंडलिंग तंत्र#संरचित अपवाद हैंडलिंग|संरचित अपवाद हैंडलिंग (एसईएच) को एसईएच प्रयास/पकड़ ब्लॉक में मूल कोड को लपेटने के लिए नियोजित किया जा सकता है ताकि मशीन (सीपीयू/एफपीयू) उत्पन्न सॉफ़्टवेयर इंटरप्ट (जैसे) को कैप्चर किया जा सके NULL पॉइंटर एक्सेस उल्लंघन और डिवाइड-बाय-ज़ीरो ऑपरेशंस), और जेवीएम (यानी जावा साइड कोड) में बाधा उत्पन्न होने से पहले इन स्थितियों को संभालने के लिए, सभी संभावनाओं में जिसके परिणामस्वरूप एक अनचाहे अपवाद हो सकता है।

NewStringUTF, GetStringUTFLength, GetStringUTFChars,releaseStringUTFChars और GetStringUTFRegion फ़ंक्शंस के लिए उपयोग की जाने वाली एन्कोडिंग को UTF-8 संशोधित किया गया है। जो सभी इनपुट के लिए मान्य UTF-8 नहीं है, लेकिन वास्तव में एक अलग एन्कोडिंग है। शून्य वर्ण (U+0000) और कोडप्वाइंट जो प्लेन (यूनिकोड)#बेसिक मल्टीलिंगुअल प्लेन पर नहीं हैं (U+10000 से अधिक या उसके बराबर, यानी जिन्हें UTF-16 में सरोगेट जोड़े के रूप में दर्शाया गया है) को संशोधित UTF-8 में अलग-अलग तरीके से एन्कोड किया गया है।. कई प्रोग्राम वास्तव में इन फ़ंक्शंस का गलत तरीके से उपयोग करते हैं और संशोधित यूटीएफ -8 स्ट्रिंग्स के बजाय मानक यूटीएफ -8 स्ट्रिंग्स के रूप में लौटाए गए या फ़ंक्शन में पास किए गए यूटीएफ -8 स्ट्रिंग्स का इलाज करते हैं। प्रोग्राम को NewString, GetStringLength, GetStringChars,releaseStringChars, GetStringRegion, GetStringCritical औरreleaseStringCritical फ़ंक्शंस का उपयोग करना चाहिए, जो छोटे-एंडियन आर्किटेक्चर पर UTF-16LE एन्कोडिंग और बड़े-एंडियन आर्किटेक्चर पर UTF-16BE का उपयोग करते हैं, और फिर UTF-16 से UTF- का उपयोग करते हैं। 8 रूपांतरण दिनचर्या.

मानचित्रण प्रकार
निम्न तालिका जावा (जेएनआई) और मूल कोड के बीच प्रकारों की मैपिंग दिखाती है।

इसके अलावा, हस्ताक्षर  इसका मतलब उस नाम से विशिष्ट रूप से निर्दिष्ट वर्ग होगा; उदाहरण के लिए, हस्ताक्षर   वर्ग को संदर्भित करता है. इसके अलावा, उपसर्ग  हस्ताक्षर करने के लिए उस प्रकार की सरणी बनाता है; उदाहरण के लिए,   मतलब int सारणी प्रकार। अंततः, ए   हस्ताक्षर का उपयोग करता है   कोड.

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

प्रदर्शन
कुछ परिस्थितियों में जेएनआई को काफी ओवरहेड और प्रदर्शन हानि उठानी पड़ती है:
 * जेएनआई विधियों के लिए फ़ंक्शन कॉल महंगे हैं, खासकर जब किसी विधि को बार-बार कॉल करना।
 * मूल विधियाँ JVM द्वारा इनलाइन नहीं की जाती हैं, न ही विधि बिल्कुल सही समय पर संकलन हो सकती है, क्योंकि विधि पहले से ही संकलित है।
 * मूल कोड तक पहुंच के लिए एक जावा ऐरे को कॉपी किया जा सकता है, और बाद में वापस कॉपी किया जा सकता है। लागत सरणी के आकार में रैखिक हो सकती है।
 * यदि विधि किसी ऑब्जेक्ट को पारित कर देती है, या कॉलबैक करने की आवश्यकता होती है, तो मूल विधि संभवतः JVM पर अपनी कॉल कर रही होगी। मूल कोड से जावा फ़ील्ड, विधियों और प्रकारों तक पहुंचने के लिए प्रतिबिंब (कंप्यूटर प्रोग्रामिंग)  के समान कुछ की आवश्यकता होती है। हस्ताक्षर स्ट्रिंग्स में निर्दिष्ट किए जाते हैं और जेवीएम से पूछे जाते हैं। यह धीमा और त्रुटि-प्रवण दोनों है।
 * जावा स्ट्रिंग्स ऑब्जेक्ट हैं, लंबाई हैं और एन्कोडेड हैं। किसी स्ट्रिंग तक पहुँचने या बनाने के लिए O(n) प्रतिलिपि की आवश्यकता हो सकती है।

विकल्प
माइक्रोसॉफ्ट के जावा वर्चुअल मशीन (विजुअल जे++) के मालिकाना कार्यान्वयन में जावा से मूल कोड को कॉल करने के लिए एक समान तंत्र था, जिसे रॉ नेटिव इंटरफ़ेस (आरएनआई) कहा जाता था। इसके अलावा, इसमें मौजूदा मूल कोड को कॉल करने का एक आसान तरीका था जो स्वयं जावा से अवगत नहीं था, जैसे कि विंडोज़ एपीआई, जिसे जे/डायरेक्ट कहा जाता है। हालाँकि, इस कार्यान्वयन के बारे में J++|Sun-Microsoft मुकदमे के विरुद्ध विज़ुअल J++#मुकदमेबाजी के बाद, विज़ुअल J++ का अब रखरखाव नहीं किया जाता है।

जेएनआई की तुलना में आरएनआई का उपयोग कम अनाड़ी था, क्योंकि जावा पर्यावरण सूचक के साथ किसी बहीखाता की आवश्यकता नहीं थी। इसके बजाय, सभी जावा ऑब्जेक्ट्स को सीधे एक्सेस किया जा सकता है। इसे सुविधाजनक बनाने के लिए, एक टूल का उपयोग किया गया जो जावा कक्षाओं से हेडर फ़ाइलें उत्पन्न करता था। इसी प्रकार, आवश्यक मध्यवर्ती देशी लाइब्रेरी और जेएनआई का उपयोग करने की तुलना में जे/डायरेक्ट का उपयोग करना आसान था।

जावा नेटिव एक्सेस|जावा नेटिव एक्सेस (जेएनए) एक समुदाय-विकसित लाइब्रेरी है जो जावा प्रोग्रामर्स को जेएनआई का उपयोग किए बिना मूल साझा लाइब्रेरी तक आसान पहुंच प्रदान करती है। हालाँकि, इसके लिए निर्भर जार लाइब्रेरी के पुनर्वितरण की आवश्यकता है। जेएनआई को कोड करना कठिन होने और जेएनए के धीमे होने के बीच समझौता है। जेएनआई को कोर जावा में बनाया गया है।

यह भी देखें

 * GIWS (सॉफ्टवेयर)
 * ग्लूजेन
 * प्लेटफ़ॉर्म मंगलाचरण सेवाएँ
 * बड़ा घूँट

बाहरी संबंध

 * Oracle's JNI 6.0 API Specification
 * Java Native Interface: Programmer's Guide and Specification
 * JNI in XCode from Apple
 * Exception handling in JNI
 * Java Link (modern C++17 wrapper for JNI)