Anatomy of .bnd file
The .bnd file is a configuration file used in OSGi development (including Liferay) to define how Java classes should be packaged into OSGi bundles. It’s a critical component in the build process that generates the proper OSGi manifest entries.
Basic Structure of a .bnd File
Section titled “Basic Structure of a .bnd File”A typical .bnd file contains directives that control:
- Bundle identity
- Package imports and exports
- Bundle classpath
- OSGi component declarations
- Build instructions
Example basic structure:
Bundle-Name: My Awesome BundleBundle-SymbolicName: com.example.my.bundleBundle-Version: 1.0.0Export-Package: com.example.api.*Import-Package: org.osgi.framework.*, *Key Sections and Directives
Section titled “Key Sections and Directives”1. Bundle Identification
Section titled “1. Bundle Identification”Bundle-Name: My ProjectBundle-SymbolicName: com.example.projectBundle-Version: 1.2.3- Bundle-SymbolicName: Unique identifier (reverse domain name convention)
- Bundle-Version: Must follow OSGi versioning (major.minor.micro.qualifier)
2. Package Management
Section titled “2. Package Management”Export-Package: \ com.example.api;version="1.2.3",\ com.example.util;version="1.0.0"
Import-Package: \ org.osgi.framework;version="[1.8,2)",\ javax.servlet;version="[3.1,4)",\ *- Export-Package: Lists packages available to other bundles
- Import-Package: Lists required packages (wildcard
*for automatic calculation)
3. Classpath and Resources
Section titled “3. Classpath and Resources”-classpath: \ bin,\ lib/dependency1.jar,\ lib/dependency2.jar
-include: \ OSGI-INF/metatype/metatype.xml,\ META-INF/resources/icons4. OSGi Components
Section titled “4. OSGi Components”Service-Component: \ OSGI-INF/com.example.MyComponent.xml,\ OSGI-INF/com.example.AnotherComponent.xmlAdvanced .bnd Features
Section titled “Advanced .bnd Features”1. Version Ranges
Section titled “1. Version Ranges”Import-Package: \ org.osgi.service.log;version="[1.4,2)",\ javax.servlet;version="[3.1,4)"[1.4,2)means ≥1.4.0 and <2.0.0
2. Conditional Packages
Section titled “2. Conditional Packages”Private-Package: \ com.example.internal.*,\ !com.example.internal.test.*3. Macros and Properties
Section titled “3. Macros and Properties”project.version=1.2.3Bundle-Version: ${project.version}4. Plugin Configurations
Section titled “4. Plugin Configurations”-plugin: \ aQute.bnd.deployer.repository.FixedIndexRepo;\ name="My Repo";\ locations="https://example.com/repo/index.xml"How .bnd Files Work in Liferay
Section titled “How .bnd Files Work in Liferay”In Liferay’s build process (typically using Gradle or Maven):
flowchart TD
A[Java Sources] --> B[Compilation]
B --> C[Process with bnd]
C --> D[Generate MANIFEST.MF]
C --> E[Generate OSGI-INF]
D --> F[Create Bundle JAR]
E --> F
Liferay-Specific .bnd Directives
Section titled “Liferay-Specific .bnd Directives”Liferay adds several custom directives:
Liferay-Require-SchemaVersion: 1.0.0Liferay-Service: trueWeb-ContextPath: /my-bundleExample Complete .bnd File
Section titled “Example Complete .bnd File”Bundle-Name: My Liferay PortletBundle-SymbolicName: com.example.my.portletBundle-Version: 1.0.0Bundle-Category: Liferay
Export-Package: \ com.example.api;version="1.0.0"
Import-Package: \ com.liferay.portal.kernel.*;version="[7.0,8)",\ javax.portlet;version="[3.0,4)",\ javax.servlet;version="[3.1,4)",\ *
-sources: trueService-Component: OSGI-INF/*.xml
Liferay-Require-SchemaVersion: 1.0.0Web-ContextPath: /my-portletIntegration with Build Tools
Section titled “Integration with Build Tools”With Maven (bnd-maven-plugin)
Section titled “With Maven (bnd-maven-plugin)”<plugin> <groupId>biz.aQute.bnd</groupId> <artifactId>bnd-maven-plugin</artifactId> <version>5.3.0</version> <executions> <execution> <goals> <goal>bnd-process</goal> </goals> </execution> </executions></plugin>With Gradle (Liferay Plugin)
Section titled “With Gradle (Liferay Plugin)”apply plugin: "com.liferay.plugin"
dependencies { compileOnly group: "com.liferay", name: "com.liferay.portal.kernel", version: "4.0.0"}Best Practices
Section titled “Best Practices”- Use semantic versioning for all packages and bundles
- Be specific with imports (avoid wildcards in production)
- Separate API and implementation packages
- Keep private packages properly hidden
- Use Liferay-specific directives when needed
- Leverage build tool integration rather than raw
.bndfiles
Common Issues and Solutions
Section titled “Common Issues and Solutions”- Missing dependencies: Verify all required packages are imported
- Version conflicts: Specify exact version ranges
- Split packages: Avoid same package across multiple bundles
- Classloading issues: Properly export/import packages
- Circular dependencies: Restructure your bundle design
Debugging .bnd Files
Section titled “Debugging .bnd Files”- Check generated
MANIFEST.MFin final JAR - Use
bnd printcommand to see effective bundle configuration - Examine build logs for bnd warnings
- Use OSGi console to verify resolved dependencies
Relationship with MANIFEST.MF
Section titled “Relationship with MANIFEST.MF”The .bnd file is processed to generate the final MANIFEST.MF:
flowchart LR
BndFile[.bnd configuration] --> BndTool[bnd tool] --> Manifest[MANIFEST.MF]
JavaClasses --> BndTool
Resources --> BndTool
Advanced Topics
Section titled “Advanced Topics”- Fragment bundles: Special bundles that attach to host bundles
- Conditional compilation: Different configurations per environment
- Multi-bundle projects: Building several bundles from one project
- Custom bnd plugins: Extending bnd functionality
Conclusion
Section titled “Conclusion”The .bnd file is a powerful configuration tool that:
- Simplifies OSGi bundle creation
- Handles complex dependency management
- Generates proper OSGi metadata
- Integrates with Liferay’s specific requirements
Understanding .bnd files is essential for effective Liferay module development as they control the fundamental characteristics of your OSGi bundles.