Supongo que ya sabe cómo crear paquetes (de lo contrario, marque this).
Después de algún debuging y exploración de API Reflexiones me he dado cuenta de que el problema es que las reflexiones simplemente no puede leer OSGi URL (bundleresource: // ...) lo que resulta en una excepción:
org.reflections.ReflectionsException: could not create Vfs.Dir from url,
no matching UrlType was found [bundleresource://1009.fwk651584550/]
y esto sugerencia:
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.
así que creo que la implementación de un UrlType de OSGi (por ejemplo class BundleUrlType implements UrlType {...}
) y registrarlo como esto:
Vfs.addDefaultURLTypes(new BundleUrlType());
debe hacer que Reflections API se pueda utilizar desde dentro de un paquete. Las dependencias de reflexiones se deben agregar al proyecto del complemento de Eclipse como se describe en here.
Esta es la forma en mi muestra MANIFIEST.MF parecía después de añadir frascos necesarios:
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
Nota: Se utiliza Reflexiones v 0.9.5
Aquí está un ejemplo de implementación 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();
}
}
}
Y así es como creo los reflejos en la clase Activador:
private Reflections createReflections(Bundle bundle) {
Vfs.addDefaultURLTypes(new BundleUrlType(bundle));
Reflections reflections = new Reflections(new Object[] { "reflectiveplugin.data" });
return reflections;
}
El último bit es muy confuso, pero sigue siendo importante: si ejecuta su complemento dentro de Eclipse (Ejecutar como/OSGi Framework), debe agregar también el directorio de salida de las clases a los patrones de ruta de Reflexiones (es decir "bin" o "target/classes").Sin embargo, no es necesario para un complemento liberado (para compilar un complemento/paquete haga "Exportar" -> "Complementos desplegables y fragmentos").
Gracias por su responde @Vlad. No tengo idea de cómo crear esos paquetes, pero lo intentaré (aún estoy lejos de ser un experto en OSGi ...). Así que necesito dos paquetes: 1) la biblioteca Reflections que tiene "DynamicImport-Package: *" en su Plug-in MANIFEST; 2) un paquete con mi complemento, donde tengo que completar en la lista "Paquetes exportados" del editor de configuración del complemento, todos los paquetes que deberían ser accesibles para el Paquete de Reflexiones. Entonces supongo que debería componer estos dos paquetes en otro, ¿verdad? ¿Podría por favor elaborar un poco más su respuesta? ¡todo esto parece ser un poco complejo! Gracias – Sergio
@Sergio, he actualizado la respuesta con mis conclusiones (la respuesta anterior no proporcionó una solución). Desafortunadamente, resultó ser mucho menos directo. Espero, será de ayuda. – Vlad
Muchas gracias por ampliar tu respuesta @Vlad. Intenté implementarlo sin éxito hasta ahora. Si comprendí correctamente su nueva respuesta, solo necesito el paquete de complementos y el jar de Reflexiones en su paquete classpath (como originalmente lo tuve). Así que estoy ignorando la respuesta anterior acerca de poner Reflexiones en un paquete separado, ¿es correcto? Acerca de su archivo de manifiesto: su 'Bundle-ClassPath' es similar a la mía, en mi 'Export-Package' no tengo un archivo '.data' como usted, y en el 'Import-Package' no veo las dependencias ¿Es importante que Reflexiones funcione? – Sergio