Understanding Gadget URI: Is a Fragment Project Mandatory?
In the world of iDempiere ERP development, creating custom Dashboard Gadgets is a powerful way to enhance user experience. However, developers often hit a wall when their Gadget URIs fail to resolve. A common question arises: “Is it mandatory to use a fragment project to invoke Dashboard Content via Gadget URI?”
The short answer is: Yes, effectively. In this post, we’ll dive into the technical “why” and the best practices for implementation.

The Challenge: Why Your Standard Bundle Fails
When defining a Gadget URI, developers often attempt to reference a ZUL file inside a standard OSGi bundle. However, iDempiere’s UI is powered by the ZK Framework, which utilizes specific resource loading logic.
1. The ~./ Prefix and the Web Context Root
In iDempiere, the ~./ prefix in a URI refers to the Web Context Root of the running application—specifically the org.adempiere.ui.zk bundle.
- Standard Bundles (Isolated): A standard OSGi bundle is isolated by design. Its internal resources (like
.zulfiles) are not automatically exposed to the web context of the ZK UI bundle. If you point a URI to~./your.bundle.symbolic.name/my_gadget.zul, the Host bundle will look within its own context, fail to find the file, and return a 404 error. - Fragment Bundles (Merged): When you create a Fragment Bundle and attach it to
org.adempiere.ui.zk(the Host), its resources—such as those located in thetheme/folder—are effectively merged into the Host’s classpath. This makes them accessible as if they were part of the core UI bundle.
Can You Implement Gadgets Without a Fragment?
Technically, it is possible, but it is rarely recommended for standard enterprise environments.
- Web Application Bundles (WAB): You could register your bundle as a separate WAB or use an
HttpContextservice to expose resources via a specific alias. - The Drawback: Dashboard Gadgets are designed to run within the main iDempiere UI session. Loading a ZUL from a completely separate web context often leads to broken session states, authentication issues, and inconsistent theming.
Step-by-Step Recommendation
For a stable and maintainable ZUL-based Gadget implementation, follow these guidelines:
Step 1: Use a Fragment Project
Always create a Fragment Project and set the Host Plug-in to org.adempiere.ui.zk.
Step 2: Organize Your Directory
Place your files within the fragment, following a structure like:
your.fragment.project/theme/default/zul/dashboard/my_custom_gadget.zul
Step 3: Correct URI Syntax
When registering the Gadget in the iDempiere Window “Dashboard Content”, use the absolute path starting with /.
Recommended Syntax:
Plaintext
/theme/default/zul/dashboard/my_custom_gadget.zul
Note: While
~./is used for Classpath Web Resources, using the direct absolute path/within a Fragment is the proven method for resource resolution in the iDempiere Dashboard.
Verification Results
Based on our technical testing, here is how different configurations behave:
| Configuration | URI Pattern | Result | Reason |
| Standard Bundle | /my_path/file.zul | Fail | Isolated Context |
| Fragment Project | ~./theme/.../file.zul | Fail | Incorrect mapping for this context |
| Fragment Project | /theme/.../file.zul | SUCCESS | Resources merged into Host Root |
To implement the solution discussed, your Fragment Project must have a correctly configured MANIFEST.MF file. This file tells the OSGi container to “attach” your resources to the main iDempiere ZK web bundle.
Here is the template for the MANIFEST.MF file, specifically tailored for an iDempiere environment:
MANIFEST.MF Configuration
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: iDempiere Custom Dashboard Gadgets Fragment
Bundle-SymbolicName: com.yourcompany.ui.zk.fragment;singleton:=true
Bundle-Version: 1.0.0.qualifier
Fragment-Host: org.adempiere.ui.zk;bundle-version="[11.0.0,12.0.0)"
Bundle-Vendor: Your Company
Bundle-RequiredExecutionEnvironment: JavaSE-17Key Attributes Breakdown
Bundle-SymbolicName: A unique ID for your fragment. It is good practice to include.fragmentin the name to distinguish it from standard bundles.Fragment-Host: This is the most critical line. It specifiesorg.adempiere.ui.zkas the host.- Note: The
bundle-versionrange[11.0.0,12.0.0)ensures compatibility with iDempiere 11 (adjust this if you are using a different version like iDempiere 12).
- Note: The
singleton:=true: Prevents multiple versions of this specific fragment from being active at the same time, which is standard for UI customizations.
Directory Structure Requirement
For the /theme/... URI to resolve correctly, ensure your project folder structure looks exactly like this:
com.yourcompany.ui.zk.fragment/
├── META-INF/
│ └── MANIFEST.MF
└── theme/
└── default/ <-- or your custom theme name
└── zul/
└── dashboard/
└── my_gadget.zulSummary
To ensure your iDempiere Gadgets work seamlessly with the existing UI, stick to Fragment Projects. It aligns with the OSGi architecture used by iDempiere and ensures that the ZK engine can resolve your resources without complex workarounds.
