मुझे लगता है कि आप पहले ही जानते हैं कि बंडल कैसे बनाएं (अन्यथा, this देखें)।
कुछ debuging और कुछ विचार एपीआई के अन्वेषण के बाद मैंने महसूस किया है कि समस्या यह है कि कुछ विचार बस OSGi URL पढ़ने में विफल हो जाता है (bundleresource: // ...) एक अपवाद है, जिसके परिणामस्वरूप:
org.reflections.ReflectionsException: could not create Vfs.Dir from url,
no matching UrlType was found [bundleresource://1009.fwk651584550/]
और इस सुझाव:
either use fromURL(final URL url, final List<UrlType> urlTypes)
or use the static setDefaultURLTypes(final List<UrlType> urlTypes)
or addDefaultURLTypes(UrlType urlType) with your specialized UrlType.
तो मैं OSGi के लिए एक UrlType को लागू करने का मानना है (उदाहरण के लिए class BundleUrlType implements UrlType {...}
) और इस तरह यह दर्ज की:
Vfs.addDefaultURLTypes(new BundleUrlType());
प्रतिबिंब एपीआई को बंडल के अंदर से उपयोग करने योग्य बनाना चाहिए। here वर्णित अनुसार प्रतिबिंब निर्भरता ग्रहण प्लगइन परियोजना में प्रतिबिंब निर्भरताओं को जोड़ा जाना चाहिए।
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: ReflectivePlugin
Bundle-SymbolicName: ReflectivePlugin
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: reflectiveplugin.Activator
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Import-Package: javax.annotation;version="1.0.0",
org.osgi.framework;version="1.3.0",
org.osgi.service.log;version="1.3",
org.osgi.util.tracker;version="1.3.1"
Bundle-ClassPath: .,
lib/dom4j-1.6.1.jar,
lib/guava-r08.jar,
lib/javassist-3.12.1.GA.jar,
lib/reflections-0.9.5.jar,
lib/slf4j-api-1.6.1.jar,
lib/xml-apis-1.0.b2.jar
Export-Package: reflectiveplugin,
reflectiveplugin.data
नोट::
यह कैसे मेरे नमूना MANIFEST.MF जरूरत जार जोड़ने के बाद की तरह दिखाई देता है प्रयुक्त कुछ विचार वी 0.9.5
यहां नमूने UrlType कार्यान्वयन है:।
package reflectiveplugin;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.Iterator;
import org.osgi.framework.Bundle;
import org.reflections.vfs.Vfs;
import org.reflections.vfs.Vfs.Dir;
import org.reflections.vfs.Vfs.File;
import org.reflections.vfs.Vfs.UrlType;
import com.google.common.collect.AbstractIterator;
public class BundleUrlType implements UrlType {
public static final String BUNDLE_PROTOCOL = "bundleresource";
private final Bundle bundle;
public BundleUrlType(Bundle bundle) {
this.bundle = bundle;
}
@Override
public boolean matches(URL url) {
return BUNDLE_PROTOCOL.equals(url.getProtocol());
}
@Override
public Dir createDir(URL url) {
return new BundleDir(bundle, url);
}
public class BundleDir implements Dir {
private String path;
private final Bundle bundle;
public BundleDir(Bundle bundle, URL url) {
this(bundle, url.getPath());
}
public BundleDir(Bundle bundle, String p) {
this.bundle = bundle;
this.path = p;
if (path.startsWith(BUNDLE_PROTOCOL + ":")) {
path = path.substring((BUNDLE_PROTOCOL + ":").length());
}
}
@Override
public String getPath() {
return path;
}
@Override
public Iterable<File> getFiles() {
return new Iterable<Vfs.File>() {
public Iterator<Vfs.File> iterator() {
return new AbstractIterator<Vfs.File>() {
final Enumeration<URL> entries = bundle.findEntries(path, "*.class", true);
protected Vfs.File computeNext() {
return entries.hasMoreElements() ? new BundleFile(BundleDir.this, entries.nextElement()) : endOfData();
}
};
}
};
}
@Override
public void close() { }
}
public class BundleFile implements File {
private final BundleDir dir;
private final String name;
private final URL url;
public BundleFile(BundleDir dir, URL url) {
this.dir = dir;
this.url = url;
String path = url.getFile();
this.name = path.substring(path.lastIndexOf("/") + 1);
}
@Override
public String getName() {
return name;
}
@Override
public String getRelativePath() {
return getFullPath().substring(dir.getPath().length());
}
@Override
public String getFullPath() {
return url.getFile();
}
@Override
public InputStream openInputStream() throws IOException {
return url.openStream();
}
}
}
और इस तरह मैं एक्टिवेटर कक्षा में प्रतिबिंब बना देता हूं:
private Reflections createReflections(Bundle bundle) {
Vfs.addDefaultURLTypes(new BundleUrlType(bundle));
Reflections reflections = new Reflections(new Object[] { "reflectiveplugin.data" });
return reflections;
}
अंतिम बिट बहुत भ्रमित है, लेकिन फिर भी महत्वपूर्ण है: यदि आप अपनी प्लगइन को ग्रहण (रन एएस/ओएसजीआई फ्रेमवर्क) के अंदर चलाते हैं तो आपको प्रतिबिंब पथ पैटर्न (यानी) में अपनी कक्षा आउटपुट निर्देशिका भी जोड़नी होगी। "बिन" या "लक्ष्य/कक्षाएं")।हालांकि, एक जारी प्लगइन के लिए इसकी आवश्यकता नहीं है (प्लगइन/बंडल करने के लिए "निर्यात करें" -> "तैनाती प्लग-इन और टुकड़े")।
आपके लिए धन्यवाद उत्तर @Vlad। इस तरह के बंडलों को बनाने का कोई विचार नहीं है, लेकिन मैं कोशिश करूंगा (मैं अभी तक ओएसजीआई में एक विशेषज्ञ होने से दूर हूं ...)। इसलिए मुझे दो बंडलों की आवश्यकता है: 1) रिफ्लेक्शन लाइब्रेरी में "डायनामिक इंपोर्ट-पैकेज: *" प्लग-इन मैनिफ़ेस्ट पर है; 2) मेरी प्लगइन के साथ एक बंडल, जहां मुझे प्लगइन कॉन्फ़िगरेशन एडिटर के "निर्यात किए गए पैकेज" सूची में भरना होगा, सभी संकुल जो रिफ्लेक्सन बंडल तक पहुंच योग्य होना चाहिए। तो मुझे लगता है कि मुझे इन दो बंडलों को किसी अन्य में लिखना चाहिए, है ना? क्या आप कृपया अपना उत्तर थोड़ा और विस्तारित कर सकते हैं? यह सब थोड़ा जटिल लगता है! धन्यवाद – Sergio
@ सर्जीओ, मैंने अपने निष्कर्षों के साथ जवाब अपडेट किया है (पिछला जवाब समाधान प्रदान नहीं किया था)। दुर्भाग्यवश, यह बहुत कम सीधे आगे हुआ। उम्मीद है, यह मदद करेगा। – Vlad
आपका उत्तर @Vlad का विस्तार करने के लिए बहुत बहुत धन्यवाद। मैंने अब तक सफलता के बिना इसे लागू करने की कोशिश की है। अगर मैं आपके नए उत्तर से सही ढंग से समझ गया, तो मुझे अपने बंडल क्लासपाथ में केवल प्लगइन बंडल और रिफ्लेक्सन जार की आवश्यकता है (जैसा कि मैंने मूल रूप से किया था)। तो मैं एक अलग बंडल में रिफ्लेक्सियंस डालने के बारे में पिछले जवाब को अनदेखा कर रहा हूं, क्या यह सही है? आपकी मेनिफेस्ट फ़ाइल के बारे में: आपका 'बंडल-क्लासपाथ' मेरे जैसा दिखता है, मेरे 'निर्यात-पैकेज' में मेरे पास '.डेटा' फ़ाइल नहीं है, और 'आयात-पैकेज' में मुझे निर्भरता दिखाई नहीं देती है आपके पास है, क्या रिफ्लेक्सन के लिए काम करना महत्वपूर्ण है? – Sergio