BND and @Meta Deprecations

BND has been deprecating support for @Meta annotations, but Liferay is still using them heavily. If you face issues with building projects that leverage @Meta annotations, this blog may prove to be helpful to you.

Introduction

It started with a simple Liferay Community Slack post by Pierre Beule:

Hello, I am using pretty standard Liferay stuff to generate a Liferay configuration (let's say a GROUP scoped configuration for instance).

package com.test;

import aQute.bnd.annotation.metatype.Meta;
import 
  com.liferay.portal.configuration.metatype.annotations.ExtendedObjectClassDefinition;

@ExtendedObjectClassDefinition(
  category = "testCategory", scope = ExtendedObjectClassDefinition.Scope.GROUP
)
@Meta.OCD(
  id = "com.test.VerySimpleConfig",
  name = "very-simple-name"
)
public interface VerySimpleConfig {
  @Meta.AD(deflt = "someValue", required = false)
  public String myProperty();
}

It works well in a maven project, as long as I use this configuration:

<plugin>
  <groupId>biz.aQute.bnd</groupId>
  <artifactId>bnd-maven-plugin</artifactId>
  <version>3.5.0</version>
  <executions>
    <execution>
      <id>default-bnd-process</id>
      <goals>
        <goal>bnd-process</goal>
      </goals>
    </execution>
  </executions>
  <dependencies>
    <dependency>
      <groupId>biz.aQute.bnd</groupId>
      <artifactId>biz.aQute.bndlib</artifactId>
      <version>3.5.0</version>
    </dependency>
    <dependency>
      <groupId>com.liferay</groupId>
      <artifactId>com.liferay.ant.bnd</artifactId>
      <version>3.2.10</version>
    </dependency>
  </dependencies>
</plugin>

As soon as I try to update the version of "bnd-maven-plugin" from 4.0.0 to 6.4.0 (and its biz.aQute.bndlib dependency accordingly) the configuration no longer appears in Liferay Control panel.

When opening the compiled .jar, I noticed: "OSGI-INF/metatype/" -> folder is no longer generated in the jar 

Am I the only one to encounter this problem? What could be wrong in my configuration? I am not modifying anything else. Please note the bnd.bnd file contains the "-metatype: *" information.

Any piece of advise? Thanks

So What Happened?

Long story short, BND deprecated and then removed the support for the @Meta annotation.

But Liferay code is heavily using that annotation, so what was Liferay to do?

Well, they just added support for the annotation back in...

Pierre just needed to do the same thing to his workspace so he, too, could continue to use the @Meta annotation.

Updating the Dependencies

One option is to add the dependency to the new Liferay module. In gradle this would be:

  compileOnly group: "com.liferay", name: "biz.aQute.bnd.annotation", 
    version: "4.2.0.LIFERAY-PATCHED-2"

In Maven, it would be:

    <dependency>
      <groupId>com.liferay</groupId>
      <artifactId>biz.aQute.bnd.annotation</artifactId>
      <version>4.2.0.LIFERAY-PATCHED-2</version>
    </dependency>
It is important to include this new dependency before the biz.aQute.bndlib dependency.

From our example above, our new Maven pom would look like:

<plugin>
  <groupId>biz.aQute.bnd</groupId>
  <artifactId>bnd-maven-plugin</artifactId>
  <version>4.3.0</version>
  <executions>
    <execution>
      <id>default-bnd-process</id>
      <goals>
        <goal>bnd-process</goal>
      </goals>
    </execution>
  </executions>
  <dependencies>
    <dependency>
      <groupId>com.liferay</groupId>
      <artifactId>biz.aQute.bnd.annotation</artifactId>
      <version>4.2.0.LIFERAY-PATCHED-2</version>
    </dependency>
    <dependency>
      <groupId>biz.aQute.bnd</groupId>
      <artifactId>biz.aQute.bndlib</artifactId>
      <version>4.3.0</version>
    </dependency>
    <dependency>
      <groupId>com.liferay</groupId>
      <artifactId>com.liferay.ant.bnd</artifactId>
      <version>3.2.9</version>
    </dependency>
  </dependencies>
</plugin>

There is some version codependency going on here that you should be aware of...

Version 3.2.9 of the com.liferay.ant.bnd module is for using version 4.3.0 of biz.aQute.bndlib.

Version 3.2.10 of the com.liferay.ant.bnd module is for using version 5.3.0+ of biz.aQute.bndlib, even up to version 6.4.0.

Simplifying the Dependencies

Adding the Liferay dependency is an option, but simplifying the pom down to this form will also work (as long as you follow the next section):

<plugin>
  <groupId>biz.aQute.bnd</groupId>
  <artifactId>bnd-maven-plugin</artifactId>
  <version>4.3.0</version>
  <executions>
    <execution>
      <id>default-bnd-process</id>
      <goals>
        <goal>bnd-process</goal>
      </goals>
    </execution>
  </executions>
  <dependencies>
    <dependency>
      <groupId>biz.aQute.bnd</groupId>
      <artifactId>biz.aQute.bndlib</artifactId>
      <version>4.3.0</version>
    </dependency>
    <dependency>
      <groupId>com.liferay</groupId>
      <artifactId>com.liferay.ant.bnd</artifactId>
      <version>3.2.9</version>
    </dependency>
  </dependencies>
</plugin>

Switch up to version 3.2.10 of com.liferay.ant.bnd module if you're going to use version 5.3.0 or greater of the biz.aQute.bndlib plugin.

Updating the bnd.bnd File(s)

Along with the -metatype: * instruction, we need to add some additional instructions:

-metatype: *
-plugin.metatype: com.liferay.ant.bnd.metatype.MetatypePlugin
-fixupmessages: Bnd metatype annotations are deprecated;is=ignore

The plugin.metatype instruction indicates the class that will handle the metatypes.

The fixupmessages instruction basically discards the BND-generated warnings about metatype annotations being deprecated and prevents them from failing the build.

Conclusion

Well, so now if you go about updating your BND plugins, you'll have some idea how to fix missing configuration!

Enjoy!

Blogs

Hello David,

where did you find that the @Meta annotations have been deprecated? I was not able to find official statements about the deprecation. What should we use instead of @Meta?

I am using the org.apache.felix:maven-bundle-plugin for years instead of biz.aQute.bnd:bnd-maven-plugin. With that plugin I do not have the problems above, even when using the latest biz.aQute.bndlib. Maybe it is just a problem of the biz.aQute.bnd:bnd-maven-plugin?

The post is very helpful but it does not consider a critical problem of the configuration interface.

If you use the "required = true" property even for just one @Meta.AD() you can no longer find the configuration values in the various portlets or services of the application.

@Meta.AD(     deflt = "",     name = "some.configuration.field",     description = "some.configuration.field.desc",     required = true,  <********************************** It breaks the configuration. ​​​​​​​    type = Meta.Type.String ) public String someConfigurationField();

I found this issue in LP GA 7.4.3.

There have been problems with required = true before that... In 7.0, the interface wouldn't render correctly if the attribute was set.

I never use required = true, so I haven't seen this issue.

Have you tried reporting the issue in Ask? We could get a ticket opened on it...