springannotationsosgispring-dm

Find annotated classes inside OSGi bundle with Spring?


i want to find all classes annotated with my custom annotation inside OSGi bundle,
actual scanning must take place inside the bundle itself, or from another bundle,
i have tried using ClassPathScanningCandidateComponentProvider, but it causes exception:

java.io.FileNotFoundException: URL [bundleresource://38.fwk29597962/my/base/package/] cannot be resolved to absolute file path because it does not reside in the file system: bundleresource://38.fwk29597962/my/base/package/

i am 99% sure, solutions like reflections or other scanning libraries didn't work either, don't remember now why

i could config component-scan like so:

<context:annotation-config />
<context:component-scan base-package="my.base.package" use-default-filters="false">
    <context:include-filter type="annotation" expression="path.to.my.annotation"/>
</context:component-scan>

and get what i need form bean factory, but that would require adding @Scope("prototype") to all my annotated classes, so spring does not create singletons by default, etc.
any better solution?

-my annotated classes does not have @Component or anything related to spring
-osgi framework(eclipse equinox 3.8) is embedded in a web application
-using spring 3.2.3 and gemini-blueprint 2.0.0.M02


Solution

  • If you're prepared to do the scanning in build time rather than at runtime, then bnd has a rather nice macro you can use:

    MyAnnotated-Classes: ${classes;CONCRETE;ANNOTATION;org.example.MyAnnotation}
    

    ...which will generate a MyAnnotated-Classes head in the manifest that lists all of the classes in your bundle that have @MyAnnotation. Scanning this header at runtime is now trivial.

    This approach is a significant optimisation over runtime classpath scanning. Also runtime scanning can be unreliable, since you need to catch the contents of Bundle-ClassPath, but avoid any imported/required classes.