2012-04-03 19 views
26

मैं एक एप्लिकेशन (क्वार्ट्ज शेड्यूलर) विकसित करने की प्रक्रिया में हूं जहां हमारे पास नौकरी कक्षा है जो वास्तव में काम को निष्पादित करने के लिए ज़िम्मेदार है और हमें नौकरी कक्षा के नाम को बताने/पास करने की आवश्यकता है क्वार्ट्ज शेड्यूलर में एक ट्रिगर बनाने के दौरान।एक विशिष्ट इंटरफ़ेस को लागू करने वाले सभी वर्गों को ढूंढना

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

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

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

क्या कोई सुझाव दे सकता है कि मैं उपर्युक्त लक्ष्य कैसे प्राप्त कर सकता हूं या क्या मैं ऐसा करने का प्रयास करने का कोई और बेहतर तरीका है?

संपादित

मैं ServiceLoader के दस्तावेज़ के माध्यम से चला गया और ऐसा लगता है एक कार्यान्वयन वर्ग का नाम है, जो मुझे करने के लिए सुराग के साथ META-INF फ़ोल्डर में एक फ़ाइल बनाने के लिए है कि एक सेवा लागू करने के लिए ऐसा लगता है कि यदि मेरे एपीआई का उपयोगकर्ता 20 अलग-अलग कार्यान्वयन चाहता है, तो उसे फ़ाइल में 20 प्रविष्टियां डालना पड़ता है, जो मेरे लिए अंतिम उपयोगकर्ता के लिए बहुत अधिक काम करता है क्योंकि प्रत्येक नौकरी कक्षा एक विशिष्ट नौकरी निष्पादित करने के लिए बनाई जाएगी और वहां नौकरी कक्षाओं के 100 के हो।

अगर मेरी धारणा गलत है तो कृपया मुझे सही करें।

+2

एक और प्रयास एनोटेशन बनाने और फिर एनोटेटेड कक्षाओं की खोज करना है। यहां http://stackoverflow.com/questions/259140/scanning-java-annotations-at-runtime कहता है कि इसे कैसे प्राप्त किया जाए। – polypiel

+0

क्या यह मदद करेगा? [लिंक] (http://www.javaworld.com/javaworld/javaqa/2003-07/02-qa-0725-classsrc2.html?page=1) – titogeo

उत्तर

30

मैं एक ऐसी ही जरूरत है, जहां मुझे यकीन है कि कि एक निश्चित इंटरफ़ेस कार्यान्वित बनाए गए किसी भी कक्षाओं हमेशा सही मायने में serializable थे बनाना चाहते थे था। मैंने जावा क्लासफाइंडर बनाया जो क्लासपाथ में सभी निर्देशिकाओं के माध्यम से चलता है, और इंटरफ़ेस के लिए आवंटित सभी कक्षाएं पाता है जिनकी मुझे परवाह है। यहां एक कोड स्निपेट है:

public <T> List<Class<? extends T>> findAllMatchingTypes(Class<T> toFind) { 
    foundClasses = new ArrayList<Class<?>>(); 
    List<Class<? extends T>> returnedClasses = new ArrayList<Class<? extends T>>(); 
    this.toFind = toFind; 
    walkClassPath(); 
    for (Class<?> clazz : foundClasses) { 
     returnedClasses.add((Class<? extends T>) clazz); 
    } 
    return returnedClasses; 
} 

यदि यह मदद करता है तो मुझे आपके साथ कोड साझा करने में खुशी होगी। एकमात्र ड्रॉ बैक यह है कि यह केवल .class फ़ाइलों को संभालेगा - मैंने .zars को अनजिप करने और वहां से क्लास फ़ाइलों को पढ़ने के लिए सुविधा नहीं जोड़ा है। (लेकिन यह जोड़ने के लिए यह एक बड़ी परियोजना नहीं होगी।)

अद्यतन: मैंने उपर्युक्त के लिए अपना स्रोत कोड चेक किया, और पाया कि यह हमारी मानक उपयोगिता पुस्तकालय में कई सहायक वर्गों पर निर्भर करता है। इसे आसान बनाने के लिए, मैंने आवश्यक सभी कोड ज़िप्प किया, जिसे आप JavaClassFinder.zip से डाउनलोड कर सकते हैं। यह सीधे ग्रहण में स्थापित होगा, और आप जिस कोड की आवश्यकता है उसे आप ले सकते हैं।

आपको JavaClassFinderTest.java नामक प्रोजेक्ट में JUnit3 परीक्षण मिलेगा, जो आपको JavaClassFinder क्लास की विशेषताओं और उपयोग को दिखाता है। जूनिट टेस्ट चलाने के लिए आवश्यक एकमात्र बाहरी निर्भरता जुनीट है। इस उपयोगिता के

बेसिक उपयोग:

JavaClassFinder classFinder = new JavaClassFinder(); 
    List<Class<? extends MyTagInterface>> classes = classFinder.findAllMatchingTypes(MyTagInterface.class); 

यह आपको एक सूची है जो classpath में किसी भी वर्ग है जो "MyTagInterface.class" (उदाहरण के लिए) से आबंटित होते हैं दे देंगे। उम्मीद है की यह मदद करेगा।

+0

"walkClassPath" विधि की कमी है। क्या आप इसे कृपया प्रदान कर सकते हैं? –

+0

@YvesMartin: Yves, मैंने मूल कोड डाउनलोड करने के लिए सभी लिंक शामिल करने के लिए अपना उत्तर अपडेट किया। यह आपके इच्छित से अधिक हो सकता है, लेकिन यह एक पूर्ण कार्य संस्करण है। –

+2

@ सैमगोल्डबर्ग उत्कृष्ट उपयोगिता जो आपने यहां डिज़ाइन की है। – shashankaholic

0

जावा एसपीआई तंत्र का उपयोग करके ऐसा करने के लिए शायद सबसे अच्छा (मानक) तरीका, Javadoc देखें। असुविधाजनक (जो एक अच्छी सुविधा भी है) यह है कि यह जार की अपेक्षा करता है जो META-INF/services/your.fully.qualified.Interface में उन्हें सूचीबद्ध करने के लिए एक्सटेंशन को परिभाषित करता है।

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

27

आप उत्तर here देख सकते हैं।

मैं org.reflections

enter link description here

Reflections reflections = new Reflections("com.mycompany");  
Set<Class<? extends MyInterface>> classes = reflections.getSubTypesOf(MyInterface.class); 
+0

इनपुट के लिए धन्यवाद, मैं ServiceLocator दस्तावेज़ के माध्यम से जा रहा था, यह मेरे इंटरफ़ेस (सेवा) के प्रत्येक प्रत्यारोपण के लिए प्रतीत होता है, अंतिम उपयोगकर्ता को फ़ाइल में प्रविष्टि डालना पड़ता है ताकि इसे लोड किया जा सके, ऐसा लगता है कि डेवलपर 20 ऐसे प्रत्यारोपण चाहता है, उसे उन सभी प्रत्यारोपण नामों को रखना होगा फ़ाइल, अंतिम उपयोगकर्ता के लिए बहुत काम लगता है। –

1

मुझे लगता है कि org.reflections एक उचित समाधान के रूप में एलेक्स Stybaev ने उल्लेख किया है का उपयोग कर सकते हैं सुझाव है, तो आप एक संपत्ति फ़ाइल में कक्षाओं को संदर्भित करने की जरूरत नहीं है ।

एक और दृष्टिकोण (जो मैं लेता हूं) Spring है, क्योंकि मैं अपने अनुप्रयोगों के लिए वसंत का उपयोग कर रहा हूं और इसलिए किसी भी अतिरिक्त निर्भरता की आवश्यकता नहीं होगी।

आप (अन्य टिप्पणी या उत्तर में और विकल्प) वसंत के साथ आपकी समस्या को हल करने के लिए संकेत मिल सकता है यहां:

टिप्पणी में आपके प्रश्न हेइककिम और पॉलीपीएल के प्रश्नों से भी जुड़े हैं जिनके पास स्प्रिंग के साथ इसे हल करने के उत्तर हैं:

0

शुद्ध जावा में ऐसा करने के लिए, सबसे सही जवाब पहले से ही (सैम गोल्डबर्ग अप्रैल से 10,2012) मतदान है

के बारे में उनकी अनावश्यक रूप से जटिल है लेकिन पूर्ण कोड। मैं अपने विचार किया जाता है और वहाँ ClassFinder धकेल दिया: http://icedtea.classpath.org/hg/icedtea-web/file/0527ad4eb2dd/netx/net/sourceforge/jnlp/controlpanel/ClassFinder.java

नोट - इस योग्य स्वतंत्र अनुप्रयोग (या जार और dirs साथ नियमित रूप से classpath का उपयोग कर किसी भी आवेदन) ServerContainer में नहीं में काम करेंगे।

यदि आपका ऐप वेबसर्वर में चल रहा है, तो आपको अपने युद्ध/कान का स्थान जानना होगा और वहां खोजना होगा। या आपको अपने माता-पिता क्लासलोडर से पूछना है कि वह आपको अपना (और अन्य) स्रोत प्राप्त कर रहा है।

दूसरा नोट - मैं केवल नेटक्स और आईसीडटेटा-वेब से मेल खाने के लिए अंतिम स्थान कक्षाओं को फ़िल्टर कर रहा हूं क्योंकि मैं निर्भरता की खोज नहीं करता हूं। तो अगर आपको rt.jar को शामिल करने की आवश्यकता है, तो कृपया फिल्टर को हटा दें। या बूटक्लासपैथ को हटा दें यदि आप इसके विपरीत नहीं हैं तो इसकी आवश्यकता नहीं है।

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

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