Writing blueprint xml is quite verbose and large blueprint xmls are difficult to keep in sync with code changes and especially refactorings. So you would like to do most declarations using annoations and ideally these annotations should be standardized.

blueprint-maven-plugin

The blueprint-maven-plugin allows to configure blueprint using annotations. It scans one or more paths for annotated classes and creates a blueprint.xml in target/generated-sources/blueprint/OSGI-INF/blueprint. So at runtime the bundle behaves like a normal blueprint bundle. The generated blueprint can also be used together with a manually created blueprint file. So for example cxf services can be created in xml while most of the beans are automatically generated.

Usage:

<plugin>
    <groupId>org.apache.aries.blueprint</groupId>
    <artifactId>blueprint-maven-plugin</artifactId>
    <version>1.9.0</version>
    <configuration>
        <scanPaths>
            <scanPath>org.my.package</scanPath>
        </scanPaths>
    </configuration>
    <executions>
        <executions>
            <execution>
                <goals>
                    <goal>add-resource-dir</goal>
                    <goal>blueprint-generate</goal>
                </goals>
            </execution>
        </executions>
    </executions>
</plugin>

Goals

add-resource-dir

Creates target/generated-sources/blueprint folder and register it as a maven resource directory in generate-resources phase, so IDEs like IntelliJ IDEA could find it automatically.

blueprint-generate

Creates blueprint xml from annotations in process-classes phase and put file in target/generated-sources/blueprint/OSGI-INF/blueprint/autowire.xml. Destination directory (OSGI-INF/blueprint) and file name (autowire.xml) could be change via configuration properties: generatedDir and generatedFileName.

Annotations

javax.inject (JSR 330)

  • @Inject Inject a bean by type and optionally further qualifiers
  • @Singleton Mark a class as being a bean
  • @Named("Myname") Names a @Singleton and qualifies an @Inject to limit it to matches with the same bean id
  • @Qualifier Annotation on your own annotation

javax.enterprise

  • @Produces Create bean using factory method

javax.transaction

  • @Transactional mark the class as transactional.

javax.transaction.cdi

  • @Transactional mark the class as transactional.

javax.annotation (JSR 250)

  • @PostConstruct Marks a method to be called after DI is finished (init-method)
  • @PreDestroy Marks a method to be called before the bean is destroyed (destroy-method)

javax.persistence

  • @PersistenceContext(unitName="tasklist") inject a managed EntityManager for the given persistence unit into a field
  • @PersistenceUnit(unitName="tasklist") inject an unmanaged EntityManagerFactory for the given persistence unit into a field

Configuration annotations (org.apache.aries.blueprint.annotation.config)

  • @ConfigProperty Inject value as property from property-placeholder or constant
  • @Config Creates cm:property-placehoder
  • @DefaultProperty Configure default values for properties in property-placeholder

Collection annotations (org.apache.aries.blueprint.annotation.collection)

  • @CollectionInject Inject list, set or array of existing beans of provided interface

Bean annotations (org.apache.aries.blueprint.annotation.bean)

  • @Bean Mark a class as a bean or method as factory of bean

Reference listener annotations (org.apache.aries.blueprint.annotation.referencelistener)

  • @ReferenceListener Marks bean as reference listener
  • @Bind Method of referenence listener to be called when service registers
  • @Unbind Method of referenence listener to be called when service unregisters

Service annotations (org.apache.aries.blueprint.annotation.service)

  • @Service Publishes a bean as an OSGi service with the given interfaces
  • @ServiceProperty Defines a service property
  • @Reference Creates a reference to an OSGi service
  • @ReferenceList Creates a list of references of an OSGi services

pax-cdi (supported in version 1.x, probably dropped in next major versions)

  • @OsgiServiceProvider(classes={TaskService.class}) Publishes a bean as an OSGi service with the given interfaces
  • @OsgiService creates a reference to an OSGi service. On optional filter is also possible
  • @Properties Defines service properties for OSGiServiceProvider
  • @Property Defines a service property

Spring (supported in version 1.x, probably dropped in next major versions)

  • @Autowired Inject a bean by type and optionally further qualifiers
  • @Component Creates bean witd default or given name
  • @DependsOn Make bean depending on another bean
  • @Lazy Make bean lazy
  • @Qualifier Name injected bean
  • @Transactional mark the class as transactional
  • @Value Inject value or constant

Dependencies for annotations

<dependency>
    <groupId>javax.inject</groupId>
    <artifactId>javax.inject</artifactId>
    <version>1</version>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>javax.enterprise</groupId>
    <artifactId>cdi-api</artifactId>
    <version>1.2</version>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>javax.persistence</groupId>
    <artifactId>persistence-api</artifactId>
    <version>1.0.2</version>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>javax.transaction</groupId>
    <artifactId>javax.transaction-api</artifactId>
    <version>1.2</version>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>org.apache.aries.blueprint</groupId>
    <artifactId>blueprint-maven-plugin-annotation</artifactId>
    <version>1.3.0</version>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>org.ops4j.pax.cdi</groupId>
    <artifactId>pax-cdi-api</artifactId>
    <version>0.8.0</version>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>org.apache.servicemix.bundles</groupId>
    <artifactId>org.apache.servicemix.bundles.spring-beans</artifactId>
    <version>3.2.11.RELEASE_1</version>
    <optional>true</optional>
</dependency>

Note that the annotations are needed only during build run, so you can exclude them or mark optional in Import-Package header of your bundle.

SPI

Whole plugin is written using 'plugin architecture', so your own annotations could be configured for bleuprint generation. All you need to do, is to implement one of interfaces from blueprint-maven-plugin-spi:

<dependency>
    <groupId>org.apache.aries.blueprint</groupId>
    <artifactId>blueprint-maven-plugin-spi</artifactId>
    <version>1.1.0</version>
</dependency>

Next add file (or files) to META-INF/services directory describing which interface implementation your artifact provides and add such artifact as plugin dependency

<plugin>
    <groupId>org.apache.aries.blueprint</groupId>
    <artifactId>blueprint-maven-plugin</artifactId>
    <version>1.9.0</version>
    ...
    <dependencies>
        <dependency>
            <groupId>org.apache.aries.blueprint.example</groupId>
            <artifactId>blueprint-maven-plugin-my-extension</artifactId>
            <version>1.0.0</version>
        </dependency>
    </dependencies>
    ...
</plugin>

Additional configuration

Bean from factories are named by bean class nams or as defined in @Named or @Bean annotations. If you want to name such beans after producing method name then add configuration parameter:

<configuration>
    <customParameters>
        <blueprint.beanFromFactory.nameFromFactoryMethodName>true</blueprint.beanFromFactory.nameFromFactoryMethodName>
    </customParameters>
</configuration>

Example

For a complete example see tasklist-blueprint-cdi on github or tests of blueprint-maven-plugin.