द्वारा निष्पादित किया गया है, मैं क्लासपाथ में कुछ संसाधनों की क्वेरी के लिए Google Reflections library का उपयोग कर रहा हूं। वे संसाधन मेरी परियोजना में कक्षाओं की तुलना में एक ही स्थान पर स्थित हैं।प्रतिबिंब का उपयोग कर यूनिट परीक्षण Google लाइब्रेरी केवल तभी विफल होता है जब मैवेन
मैंने कुछ यूनिट परीक्षण लिखे जो एक्लिप्स में यूनिट टेस्ट के रूप में निष्पादित होने पर सफल हुए, लेकिन जब मैं उन्हें मेवेन के साथ निष्पादित करने का प्रयास करता हूं (उदाहरण के लिए maven install
के साथ), वे अपेक्षित काम नहीं कर रहे हैं। कुछ डिबगिंग के बाद, स्पष्ट रूप से समस्या यह है कि जब मैवेन के साथ निष्पादित किया गया, प्रतिबिंब पुस्तकालय क्लासपाथ यूआरएल नहीं ढूंढ सकता जहां संसाधन स्थित हैं।
मैं उस निष्कर्ष पर पहुंचा कि कैसे प्रतिबिंब क्लासपाथ यूआरएल निर्धारित करता है जिसका निरीक्षण किया जाना चाहिए।
public static Set<URL> forClassLoader(ClassLoader... classLoaders) {
final Set<URL> result = Sets.newHashSet();
for (ClassLoader classLoader : classLoaders) {
while (classLoader != null) {
if (classLoader instanceof URLClassLoader) {
URL[] urls = ((URLClassLoader) classLoader).getURLs();
if (urls != null) {
result.addAll(Sets.<URL>newHashSet(urls));
}
}
classLoader = classLoader.getParent();
}
}
return result;
}
संक्षेप में, यह वर्ग लोडर पदानुक्रम के लिए पूछ traversing है: उदाहरण के लिए, निम्नलिखित विधि कैसे कुछ विचार एक वर्ग लोडर (मूल विचार विधि थोड़ा सरलीकृत किया गया है) दिया पाता उपलब्ध classpath यूआरएल पता चलता प्रत्येक व्यक्तिगत क्लासलोडर के यूआरएल।
ग्रहण में मैं कुछ इस तरह के साथ एक इकाई परीक्षण से पिछले विधि आह्वान जब:
ClassLoader myClassClassLoader = <MyClass>.class.getClassLoader(); //<MyClass> is in the same classpath url than the resources I need to find
Set<URL> urls = forClassLoader(myClassClassLoader);
for(URL url : urls) {
System.out.println("a url: " + url);
की उम्मीद के रूप में, मैं (कई अन्य यूआरएल के अलावा) देख सकते हैं classpath URL हैं, जो के हिस्से के रूप में विन्यस्त कर रहे हैं मेरे परियोजना:
file:<MY_PROJECT_PATH>/target/classes/
file:<MY_PROJECT_PATH>/target/test-classes/
और कुछ विचार एक आकर्षण (संसाधनों विचार file:<MY_PROJECT_PATH>/target/classes/
में स्थित हैं खोजना चाहिए) के रूप में काम करता है।
हालांकि, जब मैवेन द्वारा परीक्षण निष्पादित किया जाता है, तो मुझे एहसास हुआ कि forClassLoader
विधि द्वारा लौटाए गए सेट से ये यूआरएल प्रविष्टियां गायब हैं, और शेष प्रतिबिंब विधियां इस समस्या के लिए अपेक्षित काम नहीं कर रही हैं।
"आश्चर्य की बात" बात यह है कि अगर मैं इस बारे में जब इकाई परीक्षण Maven द्वारा निष्पादित किया जाता है:
ClassLoader myClassClassLoader = <MyClass>.class.getClassLoader();
url = myClassClassLoader.getResource("anExistingResource");
System.out.println("URL: "+url); //a valid URL
मैं देख सकता हूँ कि वर्ग लोडर अभी भी संसाधन मैं खोजने की कोशिश कर रहा हूँ हल कर सकते हैं। मैं इस बारे में परेशान हूं कि क्यों मेवेन के साथ निष्पादित किया गया था forClassLoader
विधि में मेरे प्रोजेक्ट के क्लासपाथ यूआरएल लौटाए गए सेट में शामिल नहीं है, हालांकि साथ ही यह ऐसे यूआरएल (!) में स्थित संसाधनों को हल करने में सक्षम है।
इस व्यवहार का कारण क्या है? क्या मेवेन द्वारा चलाए गए यूनिट टेस्ट के हिस्से के रूप में आमंत्रित किए जाने पर मैं प्रतिबिंब लाइब्रेरी का काम करने की कोशिश कर सकता हूं?
यूआरएल हैशसेट में है? मुझे इस जावा पहेली की याद दिलाई जा रही है: http://javaantipatterns.wordpress.com/2007/11/24/comparing-urls-with-urlequals/ – Rekin
दिलचस्प लिंक @ रेकिन, लेकिन किसी भी मामले में उनको रखना संभव है समस्या के बिना एक सेट में यूआरएल, शायद क्योंकि वे स्थानीय जार और निर्देशिका (?) को इंगित कर रहे हैं यकीन नहीं है ... (मैंने वह कोड नहीं लिखा है, इसे सिर्फ प्रतिबिंब Google लाइब्रेरी से लिया है)। जिज्ञासा से बाहर, अगर आपको पता है कि यह क्यों काम कर रहा है (स्पष्ट रूप से आपके लिंक का विरोधाभास) कृपया मुझे बताएं! – Sergio