java - जावा के लिए कोई भी उपयोग क्यों नहीं कर रहा है?




ant makefile maven (15)

चींटी और बाद में मेवेन को Make कारण कुछ सिरदर्द हल करने के लिए डिजाइन किया गया था (प्रक्रिया में नए बनाने के दौरान) यह सिर्फ विकास है।

... इसके तुरंत बाद, कई खुले स्रोत जावा परियोजनाओं को एहसास हुआ कि चींटी मेकफ़ाइल के साथ उनकी समस्याओं को हल कर सकती है ....

http://ant.apache.org/faq.html#history

चाहे वे कुछ भी हल करें या सीखने के लिए एक अतिरिक्त प्रारूप बनाएं, एक व्यक्तिपरक विषय है। सच्चाई यह है कि हर नए आविष्कार का इतिहास काफी अधिक है: निर्माता कहते हैं कि यह कई समस्याओं का समाधान करता है और मूल उपयोगकर्ता कहते हैं कि वे गुण हैं।

इसका मुख्य लाभ जावा के साथ एकीकृत करने की संभावना है।

मुझे लगता है कि उदाहरण के लिए rake के साथ एक समान इतिहास होगा।

मैंने जो भी जावा प्रोजेक्ट देखा है, उसके बारे में मैवेन या चींटी का उपयोग करता है। वे अच्छे उपकरण हैं और मुझे लगता है कि किसी भी परियोजना के बारे में सिर्फ उनका उपयोग कर सकते हैं। लेकिन क्या करने के make कभी हुआ? इसका उपयोग विभिन्न गैर-जावा परियोजनाओं के लिए किया जाता है और आसानी से जावा को संभाल सकता है। निश्चित रूप से आपको make.exe डाउनलोड करना होगा यदि आप विंडोज का उपयोग करते हैं, लेकिन चींटी और मेवेन भी जेडीके के साथ नहीं आते हैं।

क्या जावा के साथ उपयोग किए जाने के साथ कुछ मौलिक दोष है? क्या ऐसा इसलिए है क्योंकि जावा में चींटी और मेवेन लिखे गए हैं?


स्क्रिप्ट को स्वाभाविक रूप से प्लेटफॉर्म पर निर्भर करते हैं। जावा प्लेटफ़ॉर्म स्वतंत्र होना चाहिए। इसलिए एक निर्माण प्रणाली है जो एक बहु-मंच स्रोतबेस के लिए केवल एक मंच पर काम करती है, एक समस्या है।


जब तक कि मैं कोई भी धारणा नहीं हूं, जावा के लिए कोई भी गलत नहीं है (गलत) गलत है।

"जीएनयू मेक के साथ प्रबंध परियोजनाएं" (जीएफडीएल के तहत उपलब्ध) में जावा परियोजनाओं के साथ उपयोग करने के लिए समर्पित एक पूर्ण अध्याय है।

चूंकि इसमें अन्य उपकरणों के बजाय उपयोग करने के पेशेवरों और विपक्ष की एक लंबी (और उम्मीदवार निष्पक्ष) सूची शामिल है, तो आप वहां एक नज़र डालना चाहते हैं। (देखें: http://oreilly.com/catalog/make3/book/ )


ApacheAnt मेक की तरह कुछ भी नहीं है। फ़ाइलों के बीच निर्भरताओं का वर्णन करने और फ़ाइलों को बनाने के तरीके के बारे में है। चींटी "कार्यों" के बीच निर्भरताओं के बारे में है, और वास्तव में ग्लूइंग बिल्ड स्क्रिप्ट्स का एक तरीका है।

यह आपको AntVsMake मदद कर AntVsMake


मेवेन (और आइवी-सक्षम चींटी सेटअप) द्वारा हल किए गए प्रमुख मुद्दों में से एक स्वचालित निर्भरता संकल्प और आपके निर्भरता जार डाउनलोड करना है।


मेक और जावा के साथ मौलिक मुद्दा यह है कि इस आधार पर काम करें कि आपने निर्भरता निर्दिष्ट की है, और फिर उस निर्भरता को हल करने के लिए एक नियम है।

मूल सी के साथ, आमतौर पर "एक main.c फ़ाइल को main.o फ़ाइल में कनवर्ट करने के लिए," cc main.c "चलाएं।

आप जावा में ऐसा कर सकते हैं, लेकिन आप जल्दी से कुछ सीखते हैं।

ज्यादातर जेवाक कंपाइलर शुरू करने में धीमा है।

के बीच भिन्नता:

javac Main.java
javac This.java
javac That.java
javac Other.java

तथा

javac Main.java This.java That.java Other.java

रात और दिन है

बढ़ोतरी करें कि सैकड़ों वर्गों के साथ, और यह सिर्फ अस्थिर हो जाता है।

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

संग्रह स्तर पर, कौन सी फाइलें पुरानी हैं, यह निर्धारित करने में भी बहुत अच्छा नहीं है।

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

यही कारण है कि चींटी और मेवेन जैसे विकल्प बढ़ गए।


दरअसल, सभी पुरानी जावा फाइलों के एक कमांड में पुनर्मूल्यांकन को संभाल सकते हैं। यदि आप निर्देशिका में सभी फाइलों को संकलित नहीं करना चाहते हैं या एक विशिष्ट आदेश चाहते हैं तो पहली पंक्ति बदलें ...

JAVA_FILES:=$(wildcard *.java)
#
# the rest is independent of the directory
#
JAVA_CLASSES:=$(patsubst %.java,%.class,$(JAVA_FILES))

.PHONY: classes
LIST:=

classes: $(JAVA_CLASSES)
        if [ ! -z "$(LIST)" ] ; then \
                javac $(LIST) ; \
        fi

$(JAVA_CLASSES) : %.class : %.java
        $(eval LIST+=$$<)

प्रत्येक के तकनीकी गुणों के बारे में अन्य सभी जवाब सत्य हैं। Ant बनाने के बजाय Ant और Maven बेहतर अनुकूल हो सकते हैं, या हैंक समलैंगिक बताते हैं, वे नहीं कर सकते :)

हालांकि, आपने पूछा कि क्या यह मायने रखता है कि जावा में चींटी और मेवेन लिखे गए हैं। यद्यपि स्टैक ओवरफ्लो पर हम ऐसे विचारों पर विचार नहीं करते हैं (बंद! प्रोग्रामिंग से संबंधित नहीं! आदि), इस बात का हिस्सा है कि चीज का हिस्सा है। रेलों पर हम रेक, सी ड्यूड्स का उपयोग करते हैं, और जावा में हम चींटी और मेवेन का उपयोग करते हैं। हालांकि यह सच है कि चींटी या मेवेन डेवलपर जावा डेवलपर की तुलना में शायद दूसरों की तुलना में बेहतर होंगे, एक और सवाल भी है: आप चींटी कार्यों को क्या लिखते हैं? जावा। यदि आप जावा डेवलपर हैं, तो यह एक आसान फिट है।

तो हाँ, इसका हिस्सा उस टूल में लिखे गए टूल का उपयोग करना है जिसे आप टूलिंग कर रहे हैं।


संक्षिप्त उत्तर: क्योंकि make अच्छा नहीं है। सी फ्रंट पर भी आप पॉप अप करने के कई विकल्प देखते हैं।

लंबा उत्तर: make में कई त्रुटियां होती हैं जो सी को संकलित करने के लिए मुश्किल से उपयुक्त बनाती हैं, और जावा को संकलित करने के लिए अनुपयुक्त होती हैं। यदि आप चाहें तो जावा को संकलित करने के लिए आप इसे मजबूर कर सकते हैं, लेकिन मुद्दों में भाग लेने की उम्मीद करते हैं, जिनमें से कुछ में उपयुक्त समाधान या कामकाज नहीं है। यहाँ कुछ है:

निर्भरता संकल्प

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

जावा में, निर्भरता परिपत्र हो सकती है, और प्रारूप make में ऑटो-जनरेटिंग क्लास निर्भरताओं के लिए कोई उपकरण नहीं है। ant का Depend कार्य, बजाय, कक्षा फ़ाइल को सीधे पढ़ सकता है, यह निर्धारित कर सकता है कि यह कौन से वर्ग आयात करता है, और कक्षा फ़ाइल को हटा दें यदि उनमें से कोई भी पुराना है। इसके बिना, किसी भी गैर-तुच्छ निर्भरता के परिणामस्वरूप आपको दोबारा साफ निर्माण का उपयोग करने के लिए मजबूर होना पड़ सकता है, जिससे निर्माण उपकरण का उपयोग करने का कोई फायदा हो जाता है।

फ़ाइल नामों में रिक्त स्थान

जबकि न तो जावा और न ही आपके स्रोत कोड फ़ाइल नामों में रिक्त स्थान का उपयोग करके प्रोत्साहित करते हैं, यह भी समस्या हो सकती है भले ही रिक्त स्थान फ़ाइल पथ में हों। उदाहरण के लिए, यदि आपका स्रोत कोड C:\My Documents\My Code\program\src में मौजूद है, तो विचार करें। यह तोड़ने के make पर्याप्त होगा। ऐसा इसलिए है क्योंकि तारों के रूप में फ़ाइल नाम का इलाज करते हैं। ant विशेष वस्तुओं के रूप में पथ का इलाज करता है।

निर्माण के लिए फाइल स्कैनिंग

प्रत्येक लक्ष्य के लिए कौन सी फाइलें बनाई जानी चाहिए, इसे स्पष्ट रूप से सेट make आवश्यकता है। ant एक फ़ोल्डर निर्दिष्ट करने की अनुमति देता है जो स्रोत फ़ाइलों के लिए स्वत: स्कैन किया जाना है। यह मामूली सुविधा की तरह प्रतीत हो सकता है, लेकिन इस बात पर विचार करें कि जावा में प्रत्येक नई कक्षा को एक नई फ़ाइल की आवश्यकता होती है। परियोजना में फाइलें जोड़ना एक बड़ी परेशानी तेज हो सकता है।

और make साथ सबसे बड़ी समस्या:

POSIX- निर्भर है

जावा का आदर्श वाक्य "संकलन एक बार हर जगह चलाएं" है। लेकिन उस संकलन को POSIX- आधारित सिस्टम में प्रतिबंधित करना, जिसमें जावा समर्थन वास्तव में सबसे खराब है, इरादा नहीं है।

बनाने में नियम make अनिवार्य रूप से छोटे bash स्क्रिप्ट हैं। भले ही विंडोज़ make का एक बंदरगाह है, इसके लिए इसे ठीक से काम करने के लिए, इसे bash बंदरगाह के साथ बंडल किया जाना चाहिए, जिसमें फ़ाइल सिस्टम के लिए एक पॉज़िक्स इम्यूलेशन परत शामिल है।

यह दो किस्मों में आता है:

  1. MSYS जो फ़ाइल पथों में POSIX अनुवाद को सीमित करने का प्रयास करता है, और इसलिए विशेष रूप से इसके लिए बनाए गए बाहरी उपकरण चलाते समय अप्रिय गेटचास हो सकता है।

  2. cygwin जो एक पूर्ण POSIX अनुकरण प्रदान करता है। परिणामी कार्यक्रम, हालांकि, अभी भी उस इम्यूलेशन परत पर भरोसा करते हैं।

इसी कारण से, विंडोज़ पर, मानक निर्माण उपकरण भी बिल्कुल नहीं make , बल्कि MSBuild , जो एक एक्सएमएल-आधारित उपकरण भी है, जो ant सिद्धांत में करीब है।

इसके विपरीत, जावा में ant बनाई गई है, हर जगह चल सकती है, और आंतरिक कार्यों को "कार्यों" कहा जाता है, फाइलों में हेरफेर करने और मंच-स्वतंत्र तरीके से कमांड निष्पादित करने के लिए। यह पर्याप्त बहुमुखी है कि आप वास्तव में make उपयोग make से ant का उपयोग कर विंडोज में एक सी प्रोग्राम बनाने में आसान समय ले सकते make

और एक आखिरी मामूली एक:

यहां तक ​​कि सी प्रोग्राम भी मूल रूप से उपयोग नहीं करते हैं

आप प्रारंभ में यह ध्यान नहीं दे सकते हैं, लेकिन सी प्रोग्राम आम तौर पर Makefile साथ नहीं भेजे जाते हैं। उन्हें एक CMakeLists.txt , या एक bash कॉन्फ़िगरेशन स्क्रिप्ट के साथ भेज दिया जाता है, जो वास्तविक CMakeLists.txt उत्पन्न करता है। इसके विपरीत, ant का उपयोग करके बनाए गए जावा प्रोग्राम का स्रोत पूर्व-निर्मित ant स्क्रिप्ट के साथ भेज दिया जाता है। एक Makefile अन्य टूल्स का एक उत्पाद है - यह है कि अपने आप को एक बिल्ड टूल बनने के लिए कितना अनुचित है। ant स्टैंडअलोन है, और आपकी जावा बिल्ड प्रक्रिया के लिए आवश्यक सभी चीज़ों से संबंधित है, बिना किसी अतिरिक्त आवश्यकता या निर्भरताओं के।

जब आप किसी प्लेटफ़ॉर्म पर ant चलाते हैं, तो यह जस्ट वर्क्स (टीएम) होता है। आप इसे make साथ नहीं मिल सकते make । यह अविश्वसनीय रूप से मंच और विन्यास निर्भर है।


चींटी मेकफ़ाइल और मेवेन पर एक एक्सएमएल कॉन्फ़िगरेशन उन्मुख सुधार है जो एंटी पर एक निर्भरता निर्माण उपकरण सुधार है। कुछ परियोजनाएं तीनों का उपयोग करती हैं। मुझे लगता है कि जेडीके परियोजनाओं मेकफ़ाइल और चींटी के मिश्रण का उपयोग करने के लिए प्रयोग किया जाता है।


मैंने कभी जावा परियोजनाओं के लिए जीएनयू मेक का उपयोग नहीं किया है, लेकिन मैं jmk का उपयोग jmk । अफसोस की बात है कि इसे 2002 से अद्यतन नहीं किया गया है।

इसमें कुछ जावा-विशिष्ट कार्यक्षमता थी, लेकिन इसके आकार को काफी बढ़ाए बिना आपके स्रोत टैरबॉल में शामिल करने के लिए काफी छोटा था।

आजकल मैं एंटी इंस्टॉल किए गए किसी भी जावा डेवलपर I शेयर कोड को मानता हूं।


एक बार एक बार मैंने जावा प्रोजेक्ट पर काम किया जो जीएमके का इस्तेमाल करता था। मेरी यादें आलसी हैं लेकिन आईआईआरसी हमें पैकेज निर्देशिका संरचना से निपटने में कठिनाई होती है जिसे जावैक उम्मीद करता है। मुझे यह भी याद है कि जेएआर फाइलों का निर्माण एक परेशानी थी जब तक कि आपके पास कुछ मामूली न हो।


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

हालांकि, जावा में, कंपाइलर को वास्तव में आयात के साथ import करने वाले अन्य वर्गों को संकलित import । यद्यपि कुछ ऐसा लिखना संभव होगा जो जावा स्रोत कोड से सभी आवश्यक निर्भरताओं को उत्पन्न करता है, ताकि एक समय में सही क्रम में कक्षाएं make सकें, फिर भी यह परिपत्र निर्भरताओं जैसे मामलों को संभाल नहीं पाएगा।

जावा कंपाइलर पहले से संकलित किए गए परिणामों के आधार पर आगे की कक्षाओं को संकलित करते समय अन्य कक्षाओं के संकलित परिणामों को कैशिंग करके अधिक कुशल भी हो सकता है। इस तरह के स्वचालित निर्भरता मूल्यांकन अकेले make साथ वास्तव में संभव नहीं है।


मुझे लगता है कि सबसे अधिक संभावना स्पष्टीकरण यह है कि कई कारकों ने जावा समुदाय के भीतर एक महत्वपूर्ण अवधि (1 99 0 के उत्तरार्ध में) में उपयोग के उपयोग को हतोत्साहित किया:

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

संक्षेप में, जावा परियोजनाओं के लिए सबसे निश्चित रूप से उपयोग किया जा सकता है, लेकिन इसे वास्तव में जावा बिल्ड टूल बनाने का मौका था। वह पल पारित हो गया है।


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

Serialization के लिए कुछ नियम हैं

  • एक वस्तु केवल serializable है अगर इसकी कक्षा या इसके superclass serializable इंटरफ़ेस लागू करता है

  • एक ऑब्जेक्ट serializable है (स्वयं serializable इंटरफ़ेस लागू करता है) भले ही इसका सुपरक्लास नहीं है। हालांकि, serializable वर्ग के पदानुक्रम में पहला सुपरक्लास, जो Serializable इंटरफेस लागू नहीं करता है, एक नो-Arg कन्स्ट्रक्टर होना चाहिए। यदि इसका उल्लंघन किया जाता है, तो readObject () रनटाइम में java.io.InvalidClassException उत्पन्न करेगा

  • सभी आदिम प्रकार serializable हैं।

  • क्षणिक फ़ील्ड (क्षणिक संशोधक के साथ) क्रमबद्ध नहीं हैं, (यानी, सहेजा या बहाल नहीं किया गया)। एक वर्ग जो Serializable लागू करता है उन वर्गों के क्षणिक फ़ील्ड को चिह्नित करना चाहिए जो serialization (उदाहरण के लिए, एक फ़ाइल स्ट्रीम) का समर्थन नहीं करते हैं।

  • स्टेटिक फ़ील्ड (स्थिर संशोधक के साथ) क्रमबद्ध नहीं हैं।

जब ऑब्जेक्ट को क्रमबद्ध किया जाता है तो जावा रनटाइम सीरियल संस्करण संख्या को संबद्ध करता है जिसे धारावाहिक VersionID कहा जाता है।

जहां हमें serialVersionID की आवश्यकता है: यह सत्यापित करने के लिए deserialization के दौरान प्रेषक और रिसीवर serialization के संबंध में संगत हैं। अगर रिसीवर अलग serialVersionID के साथ वर्ग लोड किया तो deserialization अवैध क्लासकास्टएक्सप्शन के साथ खत्म हो जाएगा।
एक धारावाहिक वर्ग "serialVersionUID" नामक फ़ील्ड घोषित करके स्पष्ट रूप से स्थिर, अंतिम और प्रकार का होना चाहिए:।

आइए इसे एक उदाहरण के साथ आज़माएं।

import java.io.Serializable;    
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
private String empname;
private byte empage;

public String getEmpName() {
    return name;
}
public void setEmpName(String empname) {
    this.empname = empname;
}
public byte getEmpAge() {
    return empage;
}
public void setEmpAge(byte empage) {
    this.empage = empage;
}

public String whoIsThis() {
    StringBuffer employee = new StringBuffer();
    employee.append(getEmpName()).append(" is ).append(getEmpAge()).append("
years old  "));
    return employee.toString();
}
}

Serialize ऑब्जेक्ट बनाएँ

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class Writer {
public static void main(String[] args) throws IOException {
    Employee employee = new Employee();
    employee.setEmpName("Jagdish");
    employee.setEmpAge((byte) 30);

    FileOutputStream fout = new 
FileOutputStream("/users/Jagdish.vala/employee.obj");
    ObjectOutputStream oos = new ObjectOutputStream(fout);
    oos.writeObject(employee);
    oos.close();
    System.out.println("Process complete");
}
}

वस्तु Deserializ

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class Reader {
public static void main(String[] args) throws ClassNotFoundException, 
IOException {
    Employee employee = new Employee();
    FileInputStream fin = new 
    FileInputStream("/users/Jagdish.vala/employee.obj");
    ObjectInputStream ois = new ObjectInputStream(fin);
    employee = (Employee) ois.readObject();
    ois.close();
    System.out.println(employee.whoIsThis());
 }
}    

नोट: अब कर्मचारी वर्ग के serialVersionUID को बदलें और सहेजें:

private static final long serialVersionUID = **4L**;

और रीडर वर्ग निष्पादित करें। लेखक वर्ग को निष्पादित नहीं करना है और आपको अपवाद मिलेगा।

Exception in thread "main" java.io.InvalidClassException: 
com.jagdish.vala.java.serialVersion.Employee; local class incompatible: 
stream classdesc serialVersionUID = 1, local class serialVersionUID = 4
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:616)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1623)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1518)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1774)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
at com.krishantha.sample.java.serialVersion.Reader.main(Reader.java:14)




java ant makefile maven