سلام! اڄ اسان توهان کي JNDI سان متعارف ڪرايو. اچو ته اهو معلوم ڪريون ته اهو ڇا آهي، ان جي ضرورت ڇو آهي، اهو ڪيئن ڪم ڪري ٿو، اسان ان سان ڪيئن ڪم ڪري سگهون ٿا. ۽ پوءِ اسين اسپرنگ بوٽ يونٽ ٽيسٽ لکنداسين، جنهن جي اندر اسين هن ئي JNDI سان کيڏنداسين.
تعارف. نالو ۽ ڊاريڪٽري خدمتون
JNDI ۾ ڊائيونگ ڪرڻ کان اڳ، اچو ته سمجھون ته ڇا نالو ڏيڻ ۽ ڊاريڪٽري خدمتون آھن. اهڙي خدمت جو سڀ کان واضح مثال ڪنهن به PC، ليپ ٽاپ يا اسمارٽ فون تي فائيل سسٽم آهي. فائل سسٽم منظم ڪري ٿو (غير معمولي ڪافي) فائلون. اهڙين سسٽم ۾ فائلون هڪ وڻ جي جوڙجڪ ۾ گروپ ٿيل آهن. هر فائل جو هڪ منفرد پورو نالو آهي، مثال طور: C:\windows\notepad.exe. مهرباني ڪري نوٽ ڪريو: مڪمل فائل جو نالو رستو آهي ڪجهه روٽ پوائنٽ (ڊرائيو سي) کان فائل پاڻ ڏانهن (notepad.exe). اهڙي زنجير ۾ وچولي نوڊس ڊاريڪٽري آهن (ونڊوز ڊاريڪٽري). ڊاريڪٽري اندر فائلون خاصيتون آهن. مثال طور، ”پوشيده“، ”ريڊ اونلي“، وغيره. اهڙي سادي شيءِ جو تفصيلي بيان جيئن ته فائيل سسٽم، نالو ڏيڻ ۽ ڊاريڪٽري سروسز جي تعريف کي بهتر سمجهڻ ۾ مدد ڪندو. تنهن ڪري، هڪ نالو ۽ ڊاريڪٽري سروس هڪ سسٽم آهي جيڪو ڪيترن ئي شين جي ڪيترن ئي نالن جي نقشي کي منظم ڪري ٿو. اسان جي فائيل سسٽم ۾، اسان فائلن جي نالن سان رابطو ڪندا آهيون جيڪي شيون لڪائيندا آهن- فائلون پاڻ کي مختلف فارميٽ ۾. نالو ڏيڻ ۽ ڊاريڪٽري سروس ۾، نامزد ڪيل شيون ھڪڙي وڻ جي جوڙجڪ ۾ منظم ٿيل آھن. ۽ ڊاريڪٽري شيون خاصيتون آهن. نالو ۽ ڊاريڪٽري سروس جو ٻيو مثال DNS (ڊومين نالو سسٽم) آهي. هي سسٽم انساني پڙهڻ جي قابل ڊومين نالن (مثال طور، https://javarush.com/) ۽ مشين پڙهڻ جي قابل IP پتي (مثال طور، 18.196.51.113) جي وچ ۾ ميپنگ کي منظم ڪري ٿو. DNS ۽ فائل سسٽم کان علاوه، ٻيون ڪيتريون ئي خدمتون آهن، جهڙوڪ:- لائيٽ ويٽ ڊاريڪٽري رسائي پروٽوڪول (LDAP) ؛
- CORBA نالي جي خدمت ؛
- نيٽورڪ انفارميشن سروس (NIS) ؛
- ۽ ٻيا.
جي اين ڊي آئي
JNDI، يا جاوا نالونگ ۽ ڊاريڪٽري انٽرفيس، نالو ڏيڻ ۽ ڊاريڪٽري خدمتن تائين رسائي لاءِ جاوا API آھي. JNDI هڪ API آهي جيڪو هڪ يونيفارم ميکانيزم مهيا ڪري ٿو جاوا پروگرام لاءِ مختلف نالن ۽ ڊاريڪٽري خدمتن سان رابطو ڪرڻ لاءِ. هود جي تحت، JNDI ۽ ڪنهن به ڏنل خدمت جي وچ ۾ انضمام هڪ سروس فراهم ڪندڙ انٽرفيس (SPI) استعمال ڪندي مڪمل ڪيو ويو آهي. SPI مختلف نالا ڏيڻ ۽ ڊاريڪٽري سروسز کي شفاف طور تي ڳنڍڻ جي اجازت ڏئي ٿي، جاوا ايپليڪيشن کي JNDI API استعمال ڪرڻ جي اجازت ڏئي ٿي ڳنڍيل خدمتن تائين رسائي. هيٺ ڏنل شڪل JNDI فن تعمير کي بيان ڪري ٿو:ذريعو: Oracle Java Tutorials
جي اين ڊي آئي آسان لفظن ۾ معنيٰ
بنيادي سوال آهي: اسان کي JNDI جي ضرورت ڇو آهي؟ JNDI جي ضرورت آهي ته جيئن اسان جاوا اعتراض حاصل ڪري سگھون "رجسٽريشن" مان ڪجهه شيون جاوا ڪوڊ مان هن اعتراض سان پابند اعتراض جي نالي سان. اچو ته مٿين بيان کي ٿيسز ۾ ٽوڙيون ته جيئن بار بار لفظن جي گهڻائي اسان کي پريشان نه ڪري:- آخرڪار اسان کي جاوا اعتراض حاصل ڪرڻ جي ضرورت آهي.
- اسان هي اعتراض ڪجهه رجسٽري مان حاصل ڪنداسين.
- هن رجسٽري ۾ شيون جو هڪ گروپ آهي.
- هن رجسٽري ۾ هر شئي جو هڪ منفرد نالو آهي.
- رجسٽري مان هڪ اعتراض حاصل ڪرڻ لاء، اسان کي اسان جي درخواست ۾ هڪ نالو پاس ڪرڻ گهرجي. ڄڻ ته چون: ”مهرباني ڪري مون کي ڏي ته تو وٽ فلاڻي نالي سان ڇا آهي“.
- اسان نه رڳو شيون رجسٽري مان انهن جي نالي سان پڙهي سگهون ٿا، پر هن رجسٽري ۾ شيون ڪجهه نالن سان محفوظ ڪري سگهون ٿا (ڪنهن نه ڪنهن طرح اهي اتي ختم ٿين ٿا).
JNDI API
JNDI جاوا SE پليٽ فارم ۾ مهيا ڪيل آهي. JNDI استعمال ڪرڻ لاءِ، توھان کي ضرور درآمد ڪرڻ گھرجي JNDI ڪلاسز، ۽ گڏوگڏ ھڪ يا وڌيڪ خدمت فراهم ڪندڙ کي نالو ڏيڻ ۽ ڊاريڪٽري سروسز تائين رسائي حاصل ڪرڻ لاءِ. JDK ھيٺ ڏنل خدمتن لاء سروس فراهم ڪندڙ شامل آھن:- لائيٽ ويٽ ڊاريڪٽري رسائي پروٽوڪول (LDAP)؛
- عام اعتراض درخواست بروکر آرڪيٽيڪچر (CORBA)؛
- عام اعتراض خدمتون (COS) نالي جي خدمت؛
- Java Remote Method Invocation (RMI) رجسٽري؛
- ڊومين نالو سروس (DNS).
- javax.naming؛
- javax.naming.directory؛
- javax.naming.ldap؛
- javax.naming.event؛
- javax.naming.spi.
انٽرفيس جو نالو
نالو انٽرفيس توهان کي اجزاء جي نالن سان گڏوگڏ JNDI نالي جي نحو کي ڪنٽرول ڪرڻ جي اجازت ڏئي ٿو. JNDI ۾، سڀئي نالو ۽ ڊاريڪٽري آپريشنز جي حوالي سان ڪيا ويا آھن. ڪي به مطلق جڙ نه آهن. تنهن ڪري، JNDI هڪ InitialContext بيان ڪري ٿو، جيڪو نالو ڏيڻ ۽ ڊاريڪٽري جي عملن لاء هڪ شروعاتي نقطو مهيا ڪري ٿو. هڪ دفعو شروعاتي حوالي سان رسائي حاصل ڪئي وئي آهي، اهو شيون ۽ ٻين مقصدن جي ڳولا لاء استعمال ڪري سگهجي ٿو.Name objectName = new CompositeName("java:comp/env/jdbc");
مٿي ڏنل ڪوڊ ۾، اسان ڪجھ نالو بيان ڪيو آھي جنھن جي ھيٺان ڪجھ اعتراض واقع آھي (شايد اھو واقع نه ھجي، پر اسان ان تي ڳڻڻ وارا آھيون). اسان جو آخري مقصد آھي ھن اعتراض جو حوالو حاصل ڪرڻ ۽ ان کي اسان جي پروگرام ۾ استعمال ڪرڻ. تنهن ڪري، نالو ڪيترن ئي حصن (يا ٽوڪن) تي مشتمل آهي، سليش سان الڳ ٿيل. اهڙن ٽوڪن کي contexts سڏيو ويندو آهي. سڀ کان پھريون ھڪڙو سادو حوالو آھي، سڀ بعد وارا ذيلي حوالا آھن (ھاڻي بعد ۾ ذيلي حوالي سان حوالو ڏنو ويو آھي). حوالا سمجھڻ ۾ آسان آھن جيڪڏھن توھان سمجھو ٿا انھن کي ڊاريڪٽريز يا ڊاريڪٽريز جي برابر، يا صرف باقاعده فولڊر. روٽ جي حوالي سان روٽ فولڊر آهي. ذيلي حوالو هڪ ذيلي فولڊر آهي. اسان هيٺ ڏنل ڪوڊ کي هلائڻ سان ڏنل نالي جي سڀني حصن (سبب ۽ ذيلي حوالن) کي ڏسي سگهون ٿا:
Enumeration<String> elements = objectName.getAll();
while(elements.hasMoreElements()) {
System.out.println(elements.nextElement());
}
پيداوار هن ريت ٿيندي:
java:comp
env
jdbc
ٻاھر ڏيکاري ٿو ته نالي ۾ ٽوڪن ھڪ ٻئي کان ڌار ٿي ويا آھن سليش (جڏھن ته، اسان ھن جو ذڪر ڪيو آھي). هر نالي جي ٽوڪن جي پنهنجي انڊيڪس آهي. ٽوڪن انڊيڪسنگ 0 تي شروع ٿئي ٿي. روٽ جي حوالي سان انڊيڪس صفر آهي، ايندڙ حوالي سان انڊيڪس 1 آهي، ايندڙ 2 وغيره. اسان ان جي انڊيڪس ذريعي ذيلي حوالن جو نالو حاصل ڪري سگھون ٿا:
System.out.println(objectName.get(1)); // -> env
اسان اضافي ٽوڪن پڻ شامل ڪري سگھون ٿا (يا ته آخر ۾ يا انڊيڪس ۾ مخصوص جڳھ تي):
objectName.add("sub-context"); // Добавит sub-context в конец
objectName.add(0, "context"); // Добавит context в налачо
طريقن جي هڪ مڪمل فهرست سرڪاري دستاويزن ۾ ڳولهي سگهجي ٿو .
انٽرفيس جي حوالي سان
هن انٽرفيس ۾ ڪنٽينٽس جو هڪ سيٽ شامل آهي ڪنهن حوالي سان شروع ڪرڻ لاءِ، انهي سان گڏ طريقن جو هڪ سيٽ به شامل آهي حوالن کي ٺاهڻ ۽ حذف ڪرڻ، شين کي هڪ نالي سان پابند ڪرڻ، ۽ شين کي ڳولڻ ۽ حاصل ڪرڻ لاءِ. اچو ته ڪجهه عملن تي نظر رکون جيڪي هن انٽرفيس کي استعمال ڪندي انجام ڏين ٿيون. سڀ کان وڌيڪ عام عمل هڪ اعتراض جي نالي سان ڳولڻ آهي. اهو طريقو استعمال ڪندي ڪيو ويندو آهي:Object lookup(String name)
Object lookup(Name name)
bind
:
void bind(Name name, Object obj)
void bind(String name, Object obj)
Object
بائنڊنگ جو انورس آپريشن - ڪنهن شئي کي نالي مان ڪڍڻ، طريقن کي استعمال ڪندي ڪيو ويندو آهي unbind
:
void unbind(Name name)
void unbind(String name)
Initial Context
InitialContext
ھڪڙو طبقو آھي جيڪو JNDI وڻ جي روٽ عنصر جي نمائندگي ڪري ٿو ۽ Context
. توھان کي ھڪڙي خاص نوڊ جي نسبت JNDI وڻ جي اندر نالي سان شيون ڳولڻ جي ضرورت آھي. وڻ جو روٽ نوڊ اهڙي نوڊ طور ڪم ڪري سگهي ٿو InitialContext
. JNDI لاء هڪ عام استعمال ڪيس آهي:
- حاصل ڪريو
InitialContext
. InitialContext
JNDI وڻ مان نالي سان شيون ٻيهر حاصل ڪرڻ لاءِ استعمال ڪريو .
InitialContext
. اهو سڀ ان ماحول تي منحصر آهي جنهن ۾ جاوا پروگرام واقع آهي. مثال طور، جيڪڏهن هڪ جاوا پروگرام ۽ هڪ JNDI وڻ ساڳئي ايپليڪيشن سرور جي اندر هلائي رهيا آهن، اهو InitialContext
حاصل ڪرڻ بلڪل آسان آهي:
InitialContext context = new InitialContext();
جيڪڏهن اهو معاملو نه آهي، حوالو حاصل ڪرڻ ٿورو وڌيڪ ڏکيو ٿي ويندو. ڪڏهن ڪڏهن اهو ضروري آهي ته ماحول جي خاصيتن جي هڪ فهرست کي پاس ڪرڻ جي حوالي سان شروع ڪرڻ لاء:
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.fscontext.RefFSContextFactory");
Context ctx = new InitialContext(env);
مٿي ڏنل مثال ظاهر ڪري ٿو هڪ ممڪن طريقن مان هڪ سلسلي کي شروع ڪرڻ لاءِ ۽ نه ئي ڪنهن ٻئي معنيٰ وارو لوڊ. تفصيل سان ڪوڊ ۾ وڃڻ جي ڪا ضرورت ناهي.
اسپرنگ بوٽ يونٽ ٽيسٽ اندر JNDI استعمال ڪرڻ جو هڪ مثال
مٿي، اسان چيو ته JNDI لاءِ نالو ڏيڻ ۽ ڊاريڪٽري سروس سان رابطو ڪرڻ لاءِ، ضروري آھي ته ھٿ ۾ SPI (سروس فراهم ڪندڙ انٽرفيس) ھٿ ۾، جنھن جي مدد سان جاوا ۽ نالي جي سروس جي وچ ۾ انضمام ڪيو ويندو. معياري JDK ڪيترن ئي مختلف SPIs سان گڏ اچي ٿو (اسان انهن کي مٿي بيان ڪيو آهي)، جن مان هر هڪ مظاهري جي مقصدن لاءِ ٿوري دلچسپي رکي ٿو. هڪ ڪنٽينر اندر JNDI ۽ جاوا ايپليڪيشن کي وڌائڻ ڪجهه دلچسپ آهي. بهرحال، هن آرٽيڪل جو ليکڪ هڪ سست ماڻهو آهي، تنهن ڪري اهو ڏيکارڻ لاءِ ته JNDI ڪيئن ڪم ڪري ٿو، هن گهٽ ۾ گهٽ مزاحمت جو رستو چونڊيو: JNDI کي اسپرنگ بوٽ ايپليڪيشن يونٽ ٽيسٽ اندر هلائي ۽ اسپرنگ فريم ورڪ مان هڪ ننڍڙو هيڪ استعمال ڪندي JNDI حوالي سان پهچ. تنهن ڪري، اسان جو منصوبو:- اچو ته هڪ خالي اسپرنگ بوٽ پروجيڪٽ لکون.
- اچو ته هن منصوبي جي اندر هڪ يونٽ ٽيسٽ ٺاهيو.
- امتحان جي اندر اسين JNDI سان ڪم ڪرڻ جو مظاهرو ڪنداسين:
- حوالن تائين رسائي حاصل ڪريو؛
- JNDI ۾ ڪجهه نالي هيٺ ڪجهه اعتراض کي پابند (بند)؛
- اعتراض حاصل ڪريو ان جي نالي سان (ڏسڻ)؛
- اچو ته چيڪ ڪريو ته اعتراض null نه آهي.
- JDBC API؛
- H2 ڊي ڊيٽابيس.
SimpleNamingContextBuilder
. هي ڪلاس آساني سان JNDI اندر يونٽ ٽيسٽ يا اسٽينڊ اڪيلو ايپليڪيشنن کي وڌائڻ لاءِ ٺاهيو ويو آهي. اچو ته حوالو حاصل ڪرڻ لاءِ ڪوڊ لکون:
final SimpleNamingContextBuilder simpleNamingContextBuilder
= new SimpleNamingContextBuilder();
simpleNamingContextBuilder.activate();
final InitialContext context = new InitialContext();
ڪوڊ جون پھريون ٻه لائينون اسان کي آساني سان JNDI حوالي سان شروع ڪرڻ جي اجازت ڏين ٿيون. انهن کان سواء، InitialContext
هڪ استثنا اڇلايو ويندو جڏهن هڪ مثال ٺاهي: javax.naming.NoInitialContextException
. رد ڪرڻ. ڪلاس SimpleNamingContextBuilder
هڪ Deprecated طبقو آهي. ۽ هي مثال مقصد ڏيکاري ٿو ته توهان JNDI سان ڪيئن ڪم ڪري سگهو ٿا. اهي يونٽ ٽيسٽ اندر JNDI استعمال ڪرڻ لاءِ بهترين طريقا نه آهن. اهو چئي سگهجي ٿو ته هڪ قاعدي جي تعمير ۽ JNDI مان شين کي بائنڊنگ ۽ ٻيهر حاصل ڪرڻ لاء هڪ ڪڇ آهي. هڪ حوالو حاصل ڪرڻ بعد، اسان ان مان شيون ڪڍي سگهون ٿا يا حوالن ۾ شيون ڳولي سگهون ٿا. JNDI ۾ اڃا تائين ڪي به شيون نه آهن، تنهنڪري اهو منطقي هوندو ته اتي ڪجهه رکڻ لاء. مثال طور، DriverManagerDataSource
:
context.bind("java:comp/env/jdbc/datasource", new DriverManagerDataSource("jdbc:h2:mem:mydb"));
هن لڪير ۾، اسان طبقاتي اعتراض کي DriverManagerDataSource
نالي سان پابند ڪيو آهي java:comp/env/jdbc/datasource
. اڳيون، اسان نالي جي حوالي سان اعتراض حاصل ڪري سگهون ٿا. اسان وٽ ڪو به اختيار نه آهي سواءِ ان شئي کي حاصل ڪرڻ لاءِ جنهن کي اسان صرف رکون ٿا، ڇاڪاڻ ته ان حوالي سان ٻيون شيون نه آهن =(
final DataSource ds = (DataSource) context.lookup("java:comp/env/jdbc/datasource");
ھاڻي اچو ته چيڪ ڪريون ته اسان جي ڊيٽا سورس ۾ ڪنيڪشن آھي (ڪنيڪشن، ڪنيڪشن يا ڪنيڪشن ھڪڙو جاوا ڪلاس آھي جيڪو ڊيٽابيس سان ڪم ڪرڻ لاءِ ٺاھيو ويو آھي):
assert ds.getConnection() != null;
System.out.println(ds.getConnection());
جيڪڏهن اسان سڀ ڪجهه صحيح طريقي سان ڪيو، پيداوار هن طرح ڪجهه ٿيندو:
conn1: url=jdbc:h2:mem:mydb user=
اهو چوڻ جي قابل آهي ته ڪوڊ جون ڪجهه لائينون استثنا ڏئي سگھن ٿيون. هيٺيون لائينون اڇلائي وينديون آهن javax.naming.NamingException
:
simpleNamingContextBuilder.activate()
new InitialContext()
context.bind(...)
context.lookup(...)
DataSource
اهو اڇلائي سگهجي ٿو java.sql.SQLException
. انهي سلسلي ۾، اهو ضروري آهي ته ڪوڊ کي بلاڪ جي اندر عمل ڪيو وڃي try-catch
، يا امتحان يونٽ جي دستخط ۾ اشارو ڪيو وڃي ته اهو استثنا ڏئي سگهي ٿو. هتي ٽيسٽ ڪلاس جو مڪمل ڪوڊ آهي:
@SpringBootTest
class JndiExampleApplicationTests {
@Test
void contextLoads() {
try {
final SimpleNamingContextBuilder simpleNamingContextBuilder
= new SimpleNamingContextBuilder();
simpleNamingContextBuilder.activate();
final InitialContext context = new InitialContext();
context.bind("java:comp/env/jdbc/datasource", new DriverManagerDataSource("jdbc:h2:mem:mydb"));
final DataSource ds = (DataSource) context.lookup("java:comp/env/jdbc/datasource");
assert ds.getConnection() != null;
System.out.println(ds.getConnection());
} catch (SQLException | NamingException e) {
e.printStackTrace();
}
}
}
ٽيسٽ هلائڻ کان پوءِ، توھان ھيٺ ڏنل لاگز ڏسي سگھو ٿا:
o.s.m.jndi.SimpleNamingContextBuilder : Activating simple JNDI environment
o.s.mock.jndi.SimpleNamingContext : Static JNDI binding: [java:comp/env/jdbc/datasource] = [org.springframework.jdbc.datasource.DriverManagerDataSource@4925f4f5]
conn1: url=jdbc:h2:mem:mydb user=
GO TO FULL VERSION